fep/frontendprocessor/test/feps/TFEP3.CPP
changeset 0 eb1f2e154e89
equal deleted inserted replaced
-1:000000000000 0:eb1f2e154e89
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @internalComponent
       
    19 */
       
    20 
       
    21 #include <e32std.h>
       
    22 #include <e32base.h>
       
    23 #include <e32keys.h>
       
    24 #include <s32strm.h>
       
    25 #include <gdi.h>
       
    26 #include <txtfrmat.h>
       
    27 #include <fbs.h>
       
    28 #include <bitstd.h>
       
    29 #include <bitdev.h>
       
    30 #include <w32std.h>
       
    31 #include <frmtlay.h>
       
    32 #include <coemain.h>
       
    33 #include <coeaui.h>
       
    34 #include <coecntrl.h>
       
    35 #include <coefepff.h>
       
    36 #include <fepbase.h>
       
    37 #include <fepitfr.h>
       
    38 #include <bautils.h>
       
    39 #include <techview/eikon.hrh>
       
    40 #include <techview/eikdialg.h>
       
    41 #include <techview/eikchkbx.h>
       
    42 #include <techview/eikbutb.h>
       
    43 #include <techview/eikchlst.h>
       
    44 
       
    45 #include "tfep3.hrh"
       
    46 #include "TFEP3.H"
       
    47 
       
    48 #define DEBUGGING_MESSAGES
       
    49 #if defined(DEBUGGING_MESSAGES)
       
    50 #include <e32svr.h>
       
    51 #endif
       
    52 
       
    53 // constants
       
    54 
       
    55 enum TPanic
       
    56 	{
       
    57 	EPanicBackupAlreadyExists=1,
       
    58 	EPanicNotExpectedToBeSimulatingKeyEvent1,
       
    59 	EPanicNotExpectedToBeSimulatingKeyEvent2,
       
    60 	EPanicBadIndex,
       
    61 	EPanicBadAttributeUid1,
       
    62 	EPanicBadAttributeUid2,
       
    63 	EPanicBadAttributeUid3,
       
    64 	EPanicBadAttributeUid4,
       
    65 	EPanicBadInputMethod1,
       
    66 	EPanicBadInputMethod2,
       
    67 	EPanicBadInputMethod3,
       
    68 	EPanicBadInputMethod4,
       
    69 	EPanicBadInputMethod5,
       
    70 	EPanicBadTextLength1,
       
    71 	EPanicBadTextLength2,
       
    72 	EPanicBadKeyCode1,
       
    73 	EPanicBadKeyCode2,
       
    74 	EPanicBadKeyCode3,
       
    75 	EPanicBadKeyCode4,
       
    76 	EPanicBadCharacterInBuffer,
       
    77 	EPanicInconsistentState,
       
    78 	EPanicArithmeticConfusion,
       
    79 	EPanicBadLengthOfTextBeforeSelection,
       
    80 	EPanicSelectionExtendsPastEndOfDocument,
       
    81 	EPanicBadLengthOfTextAfterSelection,
       
    82 	EPanicBadLengthOfSelection,
       
    83 	EPanicBadHeight,
       
    84 	EPanicIsAlreadyActive,
       
    85 	EPanicNoFepAwareTextEditorAlthoughCurrentlyInlineEditing,
       
    86 	EPanicBadKeyResponse,
       
    87 	EPanicUnexpectedButtonId,
       
    88 	EPanicBadCheckBoxState,
       
    89 	EPanicBadNumberOfAttributes
       
    90 	};
       
    91 
       
    92 LOCAL_D const TUint Alpha[10][4] = {{0,0,0,0},{0,0,0,0},{65,66,67,0},{68,69,70,0},{71,72,73,0},{74,75,76,0},{77,78,79,0},{80,81,82,83},{84,85,86,0},{87,88,89,90}} ;
       
    93 
       
    94 _LIT(KLitTFEP3, "TFEP3");
       
    95 #if defined(_UNICODE)
       
    96 const TUint KEllipsisCharacter=0x2026;
       
    97 _LIT(KLitCompositionFontTypefaceName, "publicDomainUnicode");
       
    98 #else
       
    99 const TUint KEllipsisCharacter=0x85;
       
   100 _LIT(KLitCompositionFontTypefaceName, "courier");
       
   101 #endif
       
   102 _LIT(KLitStatusFontTypefaceName, "arial");
       
   103 _LIT(KLitNotAvailable, "[not available]");
       
   104 //_LIT(KLitTooLong, "[too long]");
       
   105 _LIT(KLitQuotationMark, "\"");
       
   106 _LIT(KLitTextBeforeSelectionColonSpace, "Text before selection: ");
       
   107 _LIT(KLitTextAfterSelectionColonSpace, "Text after selection: ");
       
   108 _LIT(KLitSelectionColonSpace, "Selection: ");
       
   109 _LIT(KLitInputMethodColonSpace, "Input method: ");
       
   110 _LIT(KLitPlain, "plain");
       
   111 _LIT(KLitHexadecimalCharacterCode, "hexadecimal character-code");
       
   112 _LIT(KLitNumberKeyPad, "number keypad");
       
   113 _LIT(KLitInlineEditingColonSpace, "Inline editing: ");
       
   114 _LIT(KLitEnabled, "enabled");
       
   115 _LIT(KLitDisabled, "disabled");
       
   116 _LIT(KLitOpeningSquareBracket, "[");
       
   117 _LIT(KLitCaptionColonSpace, "Caption: ");
       
   118 _LIT(KLitInputCapabilitiesColonSpace, "Input-capabilities: ");
       
   119 _LIT(KLitNone, "none");
       
   120 _LIT(KLitWesternNumericIntegerPositive, "Western numeric integer positive");
       
   121 _LIT(KLitWesternNumericIntegerNegative, "Western numeric integer negative");
       
   122 _LIT(KLitWesternNumericReal, "Western numeric real");
       
   123 _LIT(KLitWesternAlphabetic, "Western alphabetic");
       
   124 _LIT(KLitJapaneseHiragana, "Japanese hiragana");
       
   125 _LIT(KLitJapaneseKatakanaHalfWidth, "Japanese katakana half-width");
       
   126 _LIT(KLitJapaneseKatakanaFullWidth, "Japanese katakana full-width");
       
   127 _LIT(KLitDialableCharacters, "dialable characters");
       
   128 _LIT(KLitSecretText, "secret text");
       
   129 _LIT(KLitAllText, "all text");
       
   130 _LIT(KLitNavigation, "navigation");
       
   131 _LIT(KLitCommaSpace, ", ");
       
   132 _LIT(KLitClosingSquareBracket, "]");
       
   133 
       
   134 // local and global functions
       
   135 
       
   136 LOCAL_C void Panic(TPanic aPanic)
       
   137 	{
       
   138 	User::Panic(KLitTFEP3, aPanic);
       
   139 	}
       
   140 
       
   141 GLDEF_C TInt E32Dll(
       
   142 					)
       
   143 	{
       
   144 	return KErrNone;
       
   145 	}
       
   146 
       
   147 // TTstTextBackup
       
   148 
       
   149 #pragma warning(disable: 4355) // "'this' : used in base member initializer list"
       
   150 
       
   151 TTstTextBackup::TTstTextBackup(TDes& aText)
       
   152 	:iCleanupItem(Cleanup, this),
       
   153 	 iOriginal(aText),
       
   154 	 iBackup(NULL)
       
   155 	{
       
   156 	}
       
   157 
       
   158 #pragma warning(default: 4355)
       
   159 
       
   160 void TTstTextBackup::PushOntoCleanupStackL()
       
   161 	{
       
   162 	__ASSERT_DEBUG(iBackup==NULL, Panic(EPanicBackupAlreadyExists));
       
   163 	iBackup=iOriginal.AllocL();
       
   164 	CleanupStack::PushL(iCleanupItem);
       
   165 	}
       
   166 
       
   167 void TTstTextBackup::PopOffCleanupStack()
       
   168 	{
       
   169 	delete iBackup;
       
   170 	CleanupStack::Pop();
       
   171 	}
       
   172 
       
   173 void TTstTextBackup::Cleanup(TAny* aTextBackup)
       
   174 	{
       
   175 	TTstTextBackup* const textBackup=STATIC_CAST(TTstTextBackup*, aTextBackup);
       
   176 	textBackup->iOriginal=*textBackup->iBackup;
       
   177 	delete textBackup->iBackup;
       
   178 	}
       
   179 
       
   180 // CTstInsertionPoint
       
   181 
       
   182 CTstInsertionPoint* CTstInsertionPoint::NewL(RWindowBase& aWindow, CCoeEnv& aConeEnvironment)
       
   183 	{
       
   184 	CTstInsertionPoint* const insertionPoint=new(ELeave) CTstInsertionPoint(aConeEnvironment.WsSession());
       
   185 	CleanupStack::PushL(insertionPoint);
       
   186 	insertionPoint->ConstructL(aWindow, aConeEnvironment.ScreenDevice()->DisplayMode());
       
   187 	CleanupStack::Pop(); // insertionPoint
       
   188 	return insertionPoint;
       
   189 	}
       
   190 
       
   191 CTstInsertionPoint::~CTstInsertionPoint()
       
   192 	{
       
   193 	iSprite.Close();
       
   194 	delete iSpriteMember.iBitmap; // must be deleted after iSprite is closed as iSprite has a reference to it
       
   195 	// iSpriteMember.iMaskBitmap is not deleted as it is the same as iSpriteMember.iBitmap
       
   196 	}
       
   197 
       
   198 void CTstInsertionPoint::SetPosition(const TPoint& aPosition)
       
   199 	{
       
   200 	iPosition=aPosition;
       
   201 	if (iFlags&EFlagOn)
       
   202 		{
       
   203 		iSprite.SetPosition(iPosition);
       
   204 		}
       
   205 	}
       
   206 
       
   207 void CTstInsertionPoint::SetOn(TBool aOn)
       
   208 	{
       
   209 	if (!aOn!=!(iFlags&EFlagOn)) // fold non-zero values on both sides before comparing for inequality
       
   210 		{
       
   211 		DoSetOn(aOn);
       
   212 		}
       
   213 	}
       
   214 
       
   215 CTstInsertionPoint::CTstInsertionPoint(RWsSession& aWindowServerSession)
       
   216 	:iSprite(aWindowServerSession),
       
   217 	 iPosition(0, 0),
       
   218 	 iFlags(0)
       
   219 	{
       
   220 	iSpriteMember.iBitmap=NULL;
       
   221 	iSpriteMember.iMaskBitmap=NULL;
       
   222 	}
       
   223 
       
   224 void CTstInsertionPoint::ConstructL(RWindowBase& aWindow, TDisplayMode aDisplayMode)
       
   225 	{
       
   226 	iSpriteMember.iBitmap=CreateBitmapL(aDisplayMode);
       
   227 	iSpriteMember.iMaskBitmap=iSpriteMember.iBitmap;
       
   228 	iSpriteMember.iInvertMask=ETrue;
       
   229 	iSpriteMember.iDrawMode=CGraphicsContext::EDrawModePEN;
       
   230 	iSpriteMember.iOffset.iX=-(CTstInsertionPoint::EWidth/2);
       
   231 	iSpriteMember.iOffset.iY=0;
       
   232 	iSpriteMember.iInterval=0;
       
   233 	User::LeaveIfError(iSprite.Construct(aWindow, iPosition, 0));
       
   234 	User::LeaveIfError(iSprite.AppendMember(iSpriteMember));
       
   235 	DoSetOn(EFalse);
       
   236 	User::LeaveIfError(iSprite.Activate());
       
   237 	}
       
   238 
       
   239 CFbsBitmap* CTstInsertionPoint::CreateBitmapL(TDisplayMode aDisplayMode)
       
   240 	{
       
   241 	CFbsBitmap* const bitmap=new(ELeave) CFbsBitmap;
       
   242 	CleanupStack::PushL(bitmap);
       
   243 	User::LeaveIfError(bitmap->Create(TSize(CTstInsertionPoint::EWidth, CTstInsertionPoint::EHeight), aDisplayMode));
       
   244 	CFbsBitmapDevice* const bitmapDevice=CFbsBitmapDevice::NewL(bitmap);
       
   245 	CleanupStack::PushL(bitmapDevice);
       
   246 	CFbsBitGc* const graphicsContext=CFbsBitGc::NewL();
       
   247 	CleanupStack::PushL(graphicsContext);
       
   248 	graphicsContext->Activate(bitmapDevice);
       
   249 	graphicsContext->SetBrushStyle(CGraphicsContext::ESolidBrush);
       
   250 	graphicsContext->SetBrushColor(KRgbWhite);
       
   251 	graphicsContext->SetPenStyle(CGraphicsContext::ESolidPen);
       
   252 	graphicsContext->SetPenColor(KRgbBlack);
       
   253 	graphicsContext->Clear();
       
   254 	const TPoint bottomLeft(0, CTstInsertionPoint::EHeight-1);
       
   255 	const TPoint bottomRight(CTstInsertionPoint::EWidth-1, CTstInsertionPoint::EHeight-1);
       
   256 	const TPoint top(CTstInsertionPoint::EWidth/2, 0);
       
   257 	graphicsContext->DrawLine(bottomLeft, bottomRight);
       
   258 	graphicsContext->DrawLine(bottomRight, top);
       
   259 	graphicsContext->DrawLine(top, bottomLeft);
       
   260 	CleanupStack::PopAndDestroy(2); // graphicsContext and bitmapDevice
       
   261 	CleanupStack::Pop(); // bitmap
       
   262 	return bitmap;
       
   263 	}
       
   264 
       
   265 void CTstInsertionPoint::DoSetOn(TBool aOn)
       
   266 	{
       
   267 	iSprite.SetPosition(aOn? iPosition: TPoint(-(EWidth*4), -(EHeight*4)));
       
   268 	if (aOn)
       
   269 		{
       
   270 		iFlags|=EFlagOn;
       
   271 		}
       
   272 	else
       
   273 		{
       
   274 		iFlags&=~EFlagOn;
       
   275 		}
       
   276 	}
       
   277 
       
   278 // CTstControl
       
   279 
       
   280 CTstControl* CTstControl::NewL(CTstFep& aFep)
       
   281 	{
       
   282 	CTstControl* const control=new(ELeave) CTstControl(aFep);
       
   283 	CleanupStack::PushL(control);
       
   284 	control->ConstructL();
       
   285 	CleanupStack::Pop(); // control
       
   286 	return control;
       
   287 	}
       
   288 
       
   289 CTstControl::~CTstControl()
       
   290 	{
       
   291 	if (iFlags&EFlagInsideInlineEditingTransaction)
       
   292 		{
       
   293 		CancelInlineEdit(*iInputCapabilities.FepAwareTextEditor());
       
   294 		}
       
   295 	iCoeEnv->ReleaseScreenFont(iCompositionFont);
       
   296 	iCoeEnv->ReleaseScreenFont(iStatusFont);
       
   297 	STATIC_CAST(CCoeAppUi*, iCoeEnv->AppUi())->RemoveFromStack(this);
       
   298 	delete iInsertionPoint;
       
   299 	delete iMoveCursorTimer;
       
   300 	}
       
   301 
       
   302 void CTstControl::CancelTransaction()
       
   303 	{
       
   304 	__ASSERT_DEBUG(!iFep.IsSimulatingKeyEvent() || ((~iFlags&EFlagInsideInlineEditingTransaction) && (iBuffer.Length()==0)), Panic(EPanicNotExpectedToBeSimulatingKeyEvent1));
       
   305 	TBool needToDraw=EFalse;
       
   306 	if (iFlags&EFlagInsideInlineEditingTransaction)
       
   307 		{
       
   308 		CancelInlineEdit(*iInputCapabilities.FepAwareTextEditor());
       
   309 		needToDraw=ETrue;
       
   310 		}
       
   311 	if (iBuffer.Length()>0)
       
   312 		{
       
   313 		ResetBuffer();
       
   314 		needToDraw=ETrue;
       
   315 		}
       
   316 	if (needToDraw)
       
   317 		{
       
   318 		DrawNow();
       
   319 		}
       
   320 	}
       
   321 
       
   322 void CTstControl::IsOnHasChangedState()
       
   323 	{
       
   324 	ChangeSetupAndResetBufferAndDrawNow(NULL);
       
   325 	}
       
   326 
       
   327 void CTstControl::OfferPointerEventL(CCoeFep::TEventResponse& aEventResponse, const TPointerEvent& aPointerEvent, const CCoeControl* aWindowOwningControl)
       
   328 	{
       
   329 	// this function must correctly set aEventResponse *before* calling anything that can leave
       
   330 	if (aWindowOwningControl==this)
       
   331 		{
       
   332 		aEventResponse=CCoeFep::EEventWasConsumed;
       
   333 		HandlePointerEventL(aPointerEvent);
       
   334 		}
       
   335 	else
       
   336 		{
       
   337 		aEventResponse=CCoeFep::EEventWasNotConsumed;
       
   338 		}
       
   339 	}
       
   340 
       
   341 TInt CTstControl::NumberOfAttributes()
       
   342 	{
       
   343 	// InlineEditingEnabled & InputMethod...change this if want to add any more attributes...
       
   344 	return 2;
       
   345 	}
       
   346 
       
   347 TUid CTstControl::AttributeAtIndex(TInt aIndex)
       
   348 	{
       
   349 	switch (aIndex)
       
   350 		{
       
   351 	case 0:
       
   352 		return TUid::Uid(ETstInlineEditingEnabledUid);
       
   353 	case 1:
       
   354 		return TUid::Uid(ETstInputMethodUid);
       
   355 #if defined(_DEBUG)
       
   356 	default:
       
   357 		Panic(EPanicBadIndex);
       
   358 		break;
       
   359 #endif
       
   360 		}
       
   361 	return KNullUid;
       
   362 	}
       
   363 
       
   364 void CTstControl::WriteAttributeDataToStreamL(TUid aAttributeUid, RWriteStream& aStream) const
       
   365 	{
       
   366 	switch (aAttributeUid.iUid)
       
   367 		{
       
   368 	case ETstInlineEditingEnabledUid:
       
   369 		aStream.WriteUint8L((iFlags&EFlagInlineEditingEnabled)!=0);
       
   370 		break;
       
   371 	case ETstInputMethodUid:
       
   372 		aStream.WriteUint8L(iInputMethod);
       
   373 		break;
       
   374 #if defined(_DEBUG)
       
   375 	default:
       
   376 		Panic(EPanicBadAttributeUid1);
       
   377 		break;
       
   378 #endif
       
   379 		}
       
   380 	}
       
   381 
       
   382 void CTstControl::ReadAttributeDataFromStreamL(TUid aAttributeUid, RReadStream& aStream)
       
   383 	{
       
   384 	switch (aAttributeUid.iUid)
       
   385 		{
       
   386 	case ETstInlineEditingEnabledUid:
       
   387 		ChangeSetupAndResetBufferAndDrawNow(SetFlagInlineEditingEnabled, aStream.ReadUint8L());
       
   388 		break;
       
   389 	case ETstInputMethodUid:
       
   390 		{
       
   391 		TInt inputMethod=aStream.ReadUint8L();
       
   392 		if ((inputMethod!=EInputMethodPlain) && (inputMethod!=EInputMethodHexadecimalCharacterCode) && (inputMethod!=EInputMethodNumberKeyPad))
       
   393 			{
       
   394 			User::Leave(KErrCorrupt);
       
   395 			}
       
   396 		ChangeSetupAndResetBufferAndDrawNow(SetInputMethod, inputMethod);
       
   397 		}
       
   398 		break;
       
   399 #if defined(_DEBUG)
       
   400 	default:
       
   401 		Panic(EPanicBadAttributeUid2);
       
   402 		break;
       
   403 #endif
       
   404 		}
       
   405 	}
       
   406 
       
   407 void CTstControl::WriteAttributeDataToStreamL(TUid aAttributeUid, RWriteStream& aStream, TBool aInlineEditingEnabled, TInt aInputMethod)
       
   408 	{
       
   409 	switch (aAttributeUid.iUid)
       
   410 		{
       
   411 	case ETstInlineEditingEnabledUid:
       
   412 		aStream.WriteUint8L(aInlineEditingEnabled!=EFalse);
       
   413 		break;
       
   414 	case ETstInputMethodUid:
       
   415 		aStream.WriteUint8L(aInputMethod);
       
   416 		break;
       
   417 #if defined(_DEBUG)
       
   418 	default:
       
   419 		Panic(EPanicBadAttributeUid3);
       
   420 		break;
       
   421 #endif
       
   422 		}
       
   423 	}
       
   424 
       
   425 void CTstControl::ReadAttributeDataFromStreamL(TUid aAttributeUid, RReadStream& aStream, TBool& aInlineEditingEnabled, TInt& aInputMethod)
       
   426 	{
       
   427 	switch (aAttributeUid.iUid)
       
   428 		{
       
   429 	case ETstInlineEditingEnabledUid:
       
   430 		aInlineEditingEnabled=aStream.ReadUint8L();
       
   431 		break;
       
   432 	case ETstInputMethodUid:
       
   433 		aInputMethod=aStream.ReadUint8L();
       
   434 		break;
       
   435 #if defined(_DEBUG)
       
   436 	default:
       
   437 		Panic(EPanicBadAttributeUid4);
       
   438 		break;
       
   439 #endif
       
   440 		}
       
   441 	}
       
   442 
       
   443 void CTstControl::HandleGainingForeground()
       
   444 	{
       
   445 	DrawableWindow()->MoveToGroup(iCoeEnv->WsSession().GetFocusWindowGroup()); // ignore the error returned
       
   446 	ChangeSetupAndResetBufferAndDrawNow(SetForeground, ETrue);
       
   447 	}
       
   448 
       
   449 void CTstControl::HandleLosingForeground()
       
   450 	{
       
   451 	ChangeSetupAndResetBufferAndDrawNow(SetForeground, EFalse);
       
   452 	}
       
   453 
       
   454 void CTstControl::HandleChangeInFocus()
       
   455 	{
       
   456 	ChangeSetupAndResetBufferAndDrawNow(SetInputCapabilities, NULL);
       
   457 	}
       
   458 
       
   459 void CTstControl::HandleDestructionOfFocusedItem()
       
   460 	{
       
   461 	if (!IsBeingDestroyed())
       
   462 		{
       
   463 		const TCoeInputCapabilities inputCapabilities(STATIC_CAST(const CCoeAppUi*, iCoeEnv->AppUi())->InputCapabilities());
       
   464 		if (inputCapabilities.FepAwareTextEditor()==NULL)
       
   465 			{
       
   466 			iFlags&=~EFlagInsideInlineEditingTransaction; // turn this off now so that ChangeSetupAndResetBufferAndDrawNow does not try to call CancelInlineEdit on an object that has probably been destroyed by now
       
   467 			}
       
   468 		ChangeSetupAndResetBufferAndDrawNow(SetInputCapabilities, REINTERPRET_CAST(TInt, &inputCapabilities));
       
   469 		}
       
   470 	}
       
   471 
       
   472 CTstControl::CTstControl(CTstFep& aFep)
       
   473 	:iFep(aFep),
       
   474 	 iInputMethod(EInputMethodPlain),
       
   475 	 iFlags(0),
       
   476 	 iBuffer(KNullDesC),
       
   477 	 iSelectedCompositionText(0, 0),
       
   478 	 iInputCapabilities(TCoeInputCapabilities::ENone),
       
   479 	 iCompositionFont(NULL),
       
   480 	 iStatusFont(NULL),
       
   481 	 iInsertionPoint(NULL),
       
   482 	 iPositionOnWindowBeingDragged(0, 0),
       
   483 	 iCountKeyPressed(0),
       
   484 	 iLastKeyPressed(0)
       
   485 	{
       
   486 	}
       
   487 
       
   488 void CTstControl::ConstructL()
       
   489 	{
       
   490 	iMoveCursorTimer = CTstControl::CMoveCursorTimer::NewL(*this);
       
   491 	CreateWindowL();
       
   492 	EnableDragEvents();
       
   493 	ClaimPointerGrab();
       
   494 	SetNonFocusing();
       
   495 	RDrawableWindow& window=*DrawableWindow();
       
   496 	window.SetOrdinalPosition(0, ECoeWinPriorityFep);
       
   497 	window.SetShadowHeight(3);
       
   498 	TFontSpec compositionFontSpec(KLitCompositionFontTypefaceName, 200);
       
   499 	compositionFontSpec.iTypeface.SetIsProportional(EFalse);
       
   500 	iCompositionFont=iCoeEnv->CreateScreenFontL(compositionFontSpec);
       
   501 	iStatusFont=iCoeEnv->CreateScreenFontL(TFontSpec(KLitStatusFontTypefaceName, 120));
       
   502 	iInsertionPoint=CTstInsertionPoint::NewL(window, *iCoeEnv);
       
   503 	SetPositionOfInsertionPointInBuffer(0);
       
   504 	const TInt statusFontHeightInPixels=iStatusFont->HeightInPixels();
       
   505 	const TSize size(320, 1+EGapAboveCompositionLine+iCompositionFont->HeightInPixels()+EGapBelowCompositionLine+EGapAboveTopStatusLine+(3*(statusFontHeightInPixels+EGapBetweenEachStatusLine))+statusFontHeightInPixels+EGapBelowBottomStatusLine+1);
       
   506 	const TSize screenSize=iCoeEnv->ScreenDevice()->SizeInPixels();
       
   507 	SetExtent(TPoint(screenSize.iWidth-(size.iWidth+10), screenSize.iHeight-(size.iHeight+10)), size);
       
   508 	STATIC_CAST(CCoeAppUi*, iCoeEnv->AppUi())->AddToStackL(this, ECoeStackPriorityFep, ECoeStackFlagRefusesFocus|ECoeStackFlagSharable);
       
   509 	ChangeSetupAndResetBufferAndDrawNow(SetForeground, iCoeEnv->RootWin().Identifier()==iCoeEnv->WsSession().GetFocusWindowGroup());
       
   510 	ChangeSetupAndResetBufferAndDrawNow(SetFocus, EFalse);
       
   511 	ChangeSetupAndResetBufferAndDrawNow(SetFlagInlineEditingEnabled, ETrue);
       
   512 	ChangeSetupAndResetBufferAndDrawNow(SetInputMethod, EInputMethodPlain);
       
   513 	ChangeSetupAndResetBufferAndDrawNow(SetInputCapabilities, NULL);
       
   514 	}
       
   515 
       
   516 void CTstControl::SetForeground(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter)
       
   517 	{
       
   518 	SetFlag(aControl, aChangeWasMade, aParameter, EFlagForeground);
       
   519 	}
       
   520 
       
   521 void CTstControl::SetFocus(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter)
       
   522 	{
       
   523 	aChangeWasMade=EFalse;
       
   524 	if (!aParameter!=!aControl.IsFocused()) // fold non-zero values on both sides before comparing for inequality
       
   525 		{
       
   526 		CCoeAppUi& appUi=*STATIC_CAST(CCoeAppUi*, aControl.iCoeEnv->AppUi());
       
   527 		appUi.UpdateStackedControlFlags(&aControl, (aParameter? 0: ECoeStackFlagRefusesFocus), ECoeStackFlagRefusesFocus);
       
   528 		appUi.HandleStackChanged();
       
   529 		aChangeWasMade=ETrue;
       
   530 		}
       
   531 	}
       
   532 
       
   533 void CTstControl::SetFlagInlineEditingEnabled(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter)
       
   534 	{
       
   535 	SetFlag(aControl, aChangeWasMade, aParameter, EFlagInlineEditingEnabled);
       
   536 	}
       
   537 
       
   538 void CTstControl::SetInputMethod(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter)
       
   539 	{
       
   540 	__ASSERT_DEBUG((aParameter==EInputMethodPlain) || (aParameter==EInputMethodHexadecimalCharacterCode) || (aParameter ==EInputMethodNumberKeyPad), Panic(EPanicBadInputMethod1));
       
   541 	aChangeWasMade=EFalse;
       
   542 	if (aControl.iInputMethod!=aParameter)
       
   543 		{
       
   544 		aControl.iInputMethod=aParameter;
       
   545 		aChangeWasMade=ETrue;
       
   546 		}
       
   547 	}
       
   548 
       
   549 void CTstControl::SetInputCapabilities(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter)
       
   550 	{
       
   551 	aChangeWasMade=EFalse;
       
   552 	if (!aControl.IsFocused())
       
   553 		{
       
   554 		const TCoeInputCapabilities inputCapabilities((aParameter!=NULL)? *REINTERPRET_CAST(const TCoeInputCapabilities*, aParameter): STATIC_CAST(const CCoeAppUi*, aControl.iCoeEnv->AppUi())->InputCapabilities());
       
   555 		if (aControl.iInputCapabilities!=inputCapabilities)
       
   556 			{
       
   557 			aControl.iInputCapabilities=inputCapabilities;
       
   558 			aChangeWasMade=ETrue;
       
   559 			}
       
   560 		}
       
   561 	}
       
   562 
       
   563 void CTstControl::SetFlag(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter, TUint aFlag)
       
   564 	{
       
   565 	aChangeWasMade=EFalse;
       
   566 	if (!aParameter!=!(aControl.iFlags&aFlag)) // fold non-zero values on both sides before comparing for inequality
       
   567 		{
       
   568 		aControl.iFlags^=aFlag;
       
   569 		aChangeWasMade=ETrue;
       
   570 		}
       
   571 	}
       
   572 
       
   573 void CTstControl::ChangeSetupAndResetBufferAndDrawNow(FChangeFunction aChangeFunction, TInt aParameter)
       
   574 	{
       
   575 	__ASSERT_DEBUG(!iFep.IsSimulatingKeyEvent() || ((~iFlags&EFlagInsideInlineEditingTransaction) && (iBuffer.Length()==0)), Panic(EPanicNotExpectedToBeSimulatingKeyEvent2));
       
   576 	TBool needToDraw=EFalse;
       
   577 	if (iFlags&EFlagInsideInlineEditingTransaction)
       
   578 		{
       
   579 		CancelInlineEdit(*iInputCapabilities.FepAwareTextEditor());
       
   580 		needToDraw=ETrue;
       
   581 		}
       
   582 	if (aChangeFunction!=NULL)
       
   583 		{
       
   584 		TBool changeWasMade;
       
   585 		(*aChangeFunction)(*this, changeWasMade, aParameter);
       
   586 		if (changeWasMade)
       
   587 			{
       
   588 			needToDraw=ETrue;
       
   589 			}
       
   590 		}
       
   591 	if (iBuffer.Length()>0)
       
   592 		{
       
   593 		ResetBuffer();
       
   594 		needToDraw=ETrue;
       
   595 		}
       
   596 	const TBool potentiallyInlineEditing=((iInputCapabilities.FepAwareTextEditor()!=NULL) && (iFlags&EFlagInlineEditingEnabled)); // iInputCapabilities.FepAwareTextEditor may return a different value here to the call at the start of the function, hence the need to call it again
       
   597 	iInsertionPoint->SetOn(!IsFocused() && !potentiallyInlineEditing);
       
   598 	if (!potentiallyInlineEditing!=!(iFlags&EFlagHasNoCompositionWindow)) // fold non-zero values on both sides before comparing for inequality
       
   599 		{
       
   600 		const TInt heightOfCompositionWindow=EGapAboveCompositionLine+iCompositionFont->HeightInPixels()+EGapBelowCompositionLine;
       
   601 		TInt windowAdjustmentY;
       
   602 		if (potentiallyInlineEditing)
       
   603 			{
       
   604 			windowAdjustmentY=heightOfCompositionWindow;
       
   605 			iFlags|=EFlagHasNoCompositionWindow;
       
   606 			}
       
   607 		else
       
   608 			{
       
   609 			windowAdjustmentY=-heightOfCompositionWindow;
       
   610 			iFlags&=~EFlagHasNoCompositionWindow;
       
   611 			}
       
   612 		TRect rectangle(Position(), Size()); // creating rectangle from Rect() will give the wrong result as this control owns a window (its top left position would come out as TPoint(0, 0) rather than what Position() returns)
       
   613 		rectangle.iTl.iY+=windowAdjustmentY;
       
   614 		SetRect(rectangle);
       
   615 		needToDraw=ETrue;
       
   616 		}
       
   617 	const TBool shouldBeVisible=(iFep.IsOn() && (iFlags&EFlagForeground));
       
   618 	if (!IsVisible()!=!shouldBeVisible) // fold non-zero values on both sides before comparing for inequality
       
   619 		{
       
   620 		MakeVisible(shouldBeVisible);
       
   621 		needToDraw=EFalse;
       
   622 		}
       
   623 	if (needToDraw)
       
   624 		{
       
   625 		DrawNow();
       
   626 		}
       
   627 	}
       
   628 
       
   629 // The CMoveCursorTimer 
       
   630 
       
   631 CTstControl::CMoveCursorTimer::~CMoveCursorTimer()
       
   632 {
       
   633 	// Cancel and delete anything
       
   634 	Cancel();
       
   635 }
       
   636 
       
   637 
       
   638 CTstControl::CMoveCursorTimer::CMoveCursorTimer(CTstControl& aControl):CTimer(EPriorityStandard),iControl(aControl)
       
   639 {
       
   640 		CActiveScheduler::Add(this);
       
   641 }
       
   642 
       
   643 CTstControl::CMoveCursorTimer* CTstControl::CMoveCursorTimer::NewL(CTstControl& aControl)
       
   644 {
       
   645 	CMoveCursorTimer* cursorTimer = new (ELeave) CMoveCursorTimer(aControl);
       
   646 	CleanupStack::PushL(cursorTimer);
       
   647 	cursorTimer->ConstructL();
       
   648 	CleanupStack::Pop();
       
   649 	return cursorTimer;
       
   650 }
       
   651 
       
   652 
       
   653 void CTstControl::CMoveCursorTimer::ConstructL()
       
   654 {
       
   655 	CTimer::ConstructL();
       
   656 }
       
   657 
       
   658 void CTstControl::CMoveCursorTimer::RunL()
       
   659 {
       
   660 
       
   661 	TUint moveCursor = iControl.iSelectedCompositionText.iCursorPos+1;
       
   662 	iControl.iCountKeyPressed = 0;
       
   663 	iControl.SetPositionOfInsertionPointInBuffer(moveCursor);
       
   664 	iControl.DrawNow();
       
   665 
       
   666 }
       
   667 
       
   668 
       
   669 void CTstControl::CMoveCursorTimer::StartTimer()
       
   670 {
       
   671 	Cancel();
       
   672 	CTimer::After(600000);
       
   673 }
       
   674 
       
   675 
       
   676 // End of the CMoveCursorTimer 
       
   677 
       
   678 
       
   679 void CTstControl::InsertCompositionCharacterAndDrawNowL(TUint aCharacterCode)
       
   680 	{
       
   681 	if (iBuffer.Length() < EMaximumLengthOfBuffer-1)
       
   682 		{
       
   683 		TTstTextBackup textBackup=iBuffer;
       
   684 		textBackup.PushOntoCleanupStackL();
       
   685 		TBuf<1> buffer=KNullDesC();
       
   686 		buffer.Append(aCharacterCode);
       
   687 		iBuffer.Insert(iSelectedCompositionText.iCursorPos, buffer);
       
   688 		TInt newPositionOfInsertionPointInBuffer=iSelectedCompositionText.iCursorPos+1;
       
   689 		__ASSERT_DEBUG((iInputMethod==EInputMethodPlain) || (iInputMethod==EInputMethodHexadecimalCharacterCode) || (iInputMethod==EInputMethodNumberKeyPad), Panic(EPanicBadInputMethod4));
       
   690 		if (iInputMethod==EInputMethodHexadecimalCharacterCode)
       
   691 			{
       
   692 			if (newPositionOfInsertionPointInBuffer>=ENumberOfHexadecimalDigitsPerCharacterCode)
       
   693 				{
       
   694 				TUint characterCode=0;
       
   695 				for (TInt i=ENumberOfHexadecimalDigitsPerCharacterCode; ; --i)
       
   696 					{
       
   697 					if (i<=0)
       
   698 						{
       
   699 						const TInt positionToInsertCharacterCode=newPositionOfInsertionPointInBuffer-ENumberOfHexadecimalDigitsPerCharacterCode;
       
   700 						iBuffer.Delete(positionToInsertCharacterCode, ENumberOfHexadecimalDigitsPerCharacterCode-1);
       
   701 						iBuffer[positionToInsertCharacterCode]=(TText)characterCode;
       
   702 						newPositionOfInsertionPointInBuffer-=ENumberOfHexadecimalDigitsPerCharacterCode-1;
       
   703 						break;
       
   704 						}
       
   705 					const TCharUC hexadecimalDigit=iBuffer[newPositionOfInsertionPointInBuffer-i];
       
   706 					characterCode*=16;
       
   707 					if ((hexadecimalDigit>='0') && (hexadecimalDigit<='9'))
       
   708 						{
       
   709 						characterCode+=hexadecimalDigit-'0';
       
   710 						}
       
   711 					else if ((hexadecimalDigit>='A') && (hexadecimalDigit<='F'))
       
   712 						{
       
   713 						characterCode+=(hexadecimalDigit-'A')+10;
       
   714 						}
       
   715 					else
       
   716 						{
       
   717 						break;
       
   718 						}
       
   719 					}
       
   720 				}
       
   721 			}
       
   722 		else if (iInputMethod==EInputMethodNumberKeyPad)
       
   723 			{	
       
   724 			const TInt positionToDelete = newPositionOfInsertionPointInBuffer-1;
       
   725 			iBuffer.Delete(positionToDelete,1);
       
   726 			newPositionOfInsertionPointInBuffer = positionToDelete;
       
   727 
       
   728 			if (char(aCharacterCode)=='1')
       
   729 				{
       
   730 				// Does nothing as 1 has Nothing associated with it... 
       
   731 				}
       
   732 			else
       
   733 				{
       
   734 				 if((iCountKeyPressed==0)||(iLastKeyPressed==aCharacterCode))
       
   735 					{
       
   736 					 
       
   737 					const TBool first=(iCountKeyPressed==0); 
       
   738 					iCountKeyPressed++;
       
   739 					iLastKeyPressed=aCharacterCode;
       
   740 					TInt code = iLastKeyPressed - '0';
       
   741 					TInt limit = ((code == 7)||(code == 9)) ? 4 : 3;
       
   742 					if (iCountKeyPressed > limit)
       
   743 						{
       
   744 						 iCountKeyPressed = short(iCountKeyPressed % limit);
       
   745 						 if (iCountKeyPressed == 0)
       
   746 							 iCountKeyPressed = limit;
       
   747 						}
       
   748 					TUint character = Alpha [code] [iCountKeyPressed-1];
       
   749 					if (!first)
       
   750 						{
       
   751 						iBuffer.Delete(newPositionOfInsertionPointInBuffer,1);
       
   752 						}
       
   753 					buffer.Delete(0,1);
       
   754 					buffer.Append(character);
       
   755 					iBuffer.Insert(newPositionOfInsertionPointInBuffer,buffer);
       
   756 					}
       
   757 				 else
       
   758 					{
       
   759 					 if (aCharacterCode == '0') 
       
   760 						{
       
   761 						 iCountKeyPressed = 0;
       
   762 						 newPositionOfInsertionPointInBuffer++;
       
   763 						}
       
   764 					 else
       
   765 						{
       
   766 						iLastKeyPressed = aCharacterCode;
       
   767 						iCountKeyPressed = 1;
       
   768 
       
   769 						TInt code = iLastKeyPressed - '0';
       
   770 						TUint character = Alpha [code] [iCountKeyPressed -1];
       
   771 						buffer.Delete(0,1);
       
   772 						buffer.Append(character);
       
   773 						newPositionOfInsertionPointInBuffer++;
       
   774 						iBuffer.Insert(newPositionOfInsertionPointInBuffer,buffer);
       
   775 						}
       
   776 					}
       
   777 				 iMoveCursorTimer->StartTimer();
       
   778 				}
       
   779 			}
       
   780 		SetPositionOfInsertionPointInBuffer(newPositionOfInsertionPointInBuffer);
       
   781 		MCoeFepAwareTextEditor* const fepAwareTextEditor=iInputCapabilities.FepAwareTextEditor();
       
   782 		if ((fepAwareTextEditor==NULL) || !(iFlags&EFlagInlineEditingEnabled))
       
   783 			{
       
   784 			DrawNow();
       
   785 			}
       
   786 		else
       
   787 			{
       
   788 			SetInlineTextL(*fepAwareTextEditor);
       
   789 			}
       
   790 		
       
   791 		textBackup.PopOffCleanupStack();
       
   792 		}
       
   793 	}
       
   794 
       
   795 
       
   796 void CTstControl::SetInlineTextL(MCoeFepAwareTextEditor& aFepAwareTextEditor)
       
   797 	{
       
   798 	if (iFlags&EFlagInsideInlineEditingTransaction)
       
   799 		{
       
   800 		aFepAwareTextEditor.UpdateFepInlineTextL(iBuffer, iSelectedCompositionText.iCursorPos);
       
   801 		}
       
   802 	else
       
   803 		{
       
   804 		aFepAwareTextEditor.StartFepInlineEditL(iBuffer, iSelectedCompositionText.iCursorPos, ETrue, this, *this, *this);
       
   805 		iFlags|=EFlagInsideInlineEditingTransaction;
       
   806 		}
       
   807 	}
       
   808 
       
   809 void CTstControl::CancelInlineEdit(MCoeFepAwareTextEditor& aFepAwareTextEditor)
       
   810 	{
       
   811 	aFepAwareTextEditor.CancelFepInlineEdit();
       
   812 	iFlags&=~EFlagInsideInlineEditingTransaction;
       
   813 	}
       
   814 
       
   815 void CTstControl::CommitInlineEditL(MCoeFepAwareTextEditor& aFepAwareTextEditor)
       
   816 	{
       
   817 
       
   818 	aFepAwareTextEditor.CommitFepInlineEditL(*iCoeEnv);
       
   819 	iFlags&=~EFlagInsideInlineEditingTransaction;
       
   820 	}
       
   821 
       
   822 void CTstControl::ResetBuffer()
       
   823 	{
       
   824 	SetPositionOfInsertionPointInBuffer(0);
       
   825 	iBuffer.SetLength(0);
       
   826 	}
       
   827 
       
   828 void CTstControl::SetPositionOfInsertionPointInBuffer(TInt aPositionOfInsertionPointInBuffer)
       
   829 	{
       
   830 	iSelectedCompositionText.iCursorPos=aPositionOfInsertionPointInBuffer;
       
   831 	iSelectedCompositionText.iAnchorPos=aPositionOfInsertionPointInBuffer;
       
   832 	iInsertionPoint->SetPosition(PositionOfInsertionPointOnWindow());
       
   833 	}
       
   834 
       
   835 TPoint CTstControl::PositionOfInsertionPointOnWindow() const
       
   836 	{
       
   837 	return TPoint(1+EGapLeftOfEachLine+iCompositionFont->TextWidthInPixels(iBuffer.Left(iSelectedCompositionText.iCursorPos)), 1+EGapAboveCompositionLine+iCompositionFont->HeightInPixels());
       
   838 	}
       
   839 
       
   840 void CTstControl::GetFormatAtDocumentPosition(TCharFormat& aFormat, TInt aDocumentPosition, const MCoeFepAwareTextEditor& aFepAwareTextEditor)
       
   841 	{
       
   842 	if (aDocumentPosition<0)
       
   843 		{
       
   844 		aDocumentPosition=0;
       
   845 		}
       
   846 	const TInt documentLength=aFepAwareTextEditor.DocumentLengthForFep();
       
   847 	if (aDocumentPosition>documentLength)
       
   848 		{
       
   849 		aDocumentPosition=documentLength;
       
   850 		}
       
   851 	aFepAwareTextEditor.GetFormatForFep(aFormat, aDocumentPosition);
       
   852 	}
       
   853 
       
   854 TInt CTstControl::NumberOfCharactersInBuffer(const CBase* aControl)
       
   855 	{
       
   856 	return STATIC_CAST(const CTstControl*, aControl)->iBuffer.Length();
       
   857 	}
       
   858 
       
   859 const TAny* CTstControl::CharacterInBuffer(const CBase* aControl, TInt aIndex)
       
   860 	{
       
   861 	CTstControl* control=STATIC_CAST(CTstControl*, CONST_CAST(CBase*, aControl));
       
   862 	control->iCharacterCode=control->iBuffer[aIndex];
       
   863 	return &control->iCharacterCode;
       
   864 	}
       
   865 
       
   866 TKeyResponse CTstControl::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aEventCode)
       
   867 	{
       
   868 	// CTstFep::OfferKeyEventL assumes that this will not leave if it returns EKeyWasNotConsumed
       
   869 	FEP_START_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, aEventCode);
       
   870 	const TBool isFocused=IsFocused();
       
   871 	const TCharUC keyCodeInUpperCase=aKeyEvent.iCode;
       
   872 	TInt bufferLength=iBuffer.Length();
       
   873 	if ((aKeyEvent.iModifiers&EModifierRightShift) && !isFocused && (bufferLength==0))
       
   874 		{
       
   875 		switch (keyCodeInUpperCase)
       
   876 			{
       
   877 		case 'F':
       
   878 			ChangeSetupAndResetBufferAndDrawNow(SetFocus, ETrue);
       
   879 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed);
       
   880 		case 'I':
       
   881 			ChangeSetupAndResetBufferAndDrawNow(SetFlagInlineEditingEnabled, !(iFlags&EFlagInlineEditingEnabled));
       
   882 			iFep.WriteAttributeDataAndBroadcastL(TUid::Uid(ETstInlineEditingEnabledUid));
       
   883 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed);
       
   884 		case 'M':
       
   885 			ChangeSetupAndResetBufferAndDrawNow(SetInputMethod, (iInputMethod+1<EInputMethodOnePastTheLast)? iInputMethod+1: 0);
       
   886 			iFep.WriteAttributeDataAndBroadcastL(TUid::Uid(ETstInputMethodUid));
       
   887 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed);
       
   888 		case 'N':
       
   889 			{
       
   890 			const MCoeFepAwareTextEditor* const fepAwareTextEditor=iInputCapabilities.FepAwareTextEditor();
       
   891 			if (fepAwareTextEditor==NULL)
       
   892 				{
       
   893 				User::InfoPrint(KLitNotAvailable);
       
   894 				}
       
   895 			else
       
   896 				{
       
   897 				TCursorSelection cursorSelection;
       
   898 				fepAwareTextEditor->GetCursorSelectionForFep(cursorSelection);
       
   899 				TPoint position;
       
   900 				TInt height;
       
   901 				TInt ascent;
       
   902 				fepAwareTextEditor->GetScreenCoordinatesForFepL(position,height,ascent,cursorSelection.LowerPos());
       
   903 				position.iY+=height-ascent;
       
   904 				const TSize screenSize(iCoeEnv->ScreenDevice()->SizeInPixels());
       
   905 				const TInt xMaximum=screenSize.iWidth-iSize.iWidth;
       
   906 				if ((position.iX<0) || (xMaximum<0))
       
   907 					{
       
   908 					position.iX=0;
       
   909 					}
       
   910 				else if (position.iX>xMaximum)
       
   911 					{
       
   912 					position.iX=xMaximum;
       
   913 					}
       
   914 				const TInt yMaximum=screenSize.iHeight-iSize.iHeight;
       
   915 				if ((position.iY<0) || (yMaximum<0))
       
   916 					{
       
   917 					position.iY=0;
       
   918 					}
       
   919 				else
       
   920 					{
       
   921 					const TInt yOverlapIfFepIsBelow=position.iY-yMaximum;
       
   922 					if (yOverlapIfFepIsBelow>0)
       
   923 						{
       
   924 						const TInt yPositionIfFepIsAbove=Max(0, position.iY-(height+iSize.iHeight));
       
   925 						const TInt yOverlapIfFepIsAbove=(yPositionIfFepIsAbove+iSize.iHeight)-(position.iY-height);
       
   926 						if (yOverlapIfFepIsAbove<yOverlapIfFepIsBelow)
       
   927 							{
       
   928 							position.iY=yPositionIfFepIsAbove;
       
   929 							}
       
   930 						}
       
   931 					}
       
   932 				SetPosition(position);
       
   933 				}
       
   934 			}
       
   935 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed);
       
   936 		case 'B':
       
   937 		case 'A':
       
   938 		case 'S':
       
   939 			{
       
   940 			const MCoeFepAwareTextEditor* const fepAwareTextEditor=iInputCapabilities.FepAwareTextEditor();
       
   941 			TBuf<40+EMaximumLengthOfDisplayOfContextInformation> textToDisplay;
       
   942 			if (fepAwareTextEditor==NULL)
       
   943 				{
       
   944 				textToDisplay=KLitNotAvailable;
       
   945 				}
       
   946 			else
       
   947 				{
       
   948 				TCursorSelection cursorSelection;
       
   949 				fepAwareTextEditor->GetCursorSelectionForFep(cursorSelection);
       
   950 				switch (keyCodeInUpperCase)
       
   951 					{
       
   952 				case 'B':
       
   953 					{
       
   954 					TInt lengthToRetrieve=EMaximumLengthOfDisplayOfContextInformation+1;
       
   955 					TInt documentPositionBeforeSelection=cursorSelection.LowerPos()-lengthToRetrieve;
       
   956 					if (documentPositionBeforeSelection<0)
       
   957 						{
       
   958 						lengthToRetrieve+=documentPositionBeforeSelection; // same as doing "lengthToRetrieve=cursorSelection.LowerPos()", hence the assert below
       
   959 						__ASSERT_DEBUG(lengthToRetrieve==cursorSelection.LowerPos(), Panic(EPanicArithmeticConfusion));
       
   960 						documentPositionBeforeSelection=0;
       
   961 						}
       
   962 					fepAwareTextEditor->GetEditorContentForFep(textToDisplay, documentPositionBeforeSelection, lengthToRetrieve);
       
   963 					const TInt lengthOfTextBeforeSelection=textToDisplay.Length();
       
   964 					if (lengthOfTextBeforeSelection>EMaximumLengthOfDisplayOfContextInformation)
       
   965 						{
       
   966 						textToDisplay.Delete(0, (lengthOfTextBeforeSelection-EMaximumLengthOfDisplayOfContextInformation)-1);
       
   967 						__ASSERT_DEBUG(textToDisplay.Length()==EMaximumLengthOfDisplayOfContextInformation+1, Panic(EPanicBadLengthOfTextBeforeSelection));
       
   968 						textToDisplay[0]=KEllipsisCharacter;
       
   969 						}
       
   970 					}
       
   971 					textToDisplay.Insert(0, KLitQuotationMark);
       
   972 					textToDisplay.Append(KLitQuotationMark);
       
   973 					textToDisplay.Insert(0, KLitTextBeforeSelectionColonSpace);
       
   974 					break;
       
   975 				case 'A':
       
   976 					{
       
   977 					const TInt documentLength=fepAwareTextEditor->DocumentLengthForFep();
       
   978 					const TInt documentPositionAfterSelection=cursorSelection.HigherPos()+1;
       
   979 					if (documentPositionAfterSelection>documentLength)
       
   980 						{
       
   981 						__ASSERT_DEBUG(documentPositionAfterSelection==documentLength+1, Panic(EPanicSelectionExtendsPastEndOfDocument));
       
   982 						}
       
   983 					else
       
   984 						{
       
   985 						fepAwareTextEditor->GetEditorContentForFep(textToDisplay, documentPositionAfterSelection, EMaximumLengthOfDisplayOfContextInformation+1);
       
   986 						const TInt lengthOfTextAfterSelection=textToDisplay.Length();
       
   987 						if (lengthOfTextAfterSelection>EMaximumLengthOfDisplayOfContextInformation)
       
   988 							{
       
   989 							textToDisplay.Delete(EMaximumLengthOfDisplayOfContextInformation, (lengthOfTextAfterSelection-EMaximumLengthOfDisplayOfContextInformation)-1);
       
   990 							__ASSERT_DEBUG(textToDisplay.Length()==EMaximumLengthOfDisplayOfContextInformation+1, Panic(EPanicBadLengthOfTextAfterSelection));
       
   991 							textToDisplay[EMaximumLengthOfDisplayOfContextInformation]=KEllipsisCharacter;
       
   992 							}
       
   993 						}
       
   994 					}
       
   995 					textToDisplay.Insert(0, KLitQuotationMark);
       
   996 					textToDisplay.Append(KLitQuotationMark);
       
   997 					textToDisplay.Insert(0, KLitTextAfterSelectionColonSpace);
       
   998 					break;
       
   999 				case 'S':
       
  1000 					fepAwareTextEditor->GetEditorContentForFep(textToDisplay, cursorSelection.LowerPos(), EMaximumLengthOfDisplayOfContextInformation+1);
       
  1001 					{
       
  1002 					const TInt lengthOfSelection=textToDisplay.Length();
       
  1003 					if (lengthOfSelection>EMaximumLengthOfDisplayOfContextInformation)
       
  1004 						{
       
  1005 						textToDisplay.Delete(EMaximumLengthOfDisplayOfContextInformation, (lengthOfSelection-EMaximumLengthOfDisplayOfContextInformation)-1);
       
  1006 						__ASSERT_DEBUG(textToDisplay.Length()==EMaximumLengthOfDisplayOfContextInformation+1, Panic(EPanicBadLengthOfSelection));
       
  1007 						textToDisplay[EMaximumLengthOfDisplayOfContextInformation]=KEllipsisCharacter;
       
  1008 						}
       
  1009 					}
       
  1010 					textToDisplay.Insert(0, KLitQuotationMark);
       
  1011 					textToDisplay.Append(KLitQuotationMark);
       
  1012 					textToDisplay.Insert(0, KLitSelectionColonSpace);
       
  1013 					break;
       
  1014 #if defined(_DEBUG)
       
  1015 				default:
       
  1016 					Panic(EPanicBadKeyCode1);
       
  1017 					break;
       
  1018 #endif
       
  1019 					}
       
  1020 				}
       
  1021 			User::InfoPrint(textToDisplay);
       
  1022 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed);
       
  1023 			}
       
  1024 			}
       
  1025 		}
       
  1026 	switch (keyCodeInUpperCase)
       
  1027 		{
       
  1028 	case EKeyEnter:
       
  1029 	case EKeyEscape:
       
  1030 		if (isFocused)
       
  1031 			{
       
  1032 			ChangeSetupAndResetBufferAndDrawNow(SetFocus, EFalse);
       
  1033 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed);
       
  1034 			}
       
  1035 		if (bufferLength>0)
       
  1036 			{
       
  1037 			TBool needToDraw=ETrue;
       
  1038 			switch (keyCodeInUpperCase)
       
  1039 				{
       
  1040 			case EKeyEnter:
       
  1041 				if (~iFlags&EFlagInsideInlineEditingTransaction)
       
  1042 					{
       
  1043 					iFep.SimulateKeyEventsL(TArray<TUint>(NumberOfCharactersInBuffer, CharacterInBuffer, this));
       
  1044 					}
       
  1045 				else
       
  1046 					{
       
  1047 					CommitInlineEditL(*iInputCapabilities.FepAwareTextEditor()); 
       
  1048 					needToDraw=EFalse;
       
  1049 					}
       
  1050 				break;
       
  1051 			case EKeyEscape:
       
  1052 				if (iFlags&EFlagInsideInlineEditingTransaction)
       
  1053 					{
       
  1054 					CancelInlineEdit(*iInputCapabilities.FepAwareTextEditor());
       
  1055 					needToDraw=EFalse;
       
  1056 					}
       
  1057 				break;
       
  1058 #if defined(_DEBUG)
       
  1059 			default:
       
  1060 				Panic(EPanicBadKeyCode2);
       
  1061 				break;
       
  1062 #endif
       
  1063 				}
       
  1064 
       
  1065 			ResetBuffer();
       
  1066 			if (needToDraw)
       
  1067 				{
       
  1068 				DrawNow();
       
  1069 				}
       
  1070 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed);
       
  1071 			}
       
  1072 		break;
       
  1073 	case EKeyDelete:
       
  1074 	case EKeyBackspace:
       
  1075 		if (!isFocused && (bufferLength>0))
       
  1076 			{
       
  1077 			const TBool deletePreviousCharacter=((keyCodeInUpperCase==EKeyBackspace) && !(aKeyEvent.iModifiers&EModifierShift));
       
  1078 			if (deletePreviousCharacter? (iSelectedCompositionText.iCursorPos>0): (iSelectedCompositionText.iCursorPos<bufferLength))
       
  1079 				{
       
  1080 				TTstTextBackup textBackup=iBuffer;
       
  1081 				textBackup.PushOntoCleanupStackL();
       
  1082 				if (deletePreviousCharacter)
       
  1083 					{
       
  1084 					SetPositionOfInsertionPointInBuffer(iSelectedCompositionText.iCursorPos-1);
       
  1085 					}
       
  1086 				iBuffer.Delete(iSelectedCompositionText.iCursorPos, 1);
       
  1087 				if (~iFlags&EFlagInsideInlineEditingTransaction)
       
  1088 					{
       
  1089 					DrawNow();
       
  1090 					}
       
  1091 				else
       
  1092 					{
       
  1093 					if (bufferLength-1>0)
       
  1094 						{
       
  1095 						SetInlineTextL(*iInputCapabilities.FepAwareTextEditor());
       
  1096 						}
       
  1097 					else
       
  1098 						{
       
  1099 						CancelInlineEdit(*iInputCapabilities.FepAwareTextEditor());
       
  1100 						}
       
  1101 					}
       
  1102 				textBackup.PopOffCleanupStack();
       
  1103 				}
       
  1104 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed);
       
  1105 			}
       
  1106 		break;
       
  1107 	case EKeySpace:
       
  1108 		if (!isFocused && (bufferLength>0))
       
  1109 			{
       
  1110 			__ASSERT_DEBUG((iInputMethod==EInputMethodPlain) || (iInputMethod==EInputMethodHexadecimalCharacterCode) || (iInputMethod==EInputMethodNumberKeyPad), Panic(EPanicBadInputMethod2));
       
  1111 			if ((iInputMethod==EInputMethodPlain) && (iSelectedCompositionText.iCursorPos<bufferLength))
       
  1112 				{
       
  1113 				const TInt increment=(aKeyEvent.iModifiers&EModifierShift)? -1: 1;
       
  1114 				const TCharUC limit=(aKeyEvent.iModifiers&EModifierShift)? 'A': 'Z';
       
  1115 				const TCharUC characterToAdjust=iBuffer[iSelectedCompositionText.iCursorPos];
       
  1116 				__ASSERT_DEBUG((characterToAdjust>='A') && (characterToAdjust<='Z'), Panic(EPanicBadCharacterInBuffer));
       
  1117 				if (characterToAdjust!=limit)
       
  1118 					{
       
  1119 					TTstTextBackup textBackup=iBuffer;
       
  1120 					textBackup.PushOntoCleanupStackL();
       
  1121 					iBuffer[iSelectedCompositionText.iCursorPos]=(TText)(iBuffer[iSelectedCompositionText.iCursorPos]+increment);
       
  1122 					if (iFlags&EFlagInsideInlineEditingTransaction)
       
  1123 						{
       
  1124 						SetInlineTextL(*iInputCapabilities.FepAwareTextEditor());
       
  1125 						}
       
  1126 					else
       
  1127 						{
       
  1128 						DrawNow();
       
  1129 						}
       
  1130 					textBackup.PopOffCleanupStack();
       
  1131 					}
       
  1132 				}
       
  1133 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed);
       
  1134 			}
       
  1135 		break;
       
  1136 	case EKeyHome:
       
  1137 	case EKeyEnd:
       
  1138 	case EKeyPageUp:
       
  1139 	case EKeyPageDown:
       
  1140 	case EKeyLeftArrow:
       
  1141 	case EKeyRightArrow:
       
  1142 	case EKeyUpArrow:
       
  1143 	case EKeyDownArrow:
       
  1144 		if (isFocused)
       
  1145 			{
       
  1146 			TPoint offset(0, 0);
       
  1147 			TInt magnification=10;
       
  1148 			switch (keyCodeInUpperCase)
       
  1149 				{
       
  1150 			case EKeyLeftArrow:
       
  1151 				offset.iX=-1;
       
  1152 				break;
       
  1153 			case EKeyRightArrow:
       
  1154 				offset.iX=1;
       
  1155 				break;
       
  1156 			case EKeyUpArrow:
       
  1157 				offset.iY=-1;
       
  1158 				break;
       
  1159 			case EKeyDownArrow:
       
  1160 				offset.iY=1;
       
  1161 				break;
       
  1162 			case EKeyHome:
       
  1163 				offset.iX=-iPosition.iX;
       
  1164 				offset.iY=-iPosition.iY;
       
  1165 				magnification=1;
       
  1166 				break;
       
  1167 			case EKeyEnd:
       
  1168 				{
       
  1169 				const TSize screenWidth(iCoeEnv->ScreenDevice()->SizeInPixels());
       
  1170 				offset.iX=(screenWidth.iWidth-iSize.iWidth)-iPosition.iX;
       
  1171 				offset.iY=(screenWidth.iHeight-iSize.iHeight)-iPosition.iY;
       
  1172 				}
       
  1173 				magnification=1;
       
  1174 				break;
       
  1175 			case EKeyPageUp:
       
  1176 				offset.iY=-iSize.iHeight;
       
  1177 				magnification=1;
       
  1178 				break;
       
  1179 			case EKeyPageDown:
       
  1180 				offset.iY=iSize.iHeight;
       
  1181 				magnification=1;
       
  1182 				break;
       
  1183 #if defined(_DEBUG)
       
  1184 			default:
       
  1185 				Panic(EPanicBadKeyCode3);
       
  1186 				break;
       
  1187 #endif
       
  1188 				}
       
  1189 			if (aKeyEvent.iModifiers&EModifierCtrl)
       
  1190 				{
       
  1191 				offset.iX*=magnification;
       
  1192 				offset.iY*=magnification;
       
  1193 				}
       
  1194 			SetPosition(TPoint(iPosition.iX+offset.iX, iPosition.iY+offset.iY));
       
  1195 			if (iFlags&EFlagWindowIsBeingDragged)
       
  1196 				{
       
  1197 				iPositionOnWindowBeingDragged.iX-=offset.iX;
       
  1198 				iPositionOnWindowBeingDragged.iY-=offset.iY;
       
  1199 				}
       
  1200 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed);
       
  1201 			}
       
  1202 		if (bufferLength>0)
       
  1203 			{
       
  1204 			TInt newPositionOfInsertionPointInBuffer=iSelectedCompositionText.iCursorPos;
       
  1205 			switch (keyCodeInUpperCase)
       
  1206 				{
       
  1207 			case EKeyLeftArrow:
       
  1208 				if (newPositionOfInsertionPointInBuffer>0)
       
  1209 					{
       
  1210 					--newPositionOfInsertionPointInBuffer;
       
  1211 					}
       
  1212 				break;
       
  1213 			case EKeyRightArrow:
       
  1214 				if (newPositionOfInsertionPointInBuffer<bufferLength)
       
  1215 					{
       
  1216 					++newPositionOfInsertionPointInBuffer;
       
  1217 					}
       
  1218 				break;
       
  1219 			case EKeyHome:
       
  1220 			case EKeyPageUp:
       
  1221 			case EKeyUpArrow:
       
  1222 				newPositionOfInsertionPointInBuffer=0;
       
  1223 				break;
       
  1224 			case EKeyEnd:
       
  1225 			case EKeyPageDown:
       
  1226 			case EKeyDownArrow:
       
  1227 				newPositionOfInsertionPointInBuffer=bufferLength;
       
  1228 				break;
       
  1229 #if defined(_DEBUG)
       
  1230 			default:
       
  1231 				Panic(EPanicBadKeyCode4);
       
  1232 				break;
       
  1233 #endif
       
  1234 				}
       
  1235 			if (iSelectedCompositionText.iCursorPos!=newPositionOfInsertionPointInBuffer)
       
  1236 				{
       
  1237 				SetPositionOfInsertionPointInBuffer(newPositionOfInsertionPointInBuffer);
       
  1238 				}
       
  1239 			if (iFlags&EFlagInsideInlineEditingTransaction)
       
  1240 				{
       
  1241 				SetInlineTextL(*iInputCapabilities.FepAwareTextEditor());
       
  1242 				}
       
  1243 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed);
       
  1244 			}
       
  1245 		break;
       
  1246 	default:
       
  1247 		if (isFocused)
       
  1248 			{
       
  1249 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed);
       
  1250 			}
       
  1251 		TBool isLegalCompositionCharacter=EFalse;
       
  1252 		switch (iInputMethod)
       
  1253 			{
       
  1254 		case EInputMethodPlain:
       
  1255 			isLegalCompositionCharacter=keyCodeInUpperCase.IsAlpha();
       
  1256 			break;
       
  1257 		case EInputMethodHexadecimalCharacterCode:
       
  1258 			isLegalCompositionCharacter=keyCodeInUpperCase.IsHexDigit();
       
  1259 			break;
       
  1260 		case EInputMethodNumberKeyPad:
       
  1261 			isLegalCompositionCharacter=keyCodeInUpperCase.IsDigit();
       
  1262 			break;
       
  1263 		case EInputMethodOnePastTheLast:
       
  1264 #if defined(_DEBUG)
       
  1265 		default:
       
  1266 			Panic(EPanicBadInputMethod3);
       
  1267 #endif
       
  1268 			break;
       
  1269 			}
       
  1270 		if (isLegalCompositionCharacter)
       
  1271 			{
       
  1272 			iCharacterCode=aKeyEvent.iCode;// set iCharacterCode to aKeyEvent.iCode rather than keyCodeInUpperCase so that the original case is preserved
       
  1273 			iFep.MakeDeferredFunctionCall(*this); // deferred call to InsertCompositionCharacterAndDrawNowL
       
  1274 			if (bufferLength==0)
       
  1275 				{
       
  1276 				iCoeEnv->ForEachFepObserverCall(FepObserverHandleStartOfTransactionL); // must be called before inserting the composition character as an application's HandleStartOfTransactionL function may move focus to a control supporting inline-editing
       
  1277 				}
       
  1278 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed);
       
  1279 			}
       
  1280 		if (bufferLength>0)
       
  1281 			{
       
  1282 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed);
       
  1283 			}
       
  1284 		break;
       
  1285 		}
       
  1286 	FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasNotConsumed);
       
  1287 	}
       
  1288 
       
  1289 void CTstControl::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
  1290 	{
       
  1291 	switch (aPointerEvent.iType)
       
  1292 		{
       
  1293 	case TPointerEvent::EButton1Down:
       
  1294 	case TPointerEvent::EDrag:
       
  1295 		if (iFlags&EFlagWindowIsBeingDragged)
       
  1296 			{
       
  1297 			SetPosition(aPointerEvent.iParentPosition-iPositionOnWindowBeingDragged);
       
  1298 			}
       
  1299 		else
       
  1300 			{
       
  1301 			iFlags|=EFlagWindowIsBeingDragged;
       
  1302 			iPositionOnWindowBeingDragged=aPointerEvent.iPosition;
       
  1303 			}
       
  1304 		break;
       
  1305 	case TPointerEvent::EButton1Up:
       
  1306 		iFlags&=~EFlagWindowIsBeingDragged;
       
  1307 		break;
       
  1308 #if defined(__GCC32__)
       
  1309 	default:
       
  1310 		break;
       
  1311 #endif
       
  1312 		}
       
  1313 	}
       
  1314 
       
  1315 void CTstControl::Draw(const TRect&) const
       
  1316 	{
       
  1317 	CWindowGc& graphicsContext=SystemGc();
       
  1318 	graphicsContext.SetPenStyle(CGraphicsContext::ESolidPen);
       
  1319 	graphicsContext.SetPenColor(KRgbBlack);
       
  1320 	graphicsContext.SetBrushStyle(CGraphicsContext::ENullBrush);
       
  1321 	TRect rectangle(Rect());
       
  1322 	graphicsContext.DrawRect(rectangle);
       
  1323 	rectangle.Shrink(1, 1);
       
  1324 	graphicsContext.SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  1325 	if (IsFocused())
       
  1326 		{
       
  1327 		__ASSERT_DEBUG(iBuffer.Length()==0, Panic(EPanicInconsistentState));
       
  1328 		// the pen color is still black here
       
  1329 		graphicsContext.SetBrushColor(KRgbBlack);
       
  1330 		graphicsContext.DrawRect(rectangle);
       
  1331 		const TPoint center=rectangle.Center();
       
  1332 		graphicsContext.SetPenColor(KRgbWhite);
       
  1333 		const TPoint leftArrowHead((rectangle.iTl.iX+center.iX)/2, center.iY);
       
  1334 		const TPoint rightArrowHead((center.iX+rectangle.iBr.iX)/2, center.iY);
       
  1335 		const TPoint topArrowHead(center.iX, (rectangle.iTl.iY+center.iY)/2);
       
  1336 		const TPoint bottomArrowHead(center.iX, (center.iY+rectangle.iBr.iY)/2);
       
  1337 		graphicsContext.DrawLine(leftArrowHead, rightArrowHead);
       
  1338 		graphicsContext.Plot(rightArrowHead);
       
  1339 		graphicsContext.DrawLine(topArrowHead, bottomArrowHead);
       
  1340 		graphicsContext.Plot(bottomArrowHead);
       
  1341 		graphicsContext.DrawLine(TPoint(leftArrowHead.iX+EArrowHeadSize, leftArrowHead.iY+EArrowHeadSize), leftArrowHead);
       
  1342 		graphicsContext.DrawLine(TPoint(leftArrowHead.iX+EArrowHeadSize, leftArrowHead.iY-EArrowHeadSize), leftArrowHead);
       
  1343 		graphicsContext.DrawLine(TPoint(rightArrowHead.iX-EArrowHeadSize, rightArrowHead.iY-EArrowHeadSize), rightArrowHead);
       
  1344 		graphicsContext.DrawLine(TPoint(rightArrowHead.iX-EArrowHeadSize, rightArrowHead.iY+EArrowHeadSize), rightArrowHead);
       
  1345 		graphicsContext.DrawLine(TPoint(topArrowHead.iX-EArrowHeadSize, topArrowHead.iY+EArrowHeadSize), topArrowHead);
       
  1346 		graphicsContext.DrawLine(TPoint(topArrowHead.iX+EArrowHeadSize, topArrowHead.iY+EArrowHeadSize), topArrowHead);
       
  1347 		graphicsContext.DrawLine(TPoint(bottomArrowHead.iX+EArrowHeadSize, bottomArrowHead.iY-EArrowHeadSize), bottomArrowHead);
       
  1348 		graphicsContext.DrawLine(TPoint(bottomArrowHead.iX-EArrowHeadSize, bottomArrowHead.iY-EArrowHeadSize), bottomArrowHead);
       
  1349 		}
       
  1350 	else
       
  1351 		{
       
  1352 		TRect temp(rectangle);
       
  1353 		temp.iBr.iY=temp.iTl.iY;
       
  1354 		graphicsContext.SetBrushColor(KRgbWhite);
       
  1355 		if (~iFlags&EFlagHasNoCompositionWindow)
       
  1356 			{
       
  1357 			graphicsContext.UseFont(iCompositionFont);
       
  1358 			temp.iBr.iY+=EGapAboveCompositionLine+iCompositionFont->HeightInPixels()+EGapBelowCompositionLine;
       
  1359 			graphicsContext.DrawText(iBuffer, temp, EGapAboveCompositionLine+iCompositionFont->AscentInPixels(), CGraphicsContext::ELeft, EGapLeftOfEachLine);
       
  1360 			graphicsContext.DiscardFont();
       
  1361 			}
       
  1362 		TBuf<200> textToDisplay;
       
  1363 		textToDisplay=KLitInputMethodColonSpace;
       
  1364 		switch (iInputMethod)
       
  1365 			{
       
  1366 		case EInputMethodPlain:
       
  1367 			textToDisplay.Append(KLitPlain);
       
  1368 			break;
       
  1369 		case EInputMethodHexadecimalCharacterCode:
       
  1370 			textToDisplay.Append(KLitHexadecimalCharacterCode);
       
  1371 			break;
       
  1372 		case EInputMethodNumberKeyPad:
       
  1373 			textToDisplay.Append(KLitNumberKeyPad);
       
  1374 			break;
       
  1375 		default:
       
  1376 #if defined(_DEBUG)
       
  1377 			Panic(EPanicBadInputMethod5);
       
  1378 #endif
       
  1379 			break;
       
  1380 			}
       
  1381 		const TInt statusFontHeightInPixels=iStatusFont->HeightInPixels();
       
  1382 		const TInt statusFontAscentInPixels=iStatusFont->AscentInPixels();
       
  1383 		graphicsContext.SetBrushColor(KRgbGray);
       
  1384 		graphicsContext.UseFont(iStatusFont);
       
  1385 		temp.iTl.iY=temp.iBr.iY;
       
  1386 		temp.iBr.iY+=EGapAboveTopStatusLine+statusFontHeightInPixels+EGapBetweenEachStatusLine;
       
  1387 		graphicsContext.DrawText(textToDisplay, temp, EGapAboveTopStatusLine+statusFontAscentInPixels, CGraphicsContext::ELeft, EGapLeftOfEachLine);
       
  1388 		textToDisplay=KLitInlineEditingColonSpace;
       
  1389 		textToDisplay.Append((iFlags&EFlagInlineEditingEnabled)? KLitEnabled(): KLitDisabled());
       
  1390 		temp.iTl.iY=temp.iBr.iY;
       
  1391 		temp.iBr.iY+=statusFontHeightInPixels+EGapBetweenEachStatusLine;
       
  1392 		graphicsContext.DrawText(textToDisplay, temp, statusFontAscentInPixels, CGraphicsContext::ELeft, EGapLeftOfEachLine);
       
  1393 		textToDisplay=KLitOpeningSquareBracket;
       
  1394 		textToDisplay.Append(KLitCaptionColonSpace);
       
  1395 		textToDisplay.Append(KLitQuotationMark);
       
  1396 		const MCoeCaptionRetrieverForFep* captionRetrieverForFep=iInputCapabilities.CaptionRetrieverForFep();
       
  1397 		if (captionRetrieverForFep!=NULL)
       
  1398 			{
       
  1399 			TBuf<51> caption;
       
  1400 			captionRetrieverForFep->GetCaptionForFep(caption);
       
  1401 			const TInt captionLength=caption.Length();
       
  1402 			if (captionLength==caption.MaxLength())
       
  1403 				{
       
  1404 				caption[captionLength-1]=KEllipsisCharacter;
       
  1405 				}
       
  1406 			textToDisplay.Append(caption);
       
  1407 			}
       
  1408 		textToDisplay.Append(KLitQuotationMark);
       
  1409 		textToDisplay.Append(KLitClosingSquareBracket);
       
  1410 		temp.iTl.iY=temp.iBr.iY;
       
  1411 		temp.iBr.iY+=statusFontHeightInPixels+EGapBetweenEachStatusLine;
       
  1412 		graphicsContext.DrawText(textToDisplay, temp, statusFontAscentInPixels, CGraphicsContext::ELeft, EGapLeftOfEachLine);
       
  1413 		textToDisplay=KLitOpeningSquareBracket;
       
  1414 		textToDisplay.Append(KLitInputCapabilitiesColonSpace);
       
  1415 		if (iInputCapabilities.IsNone())
       
  1416 			{
       
  1417 			textToDisplay.Append(KLitNone);
       
  1418 			}
       
  1419 		else
       
  1420 			{
       
  1421 			TBool deleteLastSeparator=EFalse;
       
  1422 			if (iInputCapabilities.SupportsWesternNumericIntegerPositive())
       
  1423 				{
       
  1424 				textToDisplay.Append(KLitWesternNumericIntegerPositive);
       
  1425 				textToDisplay.Append(KLitCommaSpace);
       
  1426 				deleteLastSeparator=ETrue;
       
  1427 				}
       
  1428 			if (iInputCapabilities.SupportsWesternNumericIntegerNegative())
       
  1429 				{
       
  1430 				textToDisplay.Append(KLitWesternNumericIntegerNegative);
       
  1431 				textToDisplay.Append(KLitCommaSpace);
       
  1432 				deleteLastSeparator=ETrue;
       
  1433 				}
       
  1434 			if (iInputCapabilities.SupportsWesternNumericReal())
       
  1435 				{
       
  1436 				textToDisplay.Append(KLitWesternNumericReal);
       
  1437 				textToDisplay.Append(KLitCommaSpace);
       
  1438 				deleteLastSeparator=ETrue;
       
  1439 				}
       
  1440 			if (iInputCapabilities.SupportsWesternAlphabetic())
       
  1441 				{
       
  1442 				textToDisplay.Append(KLitWesternAlphabetic);
       
  1443 				textToDisplay.Append(KLitCommaSpace);
       
  1444 				deleteLastSeparator=ETrue;
       
  1445 				}
       
  1446 			if (iInputCapabilities.SupportsJapaneseHiragana())
       
  1447 				{
       
  1448 				textToDisplay.Append(KLitJapaneseHiragana);
       
  1449 				textToDisplay.Append(KLitCommaSpace);
       
  1450 				deleteLastSeparator=ETrue;
       
  1451 				}
       
  1452 			if (iInputCapabilities.SupportsJapaneseKatakanaHalfWidth())
       
  1453 				{
       
  1454 				textToDisplay.Append(KLitJapaneseKatakanaHalfWidth);
       
  1455 				textToDisplay.Append(KLitCommaSpace);
       
  1456 				deleteLastSeparator=ETrue;
       
  1457 				}
       
  1458 			if (iInputCapabilities.SupportsJapaneseKatakanaFullWidth())
       
  1459 				{
       
  1460 				textToDisplay.Append(KLitJapaneseKatakanaFullWidth);
       
  1461 				textToDisplay.Append(KLitCommaSpace);
       
  1462 				deleteLastSeparator=ETrue;
       
  1463 				}
       
  1464 			if (iInputCapabilities.SupportsDialableCharacters())
       
  1465 				{
       
  1466 				textToDisplay.Append(KLitDialableCharacters);
       
  1467 				textToDisplay.Append(KLitCommaSpace);
       
  1468 				deleteLastSeparator=ETrue;
       
  1469 				}
       
  1470 			if (iInputCapabilities.SupportsSecretText())
       
  1471 				{
       
  1472 				textToDisplay.Append(KLitSecretText);
       
  1473 				textToDisplay.Append(KLitCommaSpace);
       
  1474 				deleteLastSeparator=ETrue;
       
  1475 				}
       
  1476 			if (iInputCapabilities.SupportsAllText())
       
  1477 				{
       
  1478 				textToDisplay.Append(KLitAllText);
       
  1479 				textToDisplay.Append(KLitCommaSpace);
       
  1480 				deleteLastSeparator=ETrue;
       
  1481 				}
       
  1482 			if (iInputCapabilities.SupportsNavigation())
       
  1483 				{
       
  1484 				textToDisplay.Append(KLitNavigation);
       
  1485 				textToDisplay.Append(KLitCommaSpace);
       
  1486 				deleteLastSeparator=ETrue;
       
  1487 				}
       
  1488 			if (deleteLastSeparator)
       
  1489 				{
       
  1490 				const TInt lengthToDelete=KLitCommaSpace().Length();
       
  1491 				textToDisplay.Delete(textToDisplay.Length()-lengthToDelete, lengthToDelete);
       
  1492 				}
       
  1493 			}
       
  1494 		textToDisplay.Append(KLitClosingSquareBracket);
       
  1495 		temp.iTl.iY=temp.iBr.iY;
       
  1496 		temp.iBr.iY=rectangle.iBr.iY;
       
  1497 		__ASSERT_DEBUG(temp.iBr.iY==temp.iTl.iY+statusFontHeightInPixels+EGapBelowBottomStatusLine, Panic(EPanicBadHeight));
       
  1498 		graphicsContext.DrawText(textToDisplay, temp, statusFontAscentInPixels, CGraphicsContext::ELeft, EGapLeftOfEachLine);
       
  1499 		graphicsContext.DiscardFont();
       
  1500 		}
       
  1501 	}
       
  1502 
       
  1503 void CTstControl::DrawText(const TParam& aParam, const TLineInfo& aLineInfo, const TCharFormat& aFormat, const TDesC& aText, const TPoint& aTextOrigin, TInt aExtraPixels) const
       
  1504 	{
       
  1505 
       
  1506 /*	if (aFormat.iFontPresentation.iHighlightStyle == TFontPresentation::EFontHighlightFepInlineText)
       
  1507 		{
       
  1508 		//draw the dotted underline
       
  1509 		TInt width = aParam.iDrawRect.Width();
       
  1510 		TPoint second (aTextOrigin.iX + width, aTextOrigin.iY+1);
       
  1511 		aParam.iGc.SetPenStyle(aParam.iGc.EDottedPen);
       
  1512 		aParam.iGc.SetUnderlineStyle(EUnderlineOff);
       
  1513 		aParam.iGc.DrawLine(TPoint(aTextOrigin.iX,aTextOrigin.iY+1),second);
       
  1514 		}
       
  1515 */	MFormCustomDraw::DrawText(aParam,aLineInfo,aFormat,aText,aTextOrigin,aExtraPixels);
       
  1516 	}
       
  1517 
       
  1518 void CTstControl::GetFormatOfFepInlineText(TCharFormat& aFormat, TInt& aNumberOfCharactersWithSameFormat, TInt aPositionOfCharacter) const
       
  1519 	{
       
  1520 	const TInt lengthOfSelection=iSelectedCompositionText.Length();
       
  1521 	const TInt startOfSelectedInlineText=iSelectedCompositionText.LowerPos();
       
  1522 	const TInt endOfSelectedInlineText=iSelectedCompositionText.HigherPos();
       
  1523 	const MCoeFepAwareTextEditor& fepAwareTextEditor=*iInputCapabilities.FepAwareTextEditor();
       
  1524 	TCursorSelection cursorSelection;
       
  1525 	fepAwareTextEditor.GetCursorSelectionForFep(cursorSelection);
       
  1526 	TCharFormat formatBeforeInlineText;
       
  1527 	GetFormatAtDocumentPosition(formatBeforeInlineText, cursorSelection.LowerPos()-1, fepAwareTextEditor);
       
  1528 	TCharFormat formatAfterInlineText;
       
  1529 	GetFormatAtDocumentPosition(formatAfterInlineText, cursorSelection.HigherPos()+1, fepAwareTextEditor);
       
  1530 	aFormat=formatBeforeInlineText;
       
  1531 	aFormat.iFontPresentation.iTextColor.SetBlue(0);
       
  1532 	//aFormat.iFontPresentation.iHighlightStyle=TFontPresentation::EFontHighlightFepInlineText;
       
  1533 	if ((lengthOfSelection>0) && (aPositionOfCharacter>=startOfSelectedInlineText) && (aPositionOfCharacter<endOfSelectedInlineText))
       
  1534 		{ 
       
  1535 		aFormat.iFontPresentation.iTextColor.SetRed(0);
       
  1536 		aFormat.iFontPresentation.iTextColor.SetGreen(255);
       
  1537 		}
       
  1538 	else
       
  1539 		{
       
  1540 		aFormat.iFontPresentation.iTextColor.SetRed(255);
       
  1541 		aFormat.iFontPresentation.iTextColor.SetGreen(0);
       
  1542 		}
       
  1543 	if ((formatBeforeInlineText.iFontPresentation.iUnderline!=EUnderlineOn) && (formatAfterInlineText.iFontPresentation.iUnderline!=EUnderlineOn))
       
  1544 		{
       
  1545 		aFormat.iFontPresentation.iUnderline=EUnderlineOn;
       
  1546 		}
       
  1547 	else if ((formatBeforeInlineText.iFontPresentation.iUnderline!=EUnderlineOff) && (formatAfterInlineText.iFontPresentation.iUnderline!=EUnderlineOff))
       
  1548 		{
       
  1549 		aFormat.iFontPresentation.iUnderline=EUnderlineOff;
       
  1550 		}
       
  1551 	else
       
  1552 		{
       
  1553 		aFormat.iFontSpec.iFontStyle.SetPrintPosition(EPrintPosSuperscript);
       
  1554 		}
       
  1555 	const TInt endOfRunOfCharactersOfSameFormat=((lengthOfSelection==0) || (aPositionOfCharacter>=endOfSelectedInlineText))?
       
  1556 													iBuffer.Length():
       
  1557 												(aPositionOfCharacter>=startOfSelectedInlineText)?
       
  1558 													endOfSelectedInlineText:
       
  1559 													startOfSelectedInlineText;
       
  1560 	aNumberOfCharactersWithSameFormat=endOfRunOfCharactersOfSameFormat-aPositionOfCharacter;
       
  1561 	}
       
  1562 
       
  1563 void CTstControl::HandlePointerEventInInlineTextL(TPointerEvent::TType aType, TUint, TInt aPositionInInlineText)
       
  1564 	{
       
  1565 	MCoeFepAwareTextEditor* const fepAwareTextEditor=iInputCapabilities.FepAwareTextEditor();
       
  1566 	__ASSERT_DEBUG(fepAwareTextEditor!=NULL, Panic(EPanicNoFepAwareTextEditorAlthoughCurrentlyInlineEditing));
       
  1567 	const TCursorSelection oldSelectedCompositionText=iSelectedCompositionText;
       
  1568 	switch (aType)
       
  1569 		{
       
  1570 	case TPointerEvent::EButton1Down:
       
  1571 		iSelectedCompositionText.iAnchorPos=aPositionInInlineText;
       
  1572 		// fall through
       
  1573 	case TPointerEvent::EDrag:
       
  1574 		iSelectedCompositionText.iCursorPos=aPositionInInlineText;
       
  1575 		break;
       
  1576 #if defined(__GCC32__)
       
  1577 	default:
       
  1578 		break;
       
  1579 #endif
       
  1580 		}
       
  1581 	if ((iSelectedCompositionText.iCursorPos!=oldSelectedCompositionText.iCursorPos) || (iSelectedCompositionText.iAnchorPos!=oldSelectedCompositionText.iAnchorPos))
       
  1582 		{
       
  1583 		fepAwareTextEditor->UpdateFepInlineTextL(iBuffer, iSelectedCompositionText.iCursorPos);
       
  1584 		}
       
  1585 	}
       
  1586 
       
  1587 void CTstControl::ExecuteFunctionL()
       
  1588 	{
       
  1589 	
       
  1590 	InsertCompositionCharacterAndDrawNowL(iCharacterCode);
       
  1591 	}
       
  1592 
       
  1593 // CTstFep
       
  1594 
       
  1595 CTstFep::CTstFep(CCoeEnv& aConeEnvironment)
       
  1596 	:CCoeFep(aConeEnvironment)
       
  1597 	{
       
  1598 	}
       
  1599 
       
  1600 void CTstFep::ConstructL(const CCoeFepParameters& aFepParameters)
       
  1601 	{
       
  1602 	BaseConstructL(aFepParameters);
       
  1603 	iControl=CTstControl::NewL(*this);
       
  1604 	ReadAllAttributesL();
       
  1605 	iControl->ActivateL();
       
  1606 	}
       
  1607 
       
  1608 CTstFep::~CTstFep()
       
  1609 	{
       
  1610 	delete iControl;
       
  1611 	}
       
  1612 
       
  1613 void CTstFep::CancelTransaction()
       
  1614 	{
       
  1615 	iControl->CancelTransaction();
       
  1616 	}
       
  1617 
       
  1618 void CTstFep::IsOnHasChangedState()
       
  1619 	{
       
  1620 	iControl->IsOnHasChangedState();
       
  1621 	}
       
  1622 
       
  1623 void CTstFep::OfferKeyEventL(TEventResponse& aEventResponse, const TKeyEvent& aKeyEvent, TEventCode aEventCode)
       
  1624 	{
       
  1625 	// this function must correctly set aEventResponse *before* calling anything that can leave
       
  1626 	aEventResponse=CCoeFep::EEventWasConsumed; // this assumes that CTstControl::OfferKeyEventL will not leave if it returns EKeyWasNotConsumed
       
  1627 	
       
  1628 	switch (iControl->OfferKeyEventL(aKeyEvent, aEventCode))
       
  1629 		{
       
  1630 	case EKeyWasNotConsumed:
       
  1631 		aEventResponse=EEventWasNotConsumed;
       
  1632 		break;
       
  1633 	case EKeyWasConsumed:
       
  1634 		aEventResponse=EEventWasConsumed;
       
  1635 		break;
       
  1636 #if defined(_DEBUG)
       
  1637 	default:
       
  1638 		Panic(EPanicBadKeyResponse);
       
  1639 		break;
       
  1640 #endif
       
  1641 		}
       
  1642 	}
       
  1643 
       
  1644 void CTstFep::OfferPointerEventL(TEventResponse& aEventResponse, const TPointerEvent& aPointerEvent, const CCoeControl* aWindowOwningControl)
       
  1645 	{
       
  1646 	iControl->OfferPointerEventL(aEventResponse, aPointerEvent, aWindowOwningControl);
       
  1647 	}
       
  1648 
       
  1649 void CTstFep::OfferPointerBufferReadyEventL(TEventResponse& aEventResponse, const CCoeControl*)
       
  1650 	{
       
  1651 	aEventResponse=EEventWasNotConsumed;
       
  1652 	}
       
  1653 
       
  1654 TInt CTstFep::NumberOfAttributes() const
       
  1655 	{
       
  1656 	return CTstControl::NumberOfAttributes();
       
  1657 	}
       
  1658 
       
  1659 TUid CTstFep::AttributeAtIndex(TInt aIndex) const
       
  1660 	{
       
  1661 	return CTstControl::AttributeAtIndex(aIndex);
       
  1662 	}
       
  1663 
       
  1664 void CTstFep::WriteAttributeDataToStreamL(TUid aAttributeUid, RWriteStream& aStream) const
       
  1665 	{
       
  1666 	iControl->WriteAttributeDataToStreamL(aAttributeUid, aStream);
       
  1667 	}
       
  1668 
       
  1669 void CTstFep::ReadAttributeDataFromStreamL(TUid aAttributeUid, RReadStream& aStream)
       
  1670 	{
       
  1671 	iControl->ReadAttributeDataFromStreamL(aAttributeUid, aStream);
       
  1672 	}
       
  1673 
       
  1674 void CTstFep::HandleGainingForeground()
       
  1675 	{
       
  1676 	iControl->HandleGainingForeground();
       
  1677 	}
       
  1678 
       
  1679 void CTstFep::HandleLosingForeground()
       
  1680 	{
       
  1681 	iControl->HandleLosingForeground();
       
  1682 	}
       
  1683 
       
  1684 void CTstFep::HandleChangeInFocus()
       
  1685 	{
       
  1686 	iControl->HandleChangeInFocus();
       
  1687 	}
       
  1688 
       
  1689 void CTstFep::HandleDestructionOfFocusedItem()
       
  1690 	{
       
  1691 	iControl->HandleDestructionOfFocusedItem();
       
  1692 	}
       
  1693 
       
  1694 // TTstResourceFileId
       
  1695 
       
  1696 #pragma warning(disable: 4355) // "'this' : used in base member initializer list"
       
  1697 
       
  1698 TTstResourceFileId::TTstResourceFileId(CCoeEnv& aConeEnvironment, TInt aResourceFileId)
       
  1699 	:TCleanupItem(UnloadResourceFile, this),
       
  1700 	 iConeEnvironment(aConeEnvironment),
       
  1701 	 iResourceFileId(aResourceFileId)
       
  1702 	{
       
  1703 	}
       
  1704 
       
  1705 #pragma warning(default: 4355)
       
  1706 
       
  1707 void TTstResourceFileId::UnloadResourceFile(TAny* aThis)
       
  1708 	{
       
  1709 	TTstResourceFileId& resourceFileId=*STATIC_CAST(TTstResourceFileId*, aThis);
       
  1710 	resourceFileId.iConeEnvironment.DeleteResourceFile(resourceFileId.iResourceFileId);
       
  1711 	}
       
  1712 
       
  1713 // CTstSettingsDialog
       
  1714 
       
  1715 CTstSettingsDialog::CTstSettingsDialog()
       
  1716 	:iInlineEditingEnabled(ETrue),
       
  1717 	 iInputMethod(0)
       
  1718 	{
       
  1719 	}
       
  1720 
       
  1721 TBool CTstSettingsDialog::OkToExitL(TInt aButtonId)
       
  1722 	{
       
  1723 	__ASSERT_ALWAYS(aButtonId==EEikBidOk, Panic(EPanicUnexpectedButtonId));
       
  1724 	switch (STATIC_CAST(CEikCheckBox*, Control(EControlIdInlineEditingEnabled))->State())
       
  1725 		{
       
  1726 	case CEikButtonBase::EClear:
       
  1727 		iInlineEditingEnabled=EFalse;
       
  1728 		break;
       
  1729 	case CEikButtonBase::ESet:
       
  1730 		iInlineEditingEnabled=ETrue;
       
  1731 		break;
       
  1732 	case CEikButtonBase::EIndeterminate:
       
  1733 #if defined(_DEBUG)
       
  1734 	default:
       
  1735 		Panic(EPanicBadCheckBoxState);
       
  1736 #endif
       
  1737 		break;
       
  1738 		}
       
  1739 	iInputMethod=STATIC_CAST(CEikChoiceListBase*, Control(EControlIdInputMethod))->CurrentItem();
       
  1740 	TFixedArray<TUid, 2> attributeUids;
       
  1741 	__ASSERT_DEBUG(NumberOfAttributes()==2, Panic(EPanicBadNumberOfAttributes));
       
  1742 	attributeUids[0].iUid=AttributeAtIndex(0).iUid;
       
  1743 	attributeUids[1].iUid=AttributeAtIndex(1).iUid;
       
  1744 	WriteAttributeDataAndBroadcastL(*iCoeEnv, attributeUids.Array());
       
  1745 	return ETrue;
       
  1746 	}
       
  1747 
       
  1748 void CTstSettingsDialog::PreLayoutDynInitL()
       
  1749 	{
       
  1750 	ReadAllAttributesL(*iCoeEnv);
       
  1751 	STATIC_CAST(CEikCheckBox*, Control(EControlIdInlineEditingEnabled))->SetState(iInlineEditingEnabled? CEikButtonBase::ESet: CEikButtonBase::EClear);
       
  1752 	STATIC_CAST(CEikChoiceListBase*, Control(EControlIdInputMethod))->SetCurrentItem(iInputMethod);
       
  1753 	}
       
  1754 
       
  1755 TInt CTstSettingsDialog::NumberOfAttributes() const
       
  1756 	{
       
  1757 	return CTstControl::NumberOfAttributes();
       
  1758 	}
       
  1759 
       
  1760 TUid CTstSettingsDialog::AttributeAtIndex(TInt aIndex) const
       
  1761 	{
       
  1762 	return CTstControl::AttributeAtIndex(aIndex);
       
  1763 	}
       
  1764 
       
  1765 void CTstSettingsDialog::WriteAttributeDataToStreamL(TUid aAttributeUid, RWriteStream& aStream) const
       
  1766 	{
       
  1767 	CTstControl::WriteAttributeDataToStreamL(aAttributeUid, aStream, iInlineEditingEnabled, iInputMethod);
       
  1768 	}
       
  1769 
       
  1770 void CTstSettingsDialog::ReadAttributeDataFromStreamL(TUid aAttributeUid, RReadStream& aStream)
       
  1771 	{
       
  1772 	CTstControl::ReadAttributeDataFromStreamL(aAttributeUid, aStream, iInlineEditingEnabled, iInputMethod);
       
  1773 	}
       
  1774