--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/fep/frontendprocessor/test/feps/TFEP1.CPP Tue Feb 02 01:02:04 2010 +0200
@@ -0,0 +1,2039 @@
+// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include <e32std.h>
+#include <e32base.h>
+#include <e32keys.h>
+#include <s32strm.h>
+#include <gdi.h>
+#include <txtfrmat.h>
+#include <fbs.h>
+#include <bitstd.h>
+#include <bitdev.h>
+#include <w32std.h>
+#include <frmtlay.h>
+#include <coemain.h>
+#include <coeaui.h>
+#include <coecntrl.h>
+#include <coefepff.h>
+#include <fepbase.h>
+#include <fepitfr.h>
+#include <techview/eikon.hrh>
+#include <techview/eikdialg.h>
+#include <techview/eikchkbx.h>
+#include <techview/eikbutb.h>
+#include <techview/eikchlst.h>
+
+#include "tfep1.hrh"
+#include "TFEP1.H"
+#include "TFEP1COM.H"
+
+// constants
+
+enum TPanic
+ {
+ EPanicBackupAlreadyExists=1,
+ EPanicBadIndex1,
+ EPanicBadIndex2,
+ EPanicNotExpectedToBeSimulatingKeyEvent1,
+ EPanicNotExpectedToBeSimulatingKeyEvent2,
+ EPanicBadAttributeUid1,
+ EPanicBadAttributeUid2,
+ EPanicBadAttributeUid3,
+ EPanicBadAttributeUid4,
+ EPanicBadInputMethod1,
+ EPanicBadInputMethod2,
+ EPanicBadInputMethod3,
+ EPanicBadInputMethod4,
+ EPanicBadInputMethod5,
+ EPanicBadTextLength1,
+ EPanicBadTextLength2,
+ EPanicBadKeyCode1,
+ EPanicBadKeyCode2,
+ EPanicBadKeyCode3,
+ EPanicBadKeyCode4,
+ EPanicBadCharacterInBuffer,
+ EPanicInconsistentState,
+ EPanicNegativeIndex,
+ EPanicArithmeticConfusion,
+ EPanicBadLengthOfTextBeforeSelection,
+ EPanicSelectionExtendsPastEndOfDocument,
+ EPanicBadLengthOfTextAfterSelection,
+ EPanicBadLengthOfSelection,
+ EPanicBadHeight,
+ EPanicIsAlreadyActive,
+ EPanicNoFepAwareTextEditorAlthoughCurrentlyInlineEditing,
+ EPanicBadKeyResponse,
+ EPanicUnexpectedButtonId,
+ EPanicBadCheckBoxState,
+ EPanicBadNumberOfAttributes
+ };
+
+_LIT(KLitTFEP1, "TFEP1");
+#if defined(_UNICODE)
+const TUint KEllipsisCharacter=0x2026;
+_LIT(KLitCompositionFontTypefaceName, "publicDomainUnicode");
+#else
+const TUint KEllipsisCharacter=0x85;
+_LIT(KLitCompositionFontTypefaceName, "courier");
+#endif
+_LIT(KLitStatusFontTypefaceName, "arial");
+_LIT(KLitNoFocusedFepAwareTextEditor, "No focused FEP-aware text-editor");
+_LIT(KLitNoFocusedFepAwareTextEditorSupportingState, "No focused FEP-aware text-editor supporting state");
+_LIT(KLitNotAvailable, "[not available]");
+//_LIT(KLitTooLong, "[too long]");
+_LIT(KLitQuotationMark, "\"");
+_LIT(KLitTextBeforeSelectionColonSpace, "Text before selection: ");
+_LIT(KLitTextAfterSelectionColonSpace, "Text after selection: ");
+_LIT(KLitSelectionColonSpace, "Selection: ");
+_LIT(KLitInputMethodColonSpace, "Input method: ");
+_LIT(KLitPlain, "plain");
+_LIT(KLitHexadecimalCharacterCode, "hexadecimal character-code");
+_LIT(KLitInlineEditingColonSpace, "Inline editing: ");
+_LIT(KLitEnabled, "enabled");
+_LIT(KLitDisabled, "disabled");
+_LIT(KLitOpeningSquareBracket, "[");
+_LIT(KLitCaptionColonSpace, "Caption: ");
+_LIT(KLitStateColonSpace, "State: ");
+_LIT(KLitInputCapabilitiesColonSpace, "Input-capabilities: ");
+_LIT(KLitNone, "none");
+_LIT(KLitWesternNumericIntegerPositive, "Western numeric integer positive");
+_LIT(KLitWesternNumericIntegerNegative, "Western numeric integer negative");
+_LIT(KLitWesternNumericReal, "Western numeric real");
+_LIT(KLitWesternAlphabetic, "Western alphabetic");
+_LIT(KLitJapaneseHiragana, "Japanese hiragana");
+_LIT(KLitJapaneseKatakanaHalfWidth, "Japanese katakana half-width");
+_LIT(KLitJapaneseKatakanaFullWidth, "Japanese katakana full-width");
+_LIT(KLitDialableCharacters, "dialable characters");
+_LIT(KLitSecretText, "secret text");
+_LIT(KLitAllText, "all text");
+_LIT(KLitNavigation, "navigation");
+_LIT(KLitExtensionsColonSpace, "extensions: ");
+_LIT(KLitPhoneticAlphabet, "phonetic alphabet");
+_LIT(KLitCommaSpace, ", ");
+_LIT(KLitClosingSquareBracket, "]");
+
+LOCAL_D const TText* const KPhoneticAlphabet[]=
+ {
+ _S("Alpha"),
+ _S("Bravo"),
+ _S("Charlie"),
+ _S("Delta"),
+ _S("Echo"),
+ _S("Foxtrot"),
+ _S("Golf"),
+ _S("Hotel"),
+ _S("India"),
+ _S("Juliette"),
+ _S("Kilo"),
+ _S("Lima"),
+ _S("Mike"),
+ _S("November"),
+ _S("Oscar"),
+ _S("Papa"),
+ _S("Quebec"),
+ _S("Romeo"),
+ _S("Sierra"),
+ _S("Tango"),
+ _S("Uniform"),
+ _S("Victor"),
+ _S("Whiskey"),
+ _S("X-Ray"),
+ _S("Yankee"),
+ _S("Zulu")
+ };
+
+// local and global functions
+
+LOCAL_C void Panic(TPanic aPanic)
+ {
+ User::Panic(KLitTFEP1, aPanic);
+ }
+
+GLDEF_C TInt E32Dll(
+ )
+ {
+ return KErrNone;
+ }
+
+// TTstTextBackup
+
+#pragma warning(disable: 4355) // "'this' : used in base member initializer list"
+
+TTstTextBackup::TTstTextBackup(TDes& aText)
+ :iCleanupItem(Cleanup, this),
+ iOriginal(aText),
+ iBackup(NULL)
+ {
+ }
+
+#pragma warning(default: 4355)
+
+void TTstTextBackup::PushOntoCleanupStackL()
+ {
+ __ASSERT_DEBUG(iBackup==NULL, Panic(EPanicBackupAlreadyExists));
+ iBackup=iOriginal.AllocL();
+ CleanupStack::PushL(iCleanupItem);
+ }
+
+void TTstTextBackup::PopOffCleanupStack()
+ {
+ delete iBackup;
+ CleanupStack::Pop();
+ }
+
+void TTstTextBackup::Cleanup(TAny* aTextBackup)
+ {
+ TTstTextBackup* const textBackup=STATIC_CAST(TTstTextBackup*, aTextBackup);
+ textBackup->iOriginal=*textBackup->iBackup;
+ delete textBackup->iBackup;
+ }
+
+// CTstInsertionPoint
+
+CTstInsertionPoint* CTstInsertionPoint::NewL(RWindowBase& aWindow, CCoeEnv& aConeEnvironment)
+ {
+ CTstInsertionPoint* const insertionPoint=new(ELeave) CTstInsertionPoint(aConeEnvironment.WsSession());
+ CleanupStack::PushL(insertionPoint);
+ insertionPoint->ConstructL(aWindow, aConeEnvironment.ScreenDevice()->DisplayMode());
+ CleanupStack::Pop(); // insertionPoint
+ return insertionPoint;
+ }
+
+CTstInsertionPoint::~CTstInsertionPoint()
+ {
+ iSprite.Close();
+ delete iSpriteMember.iBitmap; // must be deleted after iSprite is closed as iSprite has a reference to it
+ // iSpriteMember.iMaskBitmap is not deleted as it is the same as iSpriteMember.iBitmap
+ }
+
+void CTstInsertionPoint::SetPosition(const TPoint& aPosition)
+ {
+ iPosition=aPosition;
+ if (iFlags&EFlagOn)
+ {
+ iSprite.SetPosition(iPosition);
+ }
+ }
+
+void CTstInsertionPoint::SetOn(TBool aOn)
+ {
+ if (!aOn!=!(iFlags&EFlagOn)) // fold non-zero values on both sides before comparing for inequality
+ {
+ DoSetOn(aOn);
+ }
+ }
+
+CTstInsertionPoint::CTstInsertionPoint(RWsSession& aWindowServerSession)
+ :iSprite(aWindowServerSession),
+ iPosition(0, 0),
+ iFlags(0)
+ {
+ iSpriteMember.iBitmap=NULL;
+ iSpriteMember.iMaskBitmap=NULL;
+ }
+
+void CTstInsertionPoint::ConstructL(RWindowBase& aWindow, TDisplayMode aDisplayMode)
+ {
+ iSpriteMember.iBitmap=CreateBitmapL(aDisplayMode);
+ iSpriteMember.iMaskBitmap=iSpriteMember.iBitmap;
+ iSpriteMember.iInvertMask=ETrue;
+ iSpriteMember.iDrawMode=CGraphicsContext::EDrawModePEN;
+ iSpriteMember.iOffset.iX=-(CTstInsertionPoint::EWidth/2);
+ iSpriteMember.iOffset.iY=0;
+ iSpriteMember.iInterval=0;
+ User::LeaveIfError(iSprite.Construct(aWindow, iPosition, 0));
+ User::LeaveIfError(iSprite.AppendMember(iSpriteMember));
+ DoSetOn(EFalse);
+ User::LeaveIfError(iSprite.Activate());
+ }
+
+CFbsBitmap* CTstInsertionPoint::CreateBitmapL(TDisplayMode aDisplayMode)
+ {
+ CFbsBitmap* const bitmap=new(ELeave) CFbsBitmap;
+ CleanupStack::PushL(bitmap);
+ User::LeaveIfError(bitmap->Create(TSize(CTstInsertionPoint::EWidth, CTstInsertionPoint::EHeight), aDisplayMode));
+ CFbsBitmapDevice* const bitmapDevice=CFbsBitmapDevice::NewL(bitmap);
+ CleanupStack::PushL(bitmapDevice);
+ CFbsBitGc* const graphicsContext=CFbsBitGc::NewL();
+ CleanupStack::PushL(graphicsContext);
+ graphicsContext->Activate(bitmapDevice);
+ graphicsContext->SetBrushStyle(CGraphicsContext::ESolidBrush);
+ graphicsContext->SetBrushColor(KRgbWhite);
+ graphicsContext->SetPenStyle(CGraphicsContext::ESolidPen);
+ graphicsContext->SetPenColor(KRgbBlack);
+ graphicsContext->Clear();
+ const TPoint bottomLeft(0, CTstInsertionPoint::EHeight-1);
+ const TPoint bottomRight(CTstInsertionPoint::EWidth-1, CTstInsertionPoint::EHeight-1);
+ const TPoint top(CTstInsertionPoint::EWidth/2, 0);
+ graphicsContext->DrawLine(bottomLeft, bottomRight);
+ graphicsContext->DrawLine(bottomRight, top);
+ graphicsContext->DrawLine(top, bottomLeft);
+ CleanupStack::PopAndDestroy(2); // graphicsContext and bitmapDevice
+ CleanupStack::Pop(); // bitmap
+ return bitmap;
+ }
+
+void CTstInsertionPoint::DoSetOn(TBool aOn)
+ {
+ iSprite.SetPosition(aOn? iPosition: TPoint(-(EWidth*4), -(EHeight*4)));
+ if (aOn)
+ {
+ iFlags|=EFlagOn;
+ }
+ else
+ {
+ iFlags&=~EFlagOn;
+ }
+ }
+
+// TTstArrayOfOneCtrlCharacter
+
+TTstArrayOfOneCtrlCharacter::TTstArrayOfOneCtrlCharacter(TUint aCharacter)
+ :iCharacter(aCharacter)
+ {
+ }
+
+TArray<CCoeFep::MModifiedCharacter> TTstArrayOfOneCtrlCharacter::ArrayOfModifiedCharacters()
+ {
+ return TArray<CCoeFep::MModifiedCharacter>(NumberOfModifiedCharacters, ModifiedCharacter, (const CBase*)this);
+ }
+
+TInt TTstArrayOfOneCtrlCharacter::NumberOfModifiedCharacters(const CBase*)
+ {
+ return 1;
+ }
+
+const TAny* TTstArrayOfOneCtrlCharacter::ModifiedCharacter(const CBase* aThis, TInt aIndex)
+ {
+ __ASSERT_ALWAYS(aIndex==0, Panic(EPanicBadIndex1));
+ return aThis;
+ }
+
+TUint TTstArrayOfOneCtrlCharacter::CharacterCode() const
+ {
+ return iCharacter;
+ }
+
+TUint TTstArrayOfOneCtrlCharacter::ModifierMask() const
+ {
+ return EModifierCtrl|EModifierShift|EModifierLeftShift|EModifierRightShift;
+ }
+
+TUint TTstArrayOfOneCtrlCharacter::ModifierValues() const
+ {
+ return EModifierCtrl;
+ }
+
+// CTstControl
+
+CTstControl* CTstControl::NewL(CTstFep& aFep)
+ {
+ CTstControl* const control=new(ELeave) CTstControl(aFep);
+ CleanupStack::PushL(control);
+ control->ConstructL();
+ CleanupStack::Pop(); // control
+ return control;
+ }
+
+CTstControl::~CTstControl()
+ {
+ if (iFlags&EFlagInsideInlineEditingTransaction)
+ {
+ CancelInlineEdit(*iInputCapabilities.FepAwareTextEditor());
+ }
+ iCoeEnv->ReleaseScreenFont(iCompositionFont);
+ iCoeEnv->ReleaseScreenFont(iStatusFont);
+ STATIC_CAST(CCoeAppUi*, iCoeEnv->AppUi())->RemoveFromStack(this);
+ delete iInsertionPoint;
+ }
+
+void CTstControl::CancelTransaction()
+ {
+ __ASSERT_DEBUG(!iFep.IsSimulatingKeyEvent() || ((~iFlags&EFlagInsideInlineEditingTransaction) && (iBuffer.Length()==0)), Panic(EPanicNotExpectedToBeSimulatingKeyEvent1));
+ TBool needToDraw=EFalse;
+ if (iFlags&EFlagInsideInlineEditingTransaction)
+ {
+ CancelInlineEdit(*iInputCapabilities.FepAwareTextEditor());
+ needToDraw=ETrue;
+ }
+ if (iBuffer.Length()>0)
+ {
+ ResetBuffer();
+ needToDraw=ETrue;
+ }
+ if (needToDraw)
+ {
+ DrawNow();
+ }
+ }
+
+void CTstControl::IsOnHasChangedState()
+ {
+ ChangeSetupAndResetBufferAndDrawNow(NULL);
+ }
+
+void CTstControl::OfferPointerEventL(CCoeFep::TEventResponse& aEventResponse, const TPointerEvent& aPointerEvent, const CCoeControl* aWindowOwningControl)
+ {
+ // this function must correctly set aEventResponse *before* calling anything that can leave
+ if (aWindowOwningControl==this)
+ {
+ aEventResponse=CCoeFep::EEventWasConsumed;
+ HandlePointerEventL(aPointerEvent);
+ }
+ else
+ {
+ aEventResponse=CCoeFep::EEventWasNotConsumed;
+ }
+ }
+
+TInt CTstControl::NumberOfAttributes()
+ {
+ return 2;
+ }
+
+TUid CTstControl::AttributeAtIndex(TInt aIndex)
+ {
+ switch (aIndex)
+ {
+ case 0:
+ return TUid::Uid(ETstInlineEditingEnabledUid);
+ case 1:
+ return TUid::Uid(ETstInputMethodUid);
+#if defined(_DEBUG)
+ default:
+ Panic(EPanicBadIndex2);
+ break;
+#endif
+ }
+ return KNullUid;
+ }
+
+void CTstControl::WriteAttributeDataToStreamL(TUid aAttributeUid, RWriteStream& aStream) const
+ {
+ switch (aAttributeUid.iUid)
+ {
+ case ETstInlineEditingEnabledUid:
+ aStream.WriteUint8L((iFlags&EFlagInlineEditingEnabled)!=0);
+ break;
+ case ETstInputMethodUid:
+ aStream.WriteUint8L(iInputMethod);
+ break;
+#if defined(_DEBUG)
+ default:
+ Panic(EPanicBadAttributeUid1);
+ break;
+#endif
+ }
+ }
+
+void CTstControl::ReadAttributeDataFromStreamL(TUid aAttributeUid, RReadStream& aStream)
+ {
+ switch (aAttributeUid.iUid)
+ {
+ case ETstInlineEditingEnabledUid:
+ ChangeSetupAndResetBufferAndDrawNow(SetFlagInlineEditingEnabled, aStream.ReadUint8L());
+ break;
+ case ETstInputMethodUid:
+ {
+ TInt inputMethod=aStream.ReadUint8L();
+ if ((inputMethod!=EInputMethodPlain) && (inputMethod!=EInputMethodHexadecimalCharacterCode))
+ {
+ User::Leave(KErrCorrupt);
+ }
+ ChangeSetupAndResetBufferAndDrawNow(SetInputMethod, inputMethod);
+ }
+ break;
+#if defined(_DEBUG)
+ default:
+ Panic(EPanicBadAttributeUid2);
+ break;
+#endif
+ }
+ }
+
+void CTstControl::WriteAttributeDataToStreamL(TUid aAttributeUid, RWriteStream& aStream, TBool aInlineEditingEnabled, TInt aInputMethod)
+ {
+ switch (aAttributeUid.iUid)
+ {
+ case ETstInlineEditingEnabledUid:
+ aStream.WriteUint8L(aInlineEditingEnabled!=EFalse);
+ break;
+ case ETstInputMethodUid:
+ aStream.WriteUint8L(aInputMethod);
+ break;
+#if defined(_DEBUG)
+ default:
+ Panic(EPanicBadAttributeUid3);
+ break;
+#endif
+ }
+ }
+
+void CTstControl::ReadAttributeDataFromStreamL(TUid aAttributeUid, RReadStream& aStream, TBool& aInlineEditingEnabled, TInt& aInputMethod)
+ {
+ switch (aAttributeUid.iUid)
+ {
+ case ETstInlineEditingEnabledUid:
+ aInlineEditingEnabled=aStream.ReadUint8L();
+ break;
+ case ETstInputMethodUid:
+ aInputMethod=aStream.ReadUint8L();
+ break;
+#if defined(_DEBUG)
+ default:
+ Panic(EPanicBadAttributeUid4);
+ break;
+#endif
+ }
+ }
+
+void CTstControl::HandleGainingForeground()
+ {
+ DrawableWindow()->MoveToGroup(iCoeEnv->WsSession().GetFocusWindowGroup()); // ignore the error returned
+ ChangeSetupAndResetBufferAndDrawNow(SetForeground, ETrue);
+ }
+
+void CTstControl::HandleLosingForeground()
+ {
+ ChangeSetupAndResetBufferAndDrawNow(SetForeground, EFalse);
+ }
+
+void CTstControl::HandleChangeInFocus()
+ {
+ ChangeSetupAndResetBufferAndDrawNow(SetInputCapabilities, NULL);
+ }
+
+void CTstControl::HandleDestructionOfFocusedItem()
+ {
+ if (!IsBeingDestroyed())
+ {
+ const TCoeInputCapabilities inputCapabilities(STATIC_CAST(const CCoeAppUi*, iCoeEnv->AppUi())->InputCapabilities());
+ if (inputCapabilities.FepAwareTextEditor()==NULL)
+ {
+ 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
+ }
+ ChangeSetupAndResetBufferAndDrawNow(SetInputCapabilities, REINTERPRET_CAST(TInt, &inputCapabilities));
+ }
+ }
+
+CTstControl::CTstControl(CTstFep& aFep)
+ :iFep(aFep),
+ iInputMethod(EInputMethodPlain),
+ iFlags(0),
+ iBuffer(KNullDesC),
+ iSelectedCompositionText(0, 0),
+ iInputCapabilities(TCoeInputCapabilities::ENone),
+ iCompositionFont(NULL),
+ iStatusFont(NULL),
+ iInsertionPoint(NULL),
+ iPositionOnWindowBeingDragged(0, 0)
+ {
+ }
+
+void CTstControl::ConstructL()
+ {
+ CreateWindowL();
+ EnableDragEvents();
+ ClaimPointerGrab();
+ SetNonFocusing();
+ RDrawableWindow& window=*DrawableWindow();
+ window.SetOrdinalPosition(0, ECoeWinPriorityFep);
+ window.SetShadowHeight(3);
+ TFontSpec compositionFontSpec(KLitCompositionFontTypefaceName, 200);
+ compositionFontSpec.iTypeface.SetIsProportional(EFalse);
+ iCompositionFont=iCoeEnv->CreateScreenFontL(compositionFontSpec);
+ iStatusFont=iCoeEnv->CreateScreenFontL(TFontSpec(KLitStatusFontTypefaceName, 120));
+ iInsertionPoint=CTstInsertionPoint::NewL(window, *iCoeEnv);
+ SetPositionOfInsertionPointInBuffer(0);
+ const TInt statusFontHeightInPixels=iStatusFont->HeightInPixels();
+ const TSize size(320, 1+EGapAboveCompositionLine+iCompositionFont->HeightInPixels()+EGapBelowCompositionLine+EGapAboveTopStatusLine+(4*(statusFontHeightInPixels+EGapBetweenEachStatusLine))+statusFontHeightInPixels+EGapBelowBottomStatusLine+1);
+ const TSize screenSize(iCoeEnv->ScreenDevice()->SizeInPixels());
+ SetExtent(TPoint(screenSize.iWidth-(size.iWidth+10), screenSize.iHeight-(size.iHeight+10)), size);
+ STATIC_CAST(CCoeAppUi*, iCoeEnv->AppUi())->AddToStackL(this, ECoeStackPriorityFep, ECoeStackFlagRefusesFocus|ECoeStackFlagSharable);
+ ChangeSetupAndResetBufferAndDrawNow(SetForeground, iCoeEnv->RootWin().Identifier()==iCoeEnv->WsSession().GetFocusWindowGroup());
+ ChangeSetupAndResetBufferAndDrawNow(SetFocus, EFalse);
+ ChangeSetupAndResetBufferAndDrawNow(SetFlagInlineEditingEnabled, ETrue);
+ ChangeSetupAndResetBufferAndDrawNow(SetInputMethod, EInputMethodPlain);
+ ChangeSetupAndResetBufferAndDrawNow(SetInputCapabilities, NULL);
+ }
+
+void CTstControl::SetForeground(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter)
+ {
+ SetFlag(aControl, aChangeWasMade, aParameter, EFlagForeground);
+ }
+
+void CTstControl::SetFocus(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter)
+ {
+ aChangeWasMade=EFalse;
+ if (!aParameter!=!aControl.IsFocused()) // fold non-zero values on both sides before comparing for inequality
+ {
+ CCoeAppUi& appUi=*STATIC_CAST(CCoeAppUi*, aControl.iCoeEnv->AppUi());
+ appUi.UpdateStackedControlFlags(&aControl, (aParameter? 0: ECoeStackFlagRefusesFocus), ECoeStackFlagRefusesFocus);
+ appUi.HandleStackChanged();
+ aChangeWasMade=ETrue;
+ TBool notUsed;
+ SetInputCapabilities(aControl, notUsed, NULL);
+ }
+ }
+
+void CTstControl::SetFlagInlineEditingEnabled(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter)
+ {
+ SetFlag(aControl, aChangeWasMade, aParameter, EFlagInlineEditingEnabled);
+ }
+
+void CTstControl::SetInputMethod(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter)
+ {
+ __ASSERT_DEBUG((aParameter==EInputMethodPlain) || (aParameter==EInputMethodHexadecimalCharacterCode), Panic(EPanicBadInputMethod1));
+ aChangeWasMade=EFalse;
+ if (aControl.iInputMethod!=aParameter)
+ {
+ aControl.iInputMethod=aParameter;
+ aChangeWasMade=ETrue;
+ }
+ }
+
+void CTstControl::SetInputCapabilities(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter)
+ {
+ aChangeWasMade=EFalse;
+ TCoeInputCapabilities inputCapabilities(TCoeInputCapabilities::ENone);
+ if (!aControl.IsFocused())
+ {
+ inputCapabilities=(aParameter!=NULL)? *REINTERPRET_CAST(const TCoeInputCapabilities*, aParameter): STATIC_CAST(const CCoeAppUi*, aControl.iCoeEnv->AppUi())->InputCapabilities();
+ }
+ if (aControl.iInputCapabilities!=inputCapabilities)
+ {
+ aControl.iInputCapabilities=inputCapabilities;
+ aChangeWasMade=ETrue;
+ }
+ }
+
+void CTstControl::SetFlag(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter, TUint aFlag)
+ {
+ aChangeWasMade=EFalse;
+ if (!aParameter!=!(aControl.iFlags&aFlag)) // fold non-zero values on both sides before comparing for inequality
+ {
+ aControl.iFlags^=aFlag;
+ aChangeWasMade=ETrue;
+ }
+ }
+
+void CTstControl::ChangeSetupAndResetBufferAndDrawNow(FChangeFunction aChangeFunction, TInt aParameter)
+ {
+ __ASSERT_DEBUG(!iFep.IsSimulatingKeyEvent() || ((~iFlags&EFlagInsideInlineEditingTransaction) && (iBuffer.Length()==0)), Panic(EPanicNotExpectedToBeSimulatingKeyEvent2));
+ TBool needToDraw=EFalse;
+ if (iFlags&EFlagInsideInlineEditingTransaction)
+ {
+ CancelInlineEdit(*iInputCapabilities.FepAwareTextEditor());
+ needToDraw=ETrue;
+ }
+ if (aChangeFunction!=NULL)
+ {
+ TBool changeWasMade;
+ (*aChangeFunction)(*this, changeWasMade, aParameter);
+ if (changeWasMade)
+ {
+ needToDraw=ETrue;
+ }
+ }
+ if (iBuffer.Length()>0)
+ {
+ ResetBuffer();
+ needToDraw=ETrue;
+ }
+ 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
+ iInsertionPoint->SetOn(!IsFocused() && !potentiallyInlineEditing);
+ if (!potentiallyInlineEditing!=!(iFlags&EFlagHasNoCompositionWindow)) // fold non-zero values on both sides before comparing for inequality
+ {
+ const TInt heightOfCompositionWindow=EGapAboveCompositionLine+iCompositionFont->HeightInPixels()+EGapBelowCompositionLine;
+ TInt windowAdjustmentY;
+ if (potentiallyInlineEditing)
+ {
+ windowAdjustmentY=heightOfCompositionWindow;
+ iFlags|=EFlagHasNoCompositionWindow;
+ }
+ else
+ {
+ windowAdjustmentY=-heightOfCompositionWindow;
+ iFlags&=~EFlagHasNoCompositionWindow;
+ }
+ 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)
+ rectangle.iTl.iY+=windowAdjustmentY;
+ SetRect(rectangle);
+ needToDraw=ETrue;
+ }
+ const TBool shouldBeVisible=(iFep.IsOn() && (iFlags&EFlagForeground));
+ if (!IsVisible()!=!shouldBeVisible) // fold non-zero values on both sides before comparing for inequality
+ {
+ MakeVisible(shouldBeVisible);
+ needToDraw=EFalse;
+ }
+ if (needToDraw)
+ {
+ DrawNow();
+ }
+ }
+
+void CTstControl::InsertCompositionCharacterAndDrawNowL(TUint aCharacterCode)
+ {
+ const TInt positionOfNewText=iSelectedCompositionText.LowerPos();
+ if (positionOfNewText<EMaximumLengthOfBuffer)
+ {
+ TTstTextBackup textBackup=iBuffer;
+ textBackup.PushOntoCleanupStackL();
+ const TCoeInputCapabilities::MCoeFepSpecificExtensions* fepSpecificInputCapabilityExtensions=iInputCapabilities.FepSpecificExtensions(TUid::Uid(KTfep1Uid));
+ const TUint upperCaseCharacterCode=User::UpperCase(aCharacterCode);
+ TPtrC textToInsert;
+ TBuf<1> buffer;
+ TInt newPositionOfInsertionPointInBuffer=positionOfNewText;
+ if ((iInputMethod==EInputMethodPlain) && (fepSpecificInputCapabilityExtensions!=NULL) && fepSpecificInputCapabilityExtensions->SupportsPhoneticAlphabet() && (upperCaseCharacterCode>='A') && (upperCaseCharacterCode<='Z'))
+ {
+ textToInsert.Set(TPtrC(KPhoneticAlphabet[upperCaseCharacterCode-'A']));
+ const TInt lengthOfRoomForTextToInsert=EMaximumLengthOfBuffer-positionOfNewText;
+ if (textToInsert.Length()>lengthOfRoomForTextToInsert)
+ {
+ textToInsert.Set(textToInsert.Left(lengthOfRoomForTextToInsert));
+ }
+ newPositionOfInsertionPointInBuffer+=textToInsert.Length();
+ }
+ else
+ {
+ buffer.Append(aCharacterCode);
+ textToInsert.Set(buffer);
+ ++newPositionOfInsertionPointInBuffer;
+ }
+ iBuffer.Delete(positionOfNewText, iSelectedCompositionText.Length());
+ const TInt lengthToDeleteToMakeRoom=textToInsert.Length()-(EMaximumLengthOfBuffer-iBuffer.Length());
+ if (lengthToDeleteToMakeRoom>0)
+ {
+ iBuffer.Delete(iBuffer.Length()-lengthToDeleteToMakeRoom, lengthToDeleteToMakeRoom);
+ }
+ iBuffer.Insert(positionOfNewText, textToInsert);
+ __ASSERT_DEBUG((iInputMethod==EInputMethodPlain) || (iInputMethod==EInputMethodHexadecimalCharacterCode), Panic(EPanicBadInputMethod4));
+ if (iInputMethod==EInputMethodHexadecimalCharacterCode)
+ {
+ if (newPositionOfInsertionPointInBuffer>=ENumberOfHexadecimalDigitsPerCharacterCode)
+ {
+ TUint characterCode=0;
+ for (TInt i=ENumberOfHexadecimalDigitsPerCharacterCode; ; --i)
+ {
+ if (i<=0)
+ {
+ const TInt positionToInsertCharacterCode=newPositionOfInsertionPointInBuffer-ENumberOfHexadecimalDigitsPerCharacterCode;
+ iBuffer.Delete(positionToInsertCharacterCode, ENumberOfHexadecimalDigitsPerCharacterCode-1);
+ iBuffer[positionToInsertCharacterCode]=(TText)characterCode;
+ newPositionOfInsertionPointInBuffer-=ENumberOfHexadecimalDigitsPerCharacterCode-1;
+ break;
+ }
+ const TCharUC hexadecimalDigit=iBuffer[newPositionOfInsertionPointInBuffer-i];
+ characterCode*=16;
+ if ((hexadecimalDigit>='0') && (hexadecimalDigit<='9'))
+ {
+ characterCode+=hexadecimalDigit-'0';
+ }
+ else if ((hexadecimalDigit>='A') && (hexadecimalDigit<='F'))
+ {
+ characterCode+=(hexadecimalDigit-'A')+10;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ }
+ SetPositionOfInsertionPointInBuffer(newPositionOfInsertionPointInBuffer);
+ MCoeFepAwareTextEditor* const fepAwareTextEditor=iInputCapabilities.FepAwareTextEditor();
+ if ((fepAwareTextEditor==NULL) || !(iFlags&EFlagInlineEditingEnabled))
+ {
+ DrawNow();
+ }
+ else
+ {
+ SetInlineTextL(*fepAwareTextEditor);
+ }
+ textBackup.PopOffCleanupStack();
+ }
+ } // positionOfNewText newPositionOfInsertionPointInBuffer iCursorPos
+
+void CTstControl::SetInlineTextL(MCoeFepAwareTextEditor& aFepAwareTextEditor)
+ {
+ if (iFlags&EFlagInsideInlineEditingTransaction)
+ {
+ aFepAwareTextEditor.UpdateFepInlineTextL(iBuffer, iSelectedCompositionText.iCursorPos);
+ }
+ else
+ {
+ aFepAwareTextEditor.StartFepInlineEditL(iBuffer, iSelectedCompositionText.iCursorPos, ETrue, this, *this, *this);
+ iFlags|=EFlagInsideInlineEditingTransaction;
+ }
+ }
+
+void CTstControl::CancelInlineEdit(MCoeFepAwareTextEditor& aFepAwareTextEditor)
+ {
+ aFepAwareTextEditor.CancelFepInlineEdit();
+ iFlags&=~EFlagInsideInlineEditingTransaction;
+ }
+
+void CTstControl::CommitInlineEditL(MCoeFepAwareTextEditor& aFepAwareTextEditor)
+ {
+ aFepAwareTextEditor.CommitFepInlineEditL(*iCoeEnv);
+ iFlags&=~EFlagInsideInlineEditingTransaction;
+ }
+
+void CTstControl::ResetBuffer()
+ {
+ SetPositionOfInsertionPointInBuffer(0);
+ iBuffer.SetLength(0);
+ }
+
+void CTstControl::SetPositionOfInsertionPointInBuffer(TInt aPositionOfInsertionPointInBuffer)
+ {
+ SetPositionOfInsertionPointInBuffer(aPositionOfInsertionPointInBuffer, aPositionOfInsertionPointInBuffer);
+ }
+
+void CTstControl::SetPositionOfInsertionPointInBuffer(TInt aPositionOfInsertionPointInBuffer, TInt aPositionOfAnchorInBuffer)
+ {
+ iSelectedCompositionText.iCursorPos=aPositionOfInsertionPointInBuffer;
+ iSelectedCompositionText.iAnchorPos=aPositionOfAnchorInBuffer;
+ iInsertionPoint->SetPosition(PositionOfInsertionPointOnWindow());
+ }
+
+TPoint CTstControl::PositionOfInsertionPointOnWindow() const
+ {
+ return TPoint(1+EGapLeftOfEachLine+iCompositionFont->TextWidthInPixels(iBuffer.Left(iSelectedCompositionText.iCursorPos)), 1+EGapAboveCompositionLine+iCompositionFont->HeightInPixels());
+ }
+
+TInt CTstControl::PositionInBuffer(TInt aX) const
+ {
+ const TInt lengthOfBuffer=iBuffer.Length();
+ TInt previousX=0; // dummy initialization to prevent compiler warning "local variable 'previousX' may be used without having been initialized"
+ for (TInt i=0; ; ++i)
+ {
+ if (i>lengthOfBuffer)
+ {
+ return lengthOfBuffer;
+ }
+ const TInt x=1+EGapLeftOfEachLine+iCompositionFont->TextWidthInPixels(iBuffer.Left(i));
+ if (x>aX)
+ {
+ __ASSERT_DEBUG(i>=0, Panic(EPanicNegativeIndex));
+ if (i<=0)
+ {
+ return 0;
+ }
+ if (aX-previousX<x-aX)
+ {
+ return i-1;
+ }
+ return i;
+ }
+ previousX=x;
+ }
+ }
+
+TBool CTstControl::IsLegalNonDigitForRealNumber(const TCharUC& aKeyCodeInUpperCase) const
+ {
+ const TInt startOfSelectedText=iSelectedCompositionText.LowerPos();
+ const TInt endOfSelectedText=iSelectedCompositionText.HigherPos();
+ TInt positionOfExistingDecimalPoint=iBuffer.Locate('.');
+ if ((positionOfExistingDecimalPoint>=startOfSelectedText) && (positionOfExistingDecimalPoint<endOfSelectedText))
+ {
+ positionOfExistingDecimalPoint=KErrNotFound;
+ }
+ TInt positionOfExistingE=iBuffer.Locate('E');
+ if ((positionOfExistingE>=startOfSelectedText) && (positionOfExistingE<endOfSelectedText))
+ {
+ positionOfExistingE=KErrNotFound;
+ }
+ if (aKeyCodeInUpperCase=='.')
+ {
+ return (positionOfExistingDecimalPoint==KErrNotFound) && ((positionOfExistingE==KErrNotFound) || (positionOfExistingE>=endOfSelectedText));
+ }
+ if (aKeyCodeInUpperCase=='E')
+ {
+ return (positionOfExistingE==KErrNotFound) && ((positionOfExistingDecimalPoint==KErrNotFound) || (positionOfExistingDecimalPoint<startOfSelectedText));
+ }
+ return EFalse;
+ }
+
+void CTstControl::GetFormatAtDocumentPosition(TCharFormat& aFormat, TInt aDocumentPosition, const MCoeFepAwareTextEditor& aFepAwareTextEditor)
+ {
+ if (aDocumentPosition<0)
+ {
+ aDocumentPosition=0;
+ }
+ const TInt documentLength=aFepAwareTextEditor.DocumentLengthForFep();
+ if (aDocumentPosition>documentLength)
+ {
+ aDocumentPosition=documentLength;
+ }
+ aFepAwareTextEditor.GetFormatForFep(aFormat, aDocumentPosition);
+ }
+
+TInt CTstControl::NumberOfCharactersInBuffer(const CBase* aControl)
+ {
+ return STATIC_CAST(const CTstControl*, aControl)->iBuffer.Length();
+ }
+
+const TAny* CTstControl::CharacterInBuffer(const CBase* aControl, TInt aIndex)
+ {
+ CTstControl* control=STATIC_CAST(CTstControl*, CONST_CAST(CBase*, aControl));
+ control->iCharacterCode=control->iBuffer[aIndex];
+ return &control->iCharacterCode;
+ }
+
+TKeyResponse CTstControl::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aEventCode)
+ {
+ // CTstFep::OfferKeyEventL assumes that this will not leave if it returns EKeyWasNotConsumed
+ FEP_START_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, aEventCode);
+ const TBool isFocused=IsFocused();
+ const TCharUC keyCodeInUpperCase=aKeyEvent.iCode;
+ TInt bufferLength=iBuffer.Length();
+ if ((aKeyEvent.iModifiers&EModifierRightShift) && !isFocused)
+ {
+ if (keyCodeInUpperCase=='W')
+ {
+ if (iFlags&EFlagInsideInlineEditingTransaction)
+ {
+ TBool didIt=EFalse;
+ MCoeFepAwareTextEditor* const fepAwareTextEditor=iInputCapabilities.FepAwareTextEditor();
+ if (fepAwareTextEditor!=NULL)
+ {
+ MCoeFepAwareTextEditor_Extension1* const extension=fepAwareTextEditor->Extension1();
+ if (extension!=NULL)
+ {
+ TTextCursor textCursor;
+ textCursor.iType=TTextCursor::ETypeHollowRectangle;
+ textCursor.iHeight=0; // ignored by CEikEdwin as it checks for iWidth.
+ textCursor.iAscent=0; // ignored by CEikEdwin
+ textCursor.iWidth=5;
+ textCursor.iFlags=TTextCursor::EFlagNoFlash;
+ textCursor.iColor=TRgb(255,0,0);
+ extension->SetCursorType(didIt,textCursor);
+ }
+ }
+ if (!didIt)
+ {
+ User::InfoPrint(_L("Couldn't set the cursor-type"));
+ }
+ }
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
+ }
+ else if (bufferLength==0)
+ {
+ switch (keyCodeInUpperCase)
+ {
+ case 'M':
+ ChangeSetupAndResetBufferAndDrawNow(SetInputMethod, (iInputMethod+1<EInputMethodOnePastTheLast)? iInputMethod+1: 0);
+ iFep.WriteAttributeDataAndBroadcastL(TUid::Uid(ETstInputMethodUid));
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
+
+ case 'F':
+ ChangeSetupAndResetBufferAndDrawNow(SetFocus, ETrue);
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
+ case 'I':
+ ChangeSetupAndResetBufferAndDrawNow(SetFlagInlineEditingEnabled, !(iFlags&EFlagInlineEditingEnabled));
+ iFep.WriteAttributeDataAndBroadcastL(TUid::Uid(ETstInlineEditingEnabledUid));
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
+ case 'X':
+ case 'C':
+ case 'V':
+ {
+ TTstArrayOfOneCtrlCharacter arrayOfOneCtrlCharacter(keyCodeInUpperCase-('A'-1)); // the TTstArrayOfOneCtrlCharacter object cannot be an anonymous (temporary) object as its lifetime must be guaranteed to last until iFep.SimulateKeyEventsL returns
+ iFep.SimulateKeyEventsL(arrayOfOneCtrlCharacter.ArrayOfModifiedCharacters());
+ }
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
+ case 'T':
+ {
+ MCoeFepAwareTextEditor* const fepAwareTextEditor=iInputCapabilities.FepAwareTextEditor();
+ if (fepAwareTextEditor==NULL)
+ {
+ User::InfoPrint(KLitNoFocusedFepAwareTextEditor);
+ }
+ else
+ {
+ MCoeFepAwareTextEditor_Extension1* const extension1=fepAwareTextEditor->Extension1();
+ if (extension1==NULL)
+ {
+ User::InfoPrint(KLitNoFocusedFepAwareTextEditorSupportingState);
+ }
+ else
+ {
+ MCoeFepAwareTextEditor_Extension1::CState* const state=extension1->State(TUid::Uid(KTfep1Uid));
+ if (state!=NULL)
+ {
+ STATIC_CAST(CStateInformation*, state)->IncrementMeaninglessNumber(); // this cast is safe as KTfep1Uid is used to retrieve state
+ }
+ else
+ {
+ CStateInformation* stateInformation=CStateInformation::NewLC(1);
+ extension1->SetStateTransferingOwnershipL(stateInformation, TUid::Uid(KTfep1Uid));
+ CleanupStack::Pop(stateInformation);
+ }
+ DrawNow();
+ }
+ }
+ }
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
+ case 'N':
+ {
+ const MCoeFepAwareTextEditor* const fepAwareTextEditor=iInputCapabilities.FepAwareTextEditor();
+ if (fepAwareTextEditor==NULL)
+ {
+ User::InfoPrint(KLitNotAvailable);
+ }
+ else
+ {
+ TCursorSelection cursorSelection;
+ fepAwareTextEditor->GetCursorSelectionForFep(cursorSelection);
+ TPoint position;
+ TInt height;
+ TInt ascent;
+ fepAwareTextEditor->GetScreenCoordinatesForFepL(position,height,ascent,cursorSelection.LowerPos());
+ position.iY+=height-ascent;
+ const TSize screenSize(iCoeEnv->ScreenDevice()->SizeInPixels());
+ const TInt xMaximum=screenSize.iWidth-iSize.iWidth;
+ if ((position.iX<0) || (xMaximum<0))
+ {
+ position.iX=0;
+ }
+ else if (position.iX>xMaximum)
+ {
+ position.iX=xMaximum;
+ }
+ const TInt yMaximum=screenSize.iHeight-iSize.iHeight;
+ if ((position.iY<0) || (yMaximum<0))
+ {
+ position.iY=0;
+ }
+ else
+ {
+ const TInt yOverlapIfFepIsBelow=position.iY-yMaximum;
+ if (yOverlapIfFepIsBelow>0)
+ {
+ const TInt yPositionIfFepIsAbove=Max(0, position.iY-(height+iSize.iHeight));
+ const TInt yOverlapIfFepIsAbove=(yPositionIfFepIsAbove+iSize.iHeight)-(position.iY-height);
+ if (yOverlapIfFepIsAbove<yOverlapIfFepIsBelow)
+ {
+ position.iY=yPositionIfFepIsAbove;
+ }
+ }
+ }
+ SetPosition(position);
+ }
+ }
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
+ case 'B':
+ case 'A':
+ case 'S':
+ {
+ const MCoeFepAwareTextEditor* const fepAwareTextEditor=iInputCapabilities.FepAwareTextEditor();
+ TBuf<40+EMaximumLengthOfDisplayOfContextInformation> textToDisplay;
+ if (fepAwareTextEditor==NULL)
+ {
+ textToDisplay=KLitNotAvailable;
+ }
+ else
+ {
+ TCursorSelection cursorSelection;
+ fepAwareTextEditor->GetCursorSelectionForFep(cursorSelection);
+ switch (keyCodeInUpperCase)
+ {
+ case 'B':
+ {
+ TInt lengthToRetrieve=EMaximumLengthOfDisplayOfContextInformation+1;
+ TInt documentPositionBeforeSelection=cursorSelection.LowerPos()-lengthToRetrieve;
+ if (documentPositionBeforeSelection<0)
+ {
+ lengthToRetrieve+=documentPositionBeforeSelection; // same as doing "lengthToRetrieve=cursorSelection.LowerPos()", hence the assert below
+ __ASSERT_DEBUG(lengthToRetrieve==cursorSelection.LowerPos(), Panic(EPanicArithmeticConfusion));
+ documentPositionBeforeSelection=0;
+ }
+ fepAwareTextEditor->GetEditorContentForFep(textToDisplay, documentPositionBeforeSelection, lengthToRetrieve);
+ const TInt lengthOfTextBeforeSelection=textToDisplay.Length();
+ if (lengthOfTextBeforeSelection>EMaximumLengthOfDisplayOfContextInformation)
+ {
+ textToDisplay.Delete(0, (lengthOfTextBeforeSelection-EMaximumLengthOfDisplayOfContextInformation)-1);
+ __ASSERT_DEBUG(textToDisplay.Length()==EMaximumLengthOfDisplayOfContextInformation+1, Panic(EPanicBadLengthOfTextBeforeSelection));
+ textToDisplay[0]=KEllipsisCharacter;
+ }
+ }
+ textToDisplay.Insert(0, KLitQuotationMark);
+ textToDisplay.Append(KLitQuotationMark);
+ textToDisplay.Insert(0, KLitTextBeforeSelectionColonSpace);
+ break;
+ case 'A':
+ {
+ const TInt documentLength=fepAwareTextEditor->DocumentLengthForFep();
+ const TInt documentPositionAfterSelection=cursorSelection.HigherPos();
+ if (documentPositionAfterSelection>documentLength)
+ {
+ __ASSERT_DEBUG(documentPositionAfterSelection==documentLength+1, Panic(EPanicSelectionExtendsPastEndOfDocument));
+ }
+ else
+ {
+ fepAwareTextEditor->GetEditorContentForFep(textToDisplay, documentPositionAfterSelection, EMaximumLengthOfDisplayOfContextInformation+1);
+ const TInt lengthOfTextAfterSelection=textToDisplay.Length();
+ if (lengthOfTextAfterSelection>EMaximumLengthOfDisplayOfContextInformation)
+ {
+ textToDisplay.Delete(EMaximumLengthOfDisplayOfContextInformation, (lengthOfTextAfterSelection-EMaximumLengthOfDisplayOfContextInformation)-1);
+ __ASSERT_DEBUG(textToDisplay.Length()==EMaximumLengthOfDisplayOfContextInformation+1, Panic(EPanicBadLengthOfTextAfterSelection));
+ textToDisplay[EMaximumLengthOfDisplayOfContextInformation]=KEllipsisCharacter;
+ }
+ }
+ }
+ textToDisplay.Insert(0, KLitQuotationMark);
+ textToDisplay.Append(KLitQuotationMark);
+ textToDisplay.Insert(0, KLitTextAfterSelectionColonSpace);
+ break;
+ case 'S':
+ fepAwareTextEditor->GetEditorContentForFep(textToDisplay, cursorSelection.LowerPos(), cursorSelection.Length());
+ {
+ const TInt lengthOfSelection=textToDisplay.Length();
+ if (lengthOfSelection>EMaximumLengthOfDisplayOfContextInformation)
+ {
+ textToDisplay.Delete(EMaximumLengthOfDisplayOfContextInformation, (lengthOfSelection-EMaximumLengthOfDisplayOfContextInformation)-1);
+ __ASSERT_DEBUG(textToDisplay.Length()==EMaximumLengthOfDisplayOfContextInformation+1, Panic(EPanicBadLengthOfSelection));
+ textToDisplay[EMaximumLengthOfDisplayOfContextInformation]=KEllipsisCharacter;
+ }
+ }
+ textToDisplay.Insert(0, KLitQuotationMark);
+ textToDisplay.Append(KLitQuotationMark);
+ textToDisplay.Insert(0, KLitSelectionColonSpace);
+ break;
+#if defined(_DEBUG)
+ default:
+ Panic(EPanicBadKeyCode1);
+ break;
+#endif
+ }
+ }
+ User::InfoPrint(textToDisplay);
+ }
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
+ }
+ }
+ }
+ if (iInputCapabilities.IsNone() && !isFocused)
+ {
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasNotConsumed); // returns from this function
+ }
+ switch (keyCodeInUpperCase)
+ {
+ case EKeyEnter:
+ case EKeyEscape:
+ if (isFocused)
+ {
+ ChangeSetupAndResetBufferAndDrawNow(SetFocus, EFalse);
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
+ }
+ if (bufferLength>0)
+ {
+ TBool needToDraw=ETrue;
+ switch (keyCodeInUpperCase)
+ {
+ case EKeyEnter:
+ if (~iFlags&EFlagInsideInlineEditingTransaction)
+ {
+ iFep.SimulateKeyEventsL(TArray<TUint>(NumberOfCharactersInBuffer, CharacterInBuffer, this));
+ }
+ else
+ {
+ CommitInlineEditL(*iInputCapabilities.FepAwareTextEditor());
+ needToDraw=EFalse;
+ }
+ break;
+ case EKeyEscape:
+ if (iFlags&EFlagInsideInlineEditingTransaction)
+ {
+ CancelInlineEdit(*iInputCapabilities.FepAwareTextEditor());
+ needToDraw=EFalse;
+ }
+ break;
+#if defined(_DEBUG)
+ default:
+ Panic(EPanicBadKeyCode2);
+ break;
+#endif
+ }
+ ResetBuffer();
+ if (needToDraw)
+ {
+ DrawNow();
+ }
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
+ }
+ break;
+ case EKeyDelete:
+ case EKeyBackspace:
+ if (!isFocused && (bufferLength>0))
+ {
+ TCursorSelection portionToDelete(iSelectedCompositionText.iCursorPos, iSelectedCompositionText.iAnchorPos);
+ const TBool deleteLeft=((keyCodeInUpperCase==EKeyBackspace) && !(aKeyEvent.iModifiers&EModifierShift));
+ if (portionToDelete.Length()==0)
+ {
+ if (deleteLeft)
+ {
+ if (portionToDelete.iCursorPos>0)
+ {
+ --portionToDelete.iCursorPos;
+ }
+ }
+ else
+ {
+ if (portionToDelete.iCursorPos<bufferLength)
+ {
+ ++portionToDelete.iCursorPos;
+ }
+ }
+ }
+ if (portionToDelete.Length()>0)
+ {
+ TTstTextBackup textBackup=iBuffer;
+ textBackup.PushOntoCleanupStackL();
+ SetPositionOfInsertionPointInBuffer(portionToDelete.LowerPos());
+ iBuffer.Delete(portionToDelete.LowerPos(), portionToDelete.Length());
+ if (~iFlags&EFlagInsideInlineEditingTransaction)
+ {
+ DrawNow();
+ }
+ else
+ {
+ if (bufferLength-1>0)
+ {
+ SetInlineTextL(*iInputCapabilities.FepAwareTextEditor());
+ }
+ else
+ {
+ CancelInlineEdit(*iInputCapabilities.FepAwareTextEditor());
+ }
+ }
+ textBackup.PopOffCleanupStack();
+ }
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
+ }
+ break;
+ case EKeySpace:
+ if (!isFocused && (bufferLength>0))
+ {
+ __ASSERT_DEBUG((iInputMethod==EInputMethodPlain) || (iInputMethod==EInputMethodHexadecimalCharacterCode), Panic(EPanicBadInputMethod2));
+ if ((iInputMethod==EInputMethodPlain) && (iSelectedCompositionText.iCursorPos<bufferLength))
+ {
+ const TInt increment=(aKeyEvent.iModifiers&EModifierShift)? -1: 1;
+ const TCharUC limit=(aKeyEvent.iModifiers&EModifierShift)? 'A': 'Z';
+ const TCharUC characterToAdjust=iBuffer[iSelectedCompositionText.iCursorPos];
+ __ASSERT_DEBUG((characterToAdjust>='A') && (characterToAdjust<='Z'), Panic(EPanicBadCharacterInBuffer));
+ if (characterToAdjust!=limit)
+ {
+ TTstTextBackup textBackup=iBuffer;
+ textBackup.PushOntoCleanupStackL();
+ iBuffer[iSelectedCompositionText.iCursorPos]=(TText)(iBuffer[iSelectedCompositionText.iCursorPos]+increment);
+ if (iFlags&EFlagInsideInlineEditingTransaction)
+ {
+ SetInlineTextL(*iInputCapabilities.FepAwareTextEditor());
+ }
+ else
+ {
+ DrawNow();
+ }
+ textBackup.PopOffCleanupStack();
+ }
+ }
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
+ }
+ break;
+ case EKeyHome:
+ case EKeyEnd:
+ case EKeyPageUp:
+ case EKeyPageDown:
+ case EKeyLeftArrow:
+ case EKeyRightArrow:
+ case EKeyUpArrow:
+ case EKeyDownArrow:
+ if (isFocused)
+ {
+ TPoint offset(0, 0);
+ TInt magnification=10;
+ switch (keyCodeInUpperCase)
+ {
+ case EKeyLeftArrow:
+ offset.iX=-1;
+ break;
+ case EKeyRightArrow:
+ offset.iX=1;
+ break;
+ case EKeyUpArrow:
+ offset.iY=-1;
+ break;
+ case EKeyDownArrow:
+ offset.iY=1;
+ break;
+ case EKeyHome:
+ offset.iX=-iPosition.iX;
+ offset.iY=-iPosition.iY;
+ magnification=1;
+ break;
+ case EKeyEnd:
+ {
+ const TSize screenWidth(iCoeEnv->ScreenDevice()->SizeInPixels());
+ offset.iX=(screenWidth.iWidth-iSize.iWidth)-iPosition.iX;
+ offset.iY=(screenWidth.iHeight-iSize.iHeight)-iPosition.iY;
+ }
+ magnification=1;
+ break;
+ case EKeyPageUp:
+ offset.iY=-iSize.iHeight;
+ magnification=1;
+ break;
+ case EKeyPageDown:
+ offset.iY=iSize.iHeight;
+ magnification=1;
+ break;
+#if defined(_DEBUG)
+ default:
+ Panic(EPanicBadKeyCode3);
+ break;
+#endif
+ }
+ if (aKeyEvent.iModifiers&EModifierCtrl)
+ {
+ offset.iX*=magnification;
+ offset.iY*=magnification;
+ }
+ SetPosition(TPoint(iPosition.iX+offset.iX, iPosition.iY+offset.iY));
+ if (iFlags&EFlagWindowIsBeingDragged)
+ {
+ iPositionOnWindowBeingDragged.iX-=offset.iX;
+ iPositionOnWindowBeingDragged.iY-=offset.iY;
+ }
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
+ }
+ if (bufferLength>0)
+ {
+ TInt newPositionOfInsertionPointInBuffer=iSelectedCompositionText.iCursorPos;
+ switch (keyCodeInUpperCase)
+ {
+ case EKeyLeftArrow:
+ if (newPositionOfInsertionPointInBuffer>0)
+ {
+ --newPositionOfInsertionPointInBuffer;
+ }
+ break;
+ case EKeyRightArrow:
+ if (newPositionOfInsertionPointInBuffer<bufferLength)
+ {
+ ++newPositionOfInsertionPointInBuffer;
+ }
+ break;
+ case EKeyHome:
+ case EKeyPageUp:
+ case EKeyUpArrow:
+ newPositionOfInsertionPointInBuffer=0;
+ break;
+ case EKeyEnd:
+ case EKeyPageDown:
+ case EKeyDownArrow:
+ newPositionOfInsertionPointInBuffer=bufferLength;
+ break;
+#if defined(_DEBUG)
+ default:
+ Panic(EPanicBadKeyCode4);
+ break;
+#endif
+ }
+ if (iSelectedCompositionText.iCursorPos!=newPositionOfInsertionPointInBuffer)
+ {
+ if ((iSelectedCompositionText.Length()>0) && !(aKeyEvent.iModifiers&EModifierShift))
+ {
+ if (newPositionOfInsertionPointInBuffer<iSelectedCompositionText.iCursorPos)
+ {
+ newPositionOfInsertionPointInBuffer=iSelectedCompositionText.LowerPos();
+ }
+ else
+ {
+ newPositionOfInsertionPointInBuffer=iSelectedCompositionText.HigherPos();
+ }
+ }
+ }
+ const TInt newPositionOfAnchorInBuffer=(aKeyEvent.iModifiers&EModifierShift)? iSelectedCompositionText.iAnchorPos: newPositionOfInsertionPointInBuffer;
+ if ((iSelectedCompositionText.iCursorPos!=newPositionOfInsertionPointInBuffer) || (iSelectedCompositionText.iAnchorPos!=newPositionOfAnchorInBuffer))
+ {
+ const TBool needToDraw=((iSelectedCompositionText.Length()>0) || (aKeyEvent.iModifiers&EModifierShift)); // don't need to draw if there is no selected text as a result of this event, or if there previously was no selected text before this event
+ SetPositionOfInsertionPointInBuffer(newPositionOfInsertionPointInBuffer, newPositionOfAnchorInBuffer);
+ if (iFlags&EFlagInsideInlineEditingTransaction)
+ {
+ SetInlineTextL(*iInputCapabilities.FepAwareTextEditor());
+ }
+ else if (needToDraw)
+ {
+ DrawNow();
+ }
+ }
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
+ }
+ break;
+ default:
+ if (isFocused)
+ {
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
+ }
+ TBool isLegalCompositionCharacter=EFalse;
+ switch (iInputMethod)
+ {
+ case EInputMethodPlain:
+ if (iInputCapabilities.SupportsAllText())
+ {
+ isLegalCompositionCharacter=keyCodeInUpperCase.IsPrint();
+ }
+ else
+ {
+ const TBool isDigit=((keyCodeInUpperCase>='0') && (keyCodeInUpperCase<='9'));
+ isLegalCompositionCharacter=(iInputCapabilities.SupportsWesternNumericIntegerPositive() && isDigit);
+ if (isLegalCompositionCharacter)
+ {
+ break;
+ }
+ isLegalCompositionCharacter=(iInputCapabilities.SupportsWesternNumericIntegerNegative() && (isDigit || ((iSelectedCompositionText.LowerPos()==0) && (keyCodeInUpperCase=='-'))));
+ if (isLegalCompositionCharacter)
+ {
+ break;
+ }
+ isLegalCompositionCharacter=(iInputCapabilities.SupportsWesternNumericReal() && (isDigit || IsLegalNonDigitForRealNumber(keyCodeInUpperCase)));
+ if (isLegalCompositionCharacter)
+ {
+ break;
+ }
+ const TUint foldFlags=(TChar::EFoldCase|TChar::EFoldAccents);
+ const TUint foldedKeyCode=User::Fold(keyCodeInUpperCase, foldFlags);
+ isLegalCompositionCharacter=(iInputCapabilities.SupportsWesternAlphabetic() && (foldedKeyCode>=User::Fold('A', foldFlags)) && (foldedKeyCode<=User::Fold('Z', foldFlags)));
+ if (isLegalCompositionCharacter)
+ {
+ break;
+ }
+ }
+ break;
+ case EInputMethodHexadecimalCharacterCode:
+ isLegalCompositionCharacter=keyCodeInUpperCase.IsHexDigit();
+ break;
+ case EInputMethodOnePastTheLast:
+#if defined(_DEBUG)
+ default:
+ Panic(EPanicBadInputMethod3);
+#endif
+ break;
+ }
+ if (isLegalCompositionCharacter)
+ {
+ iCharacterCode=aKeyEvent.iCode; // set iCharacterCode to aKeyEvent.iCode rather than keyCodeInUpperCase so that the original case is preserved
+ iFep.MakeDeferredFunctionCall(*this); // deferred call to InsertCompositionCharacterAndDrawNowL
+ if (bufferLength==0)
+ {
+ 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
+ }
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
+ }
+ if (bufferLength>0)
+ {
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
+ }
+ break;
+ }
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasNotConsumed); // returns from this function
+ }
+
+void CTstControl::HandlePointerEventL(const TPointerEvent& aPointerEvent)
+ {
+ switch (aPointerEvent.iType)
+ {
+ case TPointerEvent::EButton1Down:
+ if (IsFocused() ||
+ (iFlags&EFlagHasNoCompositionWindow) ||
+ (aPointerEvent.iPosition.iX<1) || (aPointerEvent.iPosition.iX>=iSize.iWidth-1) ||
+ (aPointerEvent.iPosition.iY<1) || (aPointerEvent.iPosition.iY>=1+EGapAboveCompositionLine+iCompositionFont->HeightInPixels()+EGapBelowCompositionLine))
+ {
+ iFlags|=EFlagWindowIsBeingDragged;
+ iPositionOnWindowBeingDragged=aPointerEvent.iPosition;
+ }
+ else
+ {
+ if (~iFlags&EFlagInsideInlineEditingTransaction)
+ {
+ const TInt newPositionOfInsertionPointInBuffer=PositionInBuffer(aPointerEvent.iPosition.iX);
+ const TInt newPositionOfAnchorInBuffer=(aPointerEvent.iModifiers&EModifierShift)? iSelectedCompositionText.iAnchorPos: newPositionOfInsertionPointInBuffer;
+ if ((iSelectedCompositionText.iCursorPos!=newPositionOfInsertionPointInBuffer) || (iSelectedCompositionText.iAnchorPos!=newPositionOfAnchorInBuffer))
+ {
+ const TBool needToDraw=((iSelectedCompositionText.Length()>0) || (aPointerEvent.iModifiers&EModifierShift)); // don't need to draw if there is no selected text as a result of this event, or if there previously was no selected text before this event
+ SetPositionOfInsertionPointInBuffer(newPositionOfInsertionPointInBuffer, newPositionOfAnchorInBuffer);
+ if (needToDraw)
+ {
+ DrawNow();
+ }
+ }
+ }
+ }
+ break;
+ case TPointerEvent::EDrag:
+ if (iFlags&EFlagWindowIsBeingDragged)
+ {
+ SetPosition(aPointerEvent.iParentPosition-iPositionOnWindowBeingDragged);
+ }
+ else
+ {
+ if (~iFlags&EFlagInsideInlineEditingTransaction)
+ {
+ const TInt newPositionOfInsertionPointInBuffer=PositionInBuffer(aPointerEvent.iPosition.iX);
+ if (iSelectedCompositionText.iCursorPos!=newPositionOfInsertionPointInBuffer)
+ {
+ SetPositionOfInsertionPointInBuffer(newPositionOfInsertionPointInBuffer, iSelectedCompositionText.iAnchorPos);
+ DrawNow();
+ }
+ }
+ }
+ break;
+ case TPointerEvent::EButton1Up:
+ iFlags&=~EFlagWindowIsBeingDragged;
+ break;
+#if defined(__GCC32__)
+ default:
+ break;
+#endif
+ }
+ }
+
+void CTstControl::Draw(const TRect&) const
+ {
+ CWindowGc& graphicsContext=SystemGc();
+ graphicsContext.SetPenStyle(CGraphicsContext::ESolidPen);
+ graphicsContext.SetPenColor(KRgbBlack);
+ graphicsContext.SetBrushStyle(CGraphicsContext::ENullBrush);
+ TRect rectangle(Rect());
+ graphicsContext.DrawRect(rectangle);
+ rectangle.Shrink(1, 1);
+ graphicsContext.SetBrushStyle(CGraphicsContext::ESolidBrush);
+ if (IsFocused())
+ {
+ __ASSERT_DEBUG(iBuffer.Length()==0, Panic(EPanicInconsistentState));
+ // the pen color is still black here
+ graphicsContext.SetBrushColor(KRgbBlack);
+ graphicsContext.DrawRect(rectangle);
+ const TPoint center=rectangle.Center();
+ graphicsContext.SetPenColor(KRgbWhite);
+ const TPoint leftArrowHead((rectangle.iTl.iX+center.iX)/2, center.iY);
+ const TPoint rightArrowHead((center.iX+rectangle.iBr.iX)/2, center.iY);
+ const TPoint topArrowHead(center.iX, (rectangle.iTl.iY+center.iY)/2);
+ const TPoint bottomArrowHead(center.iX, (center.iY+rectangle.iBr.iY)/2);
+ graphicsContext.DrawLine(leftArrowHead, rightArrowHead);
+ graphicsContext.Plot(rightArrowHead);
+ graphicsContext.DrawLine(topArrowHead, bottomArrowHead);
+ graphicsContext.Plot(bottomArrowHead);
+ graphicsContext.DrawLine(TPoint(leftArrowHead.iX+EArrowHeadSize, leftArrowHead.iY+EArrowHeadSize), leftArrowHead);
+ graphicsContext.DrawLine(TPoint(leftArrowHead.iX+EArrowHeadSize, leftArrowHead.iY-EArrowHeadSize), leftArrowHead);
+ graphicsContext.DrawLine(TPoint(rightArrowHead.iX-EArrowHeadSize, rightArrowHead.iY-EArrowHeadSize), rightArrowHead);
+ graphicsContext.DrawLine(TPoint(rightArrowHead.iX-EArrowHeadSize, rightArrowHead.iY+EArrowHeadSize), rightArrowHead);
+ graphicsContext.DrawLine(TPoint(topArrowHead.iX-EArrowHeadSize, topArrowHead.iY+EArrowHeadSize), topArrowHead);
+ graphicsContext.DrawLine(TPoint(topArrowHead.iX+EArrowHeadSize, topArrowHead.iY+EArrowHeadSize), topArrowHead);
+ graphicsContext.DrawLine(TPoint(bottomArrowHead.iX+EArrowHeadSize, bottomArrowHead.iY-EArrowHeadSize), bottomArrowHead);
+ graphicsContext.DrawLine(TPoint(bottomArrowHead.iX-EArrowHeadSize, bottomArrowHead.iY-EArrowHeadSize), bottomArrowHead);
+ }
+ else
+ {
+ TRect temp(rectangle);
+ temp.iBr.iY=temp.iTl.iY;
+ graphicsContext.SetBrushColor(KRgbWhite);
+ if (~iFlags&EFlagHasNoCompositionWindow)
+ {
+ graphicsContext.UseFont(iCompositionFont);
+ temp.iBr.iY+=EGapAboveCompositionLine+iCompositionFont->HeightInPixels()+EGapBelowCompositionLine;
+ TRect temp2=temp;
+ const TInt startOfSelectedCompositionText=iSelectedCompositionText.LowerPos();
+ const TPtrC textBeforeSelectedText(iBuffer.Left(startOfSelectedCompositionText));
+ temp2.iBr.iX=temp2.iTl.iX;
+ temp2.iBr.iX+=iCompositionFont->TextWidthInPixels(textBeforeSelectedText);
+ graphicsContext.SetPenColor(KRgbRed);
+ graphicsContext.DrawText(textBeforeSelectedText, temp2, EGapAboveCompositionLine+iCompositionFont->AscentInPixels(), CGraphicsContext::ELeft, EGapLeftOfEachLine);
+ const TPtrC selectedText(iBuffer.Mid(startOfSelectedCompositionText, iSelectedCompositionText.Length()));
+ temp2.iTl.iX=temp2.iBr.iX;
+ temp2.iBr.iX+=iCompositionFont->TextWidthInPixels(selectedText);
+ graphicsContext.SetPenColor(KRgbGreen);
+ graphicsContext.DrawText(selectedText, temp2, EGapAboveCompositionLine+iCompositionFont->AscentInPixels(), CGraphicsContext::ELeft, EGapLeftOfEachLine);
+ const TPtrC textAfterSelectedText(iBuffer.Mid(iSelectedCompositionText.HigherPos()));
+ temp2.iTl.iX=temp2.iBr.iX;
+ temp2.iBr.iX=temp.iBr.iX;
+ graphicsContext.SetPenColor(KRgbRed);
+ graphicsContext.DrawText(textAfterSelectedText, temp2, EGapAboveCompositionLine+iCompositionFont->AscentInPixels(), CGraphicsContext::ELeft, EGapLeftOfEachLine);
+ graphicsContext.DiscardFont();
+ graphicsContext.SetPenColor(KRgbBlack);
+ }
+ TBuf<200> textToDisplay;
+ textToDisplay=KLitInputMethodColonSpace;
+ switch (iInputMethod)
+ {
+ case EInputMethodPlain:
+ textToDisplay.Append(KLitPlain);
+ break;
+ case EInputMethodHexadecimalCharacterCode:
+ textToDisplay.Append(KLitHexadecimalCharacterCode);
+ break;
+ default:
+#if defined(_DEBUG)
+ Panic(EPanicBadInputMethod5);
+#endif
+ break;
+ }
+ const TInt statusFontHeightInPixels=iStatusFont->HeightInPixels();
+ const TInt statusFontAscentInPixels=iStatusFont->AscentInPixels();
+ graphicsContext.SetBrushColor(KRgbGray);
+ graphicsContext.UseFont(iStatusFont);
+ temp.iTl.iY=temp.iBr.iY;
+ temp.iBr.iY+=EGapAboveTopStatusLine+statusFontHeightInPixels+EGapBetweenEachStatusLine;
+ graphicsContext.DrawText(textToDisplay, temp, EGapAboveTopStatusLine+statusFontAscentInPixels, CGraphicsContext::ELeft, EGapLeftOfEachLine);
+ textToDisplay=KLitInlineEditingColonSpace;
+ textToDisplay.Append((iFlags&EFlagInlineEditingEnabled)? KLitEnabled(): KLitDisabled());
+ temp.iTl.iY=temp.iBr.iY;
+ temp.iBr.iY+=statusFontHeightInPixels+EGapBetweenEachStatusLine;
+ graphicsContext.DrawText(textToDisplay, temp, statusFontAscentInPixels, CGraphicsContext::ELeft, EGapLeftOfEachLine);
+ textToDisplay=KLitOpeningSquareBracket;
+ textToDisplay.Append(KLitCaptionColonSpace);
+ textToDisplay.Append(KLitQuotationMark);
+ const MCoeCaptionRetrieverForFep* captionRetrieverForFep=iInputCapabilities.CaptionRetrieverForFep();
+ if (captionRetrieverForFep!=NULL)
+ {
+ TBuf<51> caption;
+ captionRetrieverForFep->GetCaptionForFep(caption);
+ const TInt captionLength=caption.Length();
+ if (captionLength==caption.MaxLength())
+ {
+ caption[captionLength-1]=KEllipsisCharacter;
+ }
+ textToDisplay.Append(caption);
+ }
+ textToDisplay.Append(KLitQuotationMark);
+ textToDisplay.Append(KLitClosingSquareBracket);
+ temp.iTl.iY=temp.iBr.iY;
+ temp.iBr.iY+=statusFontHeightInPixels+EGapBetweenEachStatusLine;
+ graphicsContext.DrawText(textToDisplay, temp, statusFontAscentInPixels, CGraphicsContext::ELeft, EGapLeftOfEachLine);
+ textToDisplay=KLitOpeningSquareBracket;
+ textToDisplay.Append(KLitStateColonSpace);
+ textToDisplay.Append(KLitQuotationMark);
+ MCoeFepAwareTextEditor* const fepAwareTextEditor=iInputCapabilities.FepAwareTextEditor();
+ if (fepAwareTextEditor!=NULL)
+ {
+ MCoeFepAwareTextEditor_Extension1* const extension1=fepAwareTextEditor->Extension1();
+ if (extension1!=NULL)
+ {
+ MCoeFepAwareTextEditor_Extension1::CState* const state=extension1->State(TUid::Uid(KTfep1Uid));
+ if (state!=NULL)
+ {
+ textToDisplay.AppendNum(STATIC_CAST(CStateInformation*, state)->MeaninglessNumber()); // this cast is safe as KTfep1Uid is used to retrieve state
+ }
+ }
+ }
+ textToDisplay.Append(KLitQuotationMark);
+ textToDisplay.Append(KLitClosingSquareBracket);
+ temp.iTl.iY=temp.iBr.iY;
+ temp.iBr.iY+=statusFontHeightInPixels+EGapBetweenEachStatusLine;
+ graphicsContext.DrawText(textToDisplay, temp, statusFontAscentInPixels, CGraphicsContext::ELeft, EGapLeftOfEachLine);
+ textToDisplay=KLitOpeningSquareBracket;
+ textToDisplay.Append(KLitInputCapabilitiesColonSpace);
+ if (iInputCapabilities.IsNone())
+ {
+ textToDisplay.Append(KLitNone);
+ }
+ else
+ {
+ TBool deleteLastSeparator=EFalse;
+ if (iInputCapabilities.SupportsWesternNumericIntegerPositive())
+ {
+ textToDisplay.Append(KLitWesternNumericIntegerPositive);
+ textToDisplay.Append(KLitCommaSpace);
+ deleteLastSeparator=ETrue;
+ }
+ if (iInputCapabilities.SupportsWesternNumericIntegerNegative())
+ {
+ textToDisplay.Append(KLitWesternNumericIntegerNegative);
+ textToDisplay.Append(KLitCommaSpace);
+ deleteLastSeparator=ETrue;
+ }
+ if (iInputCapabilities.SupportsWesternNumericReal())
+ {
+ textToDisplay.Append(KLitWesternNumericReal);
+ textToDisplay.Append(KLitCommaSpace);
+ deleteLastSeparator=ETrue;
+ }
+ if (iInputCapabilities.SupportsWesternAlphabetic())
+ {
+ textToDisplay.Append(KLitWesternAlphabetic);
+ textToDisplay.Append(KLitCommaSpace);
+ deleteLastSeparator=ETrue;
+ }
+ if (iInputCapabilities.SupportsJapaneseHiragana())
+ {
+ textToDisplay.Append(KLitJapaneseHiragana);
+ textToDisplay.Append(KLitCommaSpace);
+ deleteLastSeparator=ETrue;
+ }
+ if (iInputCapabilities.SupportsJapaneseKatakanaHalfWidth())
+ {
+ textToDisplay.Append(KLitJapaneseKatakanaHalfWidth);
+ textToDisplay.Append(KLitCommaSpace);
+ deleteLastSeparator=ETrue;
+ }
+ if (iInputCapabilities.SupportsJapaneseKatakanaFullWidth())
+ {
+ textToDisplay.Append(KLitJapaneseKatakanaFullWidth);
+ textToDisplay.Append(KLitCommaSpace);
+ deleteLastSeparator=ETrue;
+ }
+ if (iInputCapabilities.SupportsDialableCharacters())
+ {
+ textToDisplay.Append(KLitDialableCharacters);
+ textToDisplay.Append(KLitCommaSpace);
+ deleteLastSeparator=ETrue;
+ }
+ if (iInputCapabilities.SupportsSecretText())
+ {
+ textToDisplay.Append(KLitSecretText);
+ textToDisplay.Append(KLitCommaSpace);
+ deleteLastSeparator=ETrue;
+ }
+ if (iInputCapabilities.SupportsAllText())
+ {
+ textToDisplay.Append(KLitAllText);
+ textToDisplay.Append(KLitCommaSpace);
+ deleteLastSeparator=ETrue;
+ }
+ if (iInputCapabilities.SupportsNavigation())
+ {
+ textToDisplay.Append(KLitNavigation);
+ textToDisplay.Append(KLitCommaSpace);
+ deleteLastSeparator=ETrue;
+ }
+ const TCoeInputCapabilities::MCoeFepSpecificExtensions* const fepSpecificInputCapabilityExtensions=iInputCapabilities.FepSpecificExtensions(TUid::Uid(KTfep1Uid));
+ if (fepSpecificInputCapabilityExtensions!=NULL)
+ {
+ textToDisplay.Append(KLitExtensionsColonSpace);
+ if (fepSpecificInputCapabilityExtensions->SupportsPhoneticAlphabet())
+ {
+ textToDisplay.Append(KLitPhoneticAlphabet);
+ textToDisplay.Append(KLitCommaSpace);
+ deleteLastSeparator=ETrue;
+ }
+ }
+ if (deleteLastSeparator)
+ {
+ const TInt lengthToDelete=KLitCommaSpace().Length();
+ textToDisplay.Delete(textToDisplay.Length()-lengthToDelete, lengthToDelete);
+ }
+ }
+ textToDisplay.Append(KLitClosingSquareBracket);
+ temp.iTl.iY=temp.iBr.iY;
+ temp.iBr.iY=rectangle.iBr.iY;
+ __ASSERT_DEBUG(temp.iBr.iY==temp.iTl.iY+statusFontHeightInPixels+EGapBelowBottomStatusLine, Panic(EPanicBadHeight));
+ graphicsContext.DrawText(textToDisplay, temp, statusFontAscentInPixels, CGraphicsContext::ELeft, EGapLeftOfEachLine);
+ graphicsContext.DiscardFont();
+ }
+ }
+
+void CTstControl::DrawText(const TParam& aParam, const TLineInfo& aLineInfo, const TCharFormat& aFormat, const TDesC& aText, const TPoint& aTextOrigin, TInt aExtraPixels) const
+ {
+ MFormCustomDraw::DrawText(aParam, aLineInfo, aFormat, aText, aTextOrigin, aExtraPixels);
+ // ?? draw the dotted underline whose phase starts at aParam.iTextLayoutTopLeft.iX
+ }
+
+void CTstControl::GetFormatOfFepInlineText(TCharFormat& aFormat, TInt& aNumberOfCharactersWithSameFormat, TInt aPositionOfCharacter) const
+ {
+ const TInt lengthOfSelection=iSelectedCompositionText.Length();
+ const TInt startOfSelectedInlineText=iSelectedCompositionText.LowerPos();
+ const TInt endOfSelectedInlineText=iSelectedCompositionText.HigherPos();
+ const MCoeFepAwareTextEditor& fepAwareTextEditor=*iInputCapabilities.FepAwareTextEditor();
+ TCursorSelection cursorSelection;
+ fepAwareTextEditor.GetCursorSelectionForFep(cursorSelection);
+ TCharFormat formatBeforeInlineText;
+ GetFormatAtDocumentPosition(formatBeforeInlineText, cursorSelection.LowerPos()-1, fepAwareTextEditor);
+ TCharFormat formatAfterInlineText;
+ GetFormatAtDocumentPosition(formatAfterInlineText, cursorSelection.HigherPos()+1, fepAwareTextEditor);
+ aFormat=formatBeforeInlineText;
+ if ((lengthOfSelection>0) && (aPositionOfCharacter>=startOfSelectedInlineText) && (aPositionOfCharacter<endOfSelectedInlineText))
+ {
+ aFormat.iFontPresentation.iTextColor=KRgbGreen;
+ }
+ else
+ {
+ aFormat.iFontPresentation.iTextColor=KRgbRed;
+ }
+ if ((formatBeforeInlineText.iFontPresentation.iUnderline!=EUnderlineOn) && (formatAfterInlineText.iFontPresentation.iUnderline!=EUnderlineOn))
+ {
+ aFormat.iFontPresentation.iUnderline=EUnderlineOn;
+ }
+ else if ((formatBeforeInlineText.iFontPresentation.iUnderline!=EUnderlineOff) && (formatAfterInlineText.iFontPresentation.iUnderline!=EUnderlineOff))
+ {
+ aFormat.iFontPresentation.iUnderline=EUnderlineOff;
+ }
+ else
+ {
+ aFormat.iFontSpec.iFontStyle.SetPrintPosition(EPrintPosSuperscript);
+ }
+ const TInt endOfRunOfCharactersOfSameFormat=((lengthOfSelection==0) || (aPositionOfCharacter>=endOfSelectedInlineText))?
+ iBuffer.Length():
+ (aPositionOfCharacter>=startOfSelectedInlineText)?
+ endOfSelectedInlineText:
+ startOfSelectedInlineText;
+ aNumberOfCharactersWithSameFormat=endOfRunOfCharactersOfSameFormat-aPositionOfCharacter;
+ }
+
+void CTstControl::HandlePointerEventInInlineTextL(TPointerEvent::TType aType, TUint, TInt aPositionInInlineText)
+ {
+ MCoeFepAwareTextEditor* const fepAwareTextEditor=iInputCapabilities.FepAwareTextEditor();
+ __ASSERT_DEBUG(fepAwareTextEditor!=NULL, Panic(EPanicNoFepAwareTextEditorAlthoughCurrentlyInlineEditing));
+ const TCursorSelection oldSelectedCompositionText=iSelectedCompositionText;
+ switch (aType)
+ {
+ case TPointerEvent::EButton1Down:
+ iSelectedCompositionText.iAnchorPos=aPositionInInlineText;
+ // fall through
+ case TPointerEvent::EDrag:
+ iSelectedCompositionText.iCursorPos=aPositionInInlineText;
+ break;
+#if defined(__GCC32__)
+ default:
+ break;
+#endif
+ }
+ if ((iSelectedCompositionText.iCursorPos!=oldSelectedCompositionText.iCursorPos) || (iSelectedCompositionText.iAnchorPos!=oldSelectedCompositionText.iAnchorPos))
+ {
+ fepAwareTextEditor->UpdateFepInlineTextL(iBuffer, iSelectedCompositionText.iCursorPos);
+ }
+ }
+
+void CTstControl::ExecuteFunctionL()
+ {
+ InsertCompositionCharacterAndDrawNowL(iCharacterCode);
+ }
+
+// CTstControl::CStateInformation
+
+CTstControl::CStateInformation* CTstControl::CStateInformation::NewLC(TInt aMeaninglessNumber)
+ {
+ CStateInformation* const stateInformation=new(ELeave) CStateInformation;
+ CleanupStack::PushL(stateInformation);
+ stateInformation->ConstructL(aMeaninglessNumber);
+ return stateInformation;
+ }
+
+CTstControl::CStateInformation::~CStateInformation()
+ {
+ delete iMeaninglessNumber;
+ }
+
+CTstControl::CStateInformation::CStateInformation()
+ :iMeaninglessNumber(NULL)
+ {
+ }
+
+void CTstControl::CStateInformation::ConstructL(TInt aMeaninglessNumber)
+ {
+ BaseConstructL();
+ iMeaninglessNumber=new(ELeave) TInt(aMeaninglessNumber);
+ }
+
+// CTstFep
+
+CTstFep::CTstFep(CCoeEnv& aConeEnvironment)
+ :CCoeFep(aConeEnvironment)
+ {
+ }
+
+void CTstFep::ConstructL(const CCoeFepParameters& aFepParameters)
+ {
+ BaseConstructL(aFepParameters);
+ iControl=CTstControl::NewL(*this);
+ ReadAllAttributesL();
+ iControl->ActivateL();
+ }
+
+CTstFep::~CTstFep()
+ {
+ delete iControl;
+ }
+
+void CTstFep::CancelTransaction()
+ {
+ iControl->CancelTransaction();
+ }
+
+void CTstFep::IsOnHasChangedState()
+ {
+ iControl->IsOnHasChangedState();
+ }
+
+void CTstFep::OfferKeyEventL(TEventResponse& aEventResponse, const TKeyEvent& aKeyEvent, TEventCode aEventCode)
+ {
+ // this function must correctly set aEventResponse *before* calling anything that can leave
+ aEventResponse=EEventWasConsumed; // this assumes that CTstControl::OfferKeyEventL will not leave if it returns EKeyWasNotConsumed
+ switch (iControl->OfferKeyEventL(aKeyEvent, aEventCode))
+ {
+ case EKeyWasNotConsumed:
+ aEventResponse=EEventWasNotConsumed;
+ break;
+ case EKeyWasConsumed:
+ aEventResponse=EEventWasConsumed;
+ break;
+#if defined(_DEBUG)
+ default:
+ Panic(EPanicBadKeyResponse);
+ break;
+#endif
+ }
+ }
+
+void CTstFep::OfferPointerEventL(TEventResponse& aEventResponse, const TPointerEvent& aPointerEvent, const CCoeControl* aWindowOwningControl)
+ {
+ iControl->OfferPointerEventL(aEventResponse, aPointerEvent, aWindowOwningControl);
+ }
+
+void CTstFep::OfferPointerBufferReadyEventL(TEventResponse& aEventResponse, const CCoeControl*)
+ {
+ aEventResponse=EEventWasNotConsumed;
+ }
+
+TInt CTstFep::NumberOfAttributes() const
+ {
+ return CTstControl::NumberOfAttributes();
+ }
+
+TUid CTstFep::AttributeAtIndex(TInt aIndex) const
+ {
+ return CTstControl::AttributeAtIndex(aIndex);
+ }
+
+void CTstFep::WriteAttributeDataToStreamL(TUid aAttributeUid, RWriteStream& aStream) const
+ {
+ iControl->WriteAttributeDataToStreamL(aAttributeUid, aStream);
+ }
+
+void CTstFep::ReadAttributeDataFromStreamL(TUid aAttributeUid, RReadStream& aStream)
+ {
+ iControl->ReadAttributeDataFromStreamL(aAttributeUid, aStream);
+ }
+
+void CTstFep::HandleGainingForeground()
+ {
+ iControl->HandleGainingForeground();
+ }
+
+void CTstFep::HandleLosingForeground()
+ {
+ iControl->HandleLosingForeground();
+ }
+
+void CTstFep::HandleChangeInFocus()
+ {
+ iControl->HandleChangeInFocus();
+ }
+
+void CTstFep::HandleDestructionOfFocusedItem()
+ {
+ iControl->HandleDestructionOfFocusedItem();
+ }
+
+// TTstResourceFileId
+
+#pragma warning(disable: 4355) // "'this' : used in base member initializer list"
+
+TTstResourceFileId::TTstResourceFileId(CCoeEnv& aConeEnvironment, TInt aResourceFileId)
+ :TCleanupItem(UnloadResourceFile, this),
+ iConeEnvironment(aConeEnvironment),
+ iResourceFileId(aResourceFileId)
+ {
+ }
+
+#pragma warning(default: 4355)
+
+void TTstResourceFileId::UnloadResourceFile(TAny* aThis)
+ {
+ TTstResourceFileId& resourceFileId=*STATIC_CAST(TTstResourceFileId*, aThis);
+ resourceFileId.iConeEnvironment.DeleteResourceFile(resourceFileId.iResourceFileId);
+ }
+
+// CTstSettingsDialog
+
+CTstSettingsDialog::CTstSettingsDialog()
+ :iInlineEditingEnabled(ETrue),
+ iInputMethod(0)
+ {
+ }
+
+TBool CTstSettingsDialog::OkToExitL(TInt aButtonId)
+ {
+ __ASSERT_ALWAYS(aButtonId==EEikBidOk, Panic(EPanicUnexpectedButtonId));
+ switch (STATIC_CAST(CEikCheckBox*, Control(EControlIdInlineEditingEnabled))->State())
+ {
+ case CEikButtonBase::EClear:
+ iInlineEditingEnabled=EFalse;
+ break;
+ case CEikButtonBase::ESet:
+ iInlineEditingEnabled=ETrue;
+ break;
+ case CEikButtonBase::EIndeterminate:
+#if defined(_DEBUG)
+ default:
+ Panic(EPanicBadCheckBoxState);
+#endif
+ break;
+ }
+ iInputMethod=STATIC_CAST(CEikChoiceListBase*, Control(EControlIdInputMethod))->CurrentItem();
+ TFixedArray<TUid, 2> attributeUids;
+ __ASSERT_DEBUG(NumberOfAttributes()==2, Panic(EPanicBadNumberOfAttributes));
+ attributeUids[0].iUid=AttributeAtIndex(0).iUid;
+ attributeUids[1].iUid=AttributeAtIndex(1).iUid;
+ WriteAttributeDataAndBroadcastL(*iCoeEnv, attributeUids.Array());
+ return ETrue;
+ }
+
+void CTstSettingsDialog::PreLayoutDynInitL()
+ {
+ ReadAllAttributesL(*iCoeEnv);
+ STATIC_CAST(CEikCheckBox*, Control(EControlIdInlineEditingEnabled))->SetState(iInlineEditingEnabled? CEikButtonBase::ESet: CEikButtonBase::EClear);
+ STATIC_CAST(CEikChoiceListBase*, Control(EControlIdInputMethod))->SetCurrentItem(iInputMethod);
+ }
+
+TInt CTstSettingsDialog::NumberOfAttributes() const
+ {
+ return CTstControl::NumberOfAttributes();
+ }
+
+TUid CTstSettingsDialog::AttributeAtIndex(TInt aIndex) const
+ {
+ return CTstControl::AttributeAtIndex(aIndex);
+ }
+
+void CTstSettingsDialog::WriteAttributeDataToStreamL(TUid aAttributeUid, RWriteStream& aStream) const
+ {
+ CTstControl::WriteAttributeDataToStreamL(aAttributeUid, aStream, iInlineEditingEnabled, iInputMethod);
+ }
+
+void CTstSettingsDialog::ReadAttributeDataFromStreamL(TUid aAttributeUid, RReadStream& aStream)
+ {
+ CTstControl::ReadAttributeDataFromStreamL(aAttributeUid, aStream, iInlineEditingEnabled, iInputMethod);
+ }
+
+
+