--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/fep/frontendprocessor/test/feps/TFEP2.CPP Tue Feb 02 01:02:04 2010 +0200
@@ -0,0 +1,1694 @@
+// 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 <e32math.h>
+#include <e32keys.h>
+#include <s32strm.h>
+#include <gdi.h>
+#include <fbs.h>
+#include <w32std.h>
+#include <coemain.h>
+#include <coeaui.h>
+#include <coecntrl.h>
+#include <coefepff.h>
+#include <fepbase.h>
+#include <bautils.h>
+#include <techview/eikon.hrh>
+#include <techview/eikdialg.h>
+#include <techview/eikchkbx.h>
+#include <techview/eikbutb.h>
+
+#include "tfep2.hrh"
+#include "TFEP2.H"
+#include "tfep2com.h"
+
+#define DEBUGGING_MESSAGES
+#if defined(DEBUGGING_MESSAGES)
+#include <e32svr.h>
+#endif
+
+// constants
+
+enum TPanic
+ {
+ EPanicTimerActive1=1,
+ EPanicTimerActive2,
+ EPanicUnexpectedError1,
+ EPanicUnexpectedError2,
+ EPanicUnexpectedError3,
+ EPanicUnexpectedError4,
+ EPanicUnexpectedError5,
+ EPanicUnexpectedError6,
+ EPanicBadIndex1,
+ EPanicBadIndex2,
+ EPanicBadAttributeUid1,
+ EPanicBadAttributeUid2,
+ EPanicBadAttributeUid3,
+ EPanicBadAttributeUid4,
+ EPanicLowLevelFlagsDoNotReflectStateOfRemoteObjects,
+ EPanicArithmeticConfusion,
+ EPanicBadLengthOfTextBeforeSelection,
+ EPanicSelectionExtendsPastEndOfDocument,
+ EPanicBadLengthOfTextAfterSelection,
+ EPanicBadLengthOfSelection,
+ EPanicBadKeyCode1,
+ EPanicBadKeyCode2,
+ EPanicBadHeight,
+ EPanicIsAlreadyActive,
+ EPanicInconsistentUpperCaseSetting,
+ EPanicBadFlagAffectingWhetherActive,
+ EPanicBadKeyResponse,
+ EPanicBadCheckBoxState,
+ EPanicUnexpectedButtonId,
+ EPanicBadNumberOfAttributes
+ };
+
+#if defined(_UNICODE)
+const TUint KEllipsisCharacter=0x2026;
+#else
+const TUint KEllipsisCharacter=0x85;
+#endif
+_LIT(KLitTFEP2, "TFEP2");
+_LIT(KLitBitmapHandleSynchronizationMutexName, "0x10003eaa-Mutex"); // using the same UID here as in the MMP file
+_LIT(KLitDllNameOfWindowServerPlugIn, "\\system\\fep\\TFEP2BE.ANI");
+_LIT(KLitStatusFontTypefaceName, "arial");
+_LIT(KLitNotAvailable, "[not available]");
+//_LIT(KLitTooLong, "[too long]");
+_LIT(KLitQuotationMark, "\"");
+_LIT(KLitTextBeforeSelectionColonSpace, "Text before selection: ");
+_LIT(KLitTextAfterSelectionColonSpace, "Text after selection: ");
+_LIT(KLitSelectionColonSpace, "Selection: ");
+_LIT(KLitUpperCaseColonSpace, "Upper case: ");
+_LIT(KLitOn, "on");
+_LIT(KLitOff, "off");
+_LIT(KLitScribbleAreaColonSpace, "Scribble area: ");
+_LIT(KLitWholeScreen, "whole screen");
+_LIT(KLitWindow, "window");
+_LIT(KLitPointerBufferColonSpace, "Pointer buffer: ");
+_LIT(KLitEnabled, "enabled");
+_LIT(KLitDisabled, "disabled");
+_LIT(KLitOpeningSquareBracket, "[");
+_LIT(KLitCaptionColonSpace, "Caption: ");
+_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(KLitCommaSpace, ", ");
+_LIT(KLitClosingSquareBracket, "]");
+
+// local and global functions
+
+LOCAL_C void Panic(TPanic aPanic)
+ {
+ User::Panic(KLitTFEP2, aPanic);
+ }
+
+GLDEF_C TInt E32Dll(
+ )
+ {
+ return KErrNone;
+ }
+
+// CTstScribbleWindow
+
+CTstScribbleWindow* CTstScribbleWindow::NewL(CTstFep& aFep, RWindowTreeNode& aParent)
+ {
+ CTstScribbleWindow* const scribbleWindow=new(ELeave) CTstScribbleWindow(aFep);
+ CleanupStack::PushL(scribbleWindow);
+ scribbleWindow->ConstructL(aParent);
+ CleanupStack::Pop(); // scribbleWindow
+ return scribbleWindow;
+ }
+
+CTstScribbleWindow::~CTstScribbleWindow()
+ {
+ // there is no need here to call FreePointerMoveBuffer on the window, as the buffer gets freed when the window gets destroyed
+ iArrayOfPolyLines.ResetAndDestroy();
+ iArrayOfPolyLines.Close();
+ delete iTimeOutTimer;
+ }
+
+void CTstScribbleWindow::SetPointerBufferEnabled(TBool aPointerBufferEnabled)
+ {
+ RDrawableWindow& window=*DrawableWindow();
+ if (!aPointerBufferEnabled!=!(iFlags&EFlagPointerBufferActuallyEnabled)) // fold non-zero values on both sides before comparing for inequality
+ {
+ if (aPointerBufferEnabled)
+ {
+ window.EnablePointerMoveBuffer();
+ iFlags|=EFlagPointerBufferActuallyEnabled;
+ }
+ else
+ {
+ window.DisablePointerMoveBuffer();
+ iFlags&=~EFlagPointerBufferActuallyEnabled;
+ }
+ }
+ }
+
+void CTstScribbleWindow::HandleTimeOutL()
+ {
+ TInt i;
+ TInt minimumX=KMaxTInt;
+ TInt maximumX=KMinTInt;
+ for (i=iArrayOfPolyLines.Count()-1; i>=0; --i)
+ {
+ const CArrayFix<TPoint>& polyLine=*iArrayOfPolyLines[i];
+ for (TInt j=polyLine.Count()-1; j>=0; --j)
+ {
+ const TInt x=polyLine[j].iX;
+ if (minimumX>x)
+ {
+ minimumX=x;
+ }
+ if (maximumX<x)
+ {
+ maximumX=x;
+ }
+ }
+ }
+ const TInt numberOfCharacters=((maximumX-minimumX)/80)+1;
+ CArrayFix<TUint>* arrayOfCharacters=new(ELeave) CArrayFixFlat<TUint>(numberOfCharacters); // a RArray would be better than a CArrayFix, but unfortunately RArray doesn't (yet) have a TArray interface
+ CleanupStack::PushL(arrayOfCharacters);
+ const TUint baseCharacter=iFep.UpperCase()? 'A': 'a';
+ TTime homeTime;
+ homeTime.HomeTime();
+ TInt64 seedForRandomNumber=homeTime.Int64();
+ for (i=0; i<numberOfCharacters; ++i)
+ {
+ arrayOfCharacters->AppendL(baseCharacter+(Math::Rand(seedForRandomNumber)%26));
+ }
+ iFep.SimulateKeyEventsL(arrayOfCharacters->Array());
+ CancelTransactionAndDrawNow();
+ CleanupStack::PopAndDestroy(); // arrayOfCharacters
+ }
+
+void CTstScribbleWindow::CancelTransactionAndDrawNow()
+ {
+ TBool changeWasMade;
+ CancelTransaction(changeWasMade);
+ if (changeWasMade)
+ {
+ DrawNow();
+ }
+ }
+
+void CTstScribbleWindow::CancelTransaction(TBool& aChangeWasMade)
+ {
+ aChangeWasMade=EFalse;
+ iTimeOutTimer->Cancel();
+ if (iArrayOfPolyLines.Count()>0)
+ {
+ iArrayOfPolyLines.ResetAndDestroy();
+ aChangeWasMade=ETrue;
+ }
+ }
+
+void CTstScribbleWindow::HandlePointerEventL(const TPointerEvent& aPointerEvent)
+ {
+ switch (aPointerEvent.iType)
+ {
+ case TPointerEvent::EDrag:
+ {
+ if (iFlags&EFlagPointerIsDown) // this test is needed in the case where there was a "leave" when handling the TRawEvent::EButton1Down event
+ {
+ __ASSERT_DEBUG(!iTimeOutTimer->IsActive(), Panic(EPanicTimerActive1));
+ CArrayFix<TPoint>& polyLine=*iArrayOfPolyLines[iArrayOfPolyLines.Count()-1];
+ polyLine.AppendL(aPointerEvent.iPosition);
+ ActivateGc();
+ CWindowGc& graphicsContext=SystemGc();
+ graphicsContext.SetPenStyle(CGraphicsContext::ESolidPen);
+ graphicsContext.SetPenColor(KRgbBlack);
+ graphicsContext.DrawLine(polyLine[polyLine.Count()-2], aPointerEvent.iPosition);
+ graphicsContext.Plot(aPointerEvent.iPosition);
+ DeactivateGc();
+ }
+ }
+ break;
+ case TPointerEvent::EButton1Down:
+ {
+ iTimeOutTimer->Cancel();
+ CArrayFix<TPoint>* const polyLine=new(ELeave) CArrayFixSeg<TPoint>(50);
+ CleanupStack::PushL(polyLine);
+ polyLine->AppendL(aPointerEvent.iPosition);
+ User::LeaveIfError(iArrayOfPolyLines.Append(polyLine));
+ CleanupStack::Pop(); // polyLine
+ ActivateGc();
+ CWindowGc& graphicsContext=SystemGc();
+ graphicsContext.SetPenStyle(CGraphicsContext::ESolidPen);
+ graphicsContext.SetPenColor(KRgbBlack);
+ graphicsContext.Plot(aPointerEvent.iPosition);
+ DeactivateGc();
+ iFlags|=EFlagPointerIsDown;
+ if (iArrayOfPolyLines.Count()==1)
+ {
+ iCoeEnv->ForEachFepObserverCall(FepObserverHandleStartOfTransactionL); // called at the end of handling this event as it may launch a waiting dialog
+ }
+ }
+ break;
+ case TPointerEvent::EButton1Up:
+ if (iFlags&EFlagPointerIsDown) // this test is needed in the cases where (i) there was a "leave" when handling the TRawEvent::EButton1Down event, and (ii) the window server sends a TPointerEvent::EButton1Up event if ClaimPointerGrab is called when the pointer is not down (this behaviour is the window-server's spec, it is not a bug)
+ {
+ __ASSERT_DEBUG(!iTimeOutTimer->IsActive(), Panic(EPanicTimerActive2));
+ iTimeOutTimer->After(ETimeOutInMicroSeconds);
+ iFlags&=~EFlagPointerIsDown;
+ }
+ break;
+#if defined(__GCC32__)
+ default:
+ break;
+#endif
+ }
+ }
+
+void CTstScribbleWindow::HandlePointerBufferReadyL()
+ {
+ TPoint arrayOfPoints[ENumberOfPointsInBuffer];
+ TPtr8 bufferOfPoints(REINTERPRET_CAST(TUint8*, arrayOfPoints), 0, ENumberOfPointsInBuffer*sizeof(TPoint));
+ User::LeaveIfError(DrawableWindow()->RetrievePointerMoveBuffer(bufferOfPoints));
+ if (iFlags&EFlagPointerIsDown) // this test is needed in the case where there was a "leave" when handling the TRawEvent::EButton1Down event
+ {
+ const TInt numberOfPointsInBuffer=bufferOfPoints.Length()/sizeof(TPoint);
+ if (numberOfPointsInBuffer>0)
+ {
+ CArrayFix<TPoint>& polyLine=*iArrayOfPolyLines[iArrayOfPolyLines.Count()-1];
+ for (TInt i=0; i<numberOfPointsInBuffer; ++i)
+ {
+ polyLine.AppendL(arrayOfPoints[i]);
+ }
+ ActivateGc();
+ CWindowGc& graphicsContext=SystemGc();
+ graphicsContext.SetPenStyle(CGraphicsContext::ESolidPen);
+ graphicsContext.SetPenColor(KRgbBlack);
+ graphicsContext.DrawLine(polyLine[polyLine.Count()-(numberOfPointsInBuffer+1)], arrayOfPoints[0]);
+ graphicsContext.DrawPolyLine(arrayOfPoints, numberOfPointsInBuffer); // draws the end-point of the last line segment of the poly-line
+ DeactivateGc();
+ }
+ }
+ }
+
+CTstScribbleWindow::CTstScribbleWindow(CTstFep& aFep)
+ :iFep(aFep),
+ iFlags(0),
+ iArrayOfPolyLines(12),
+ iTimeOutTimer(NULL)
+ {
+ }
+
+void CTstScribbleWindow::ConstructL(RWindowTreeNode& aParent)
+ {
+ CreateWindowL(aParent);
+ EnableDragEvents();
+ ClaimPointerGrab();
+ SetNonFocusing();
+ RDrawableWindow& window=*DrawableWindow();
+ User::LeaveIfError(window.AllocPointerMoveBuffer(ENumberOfPointsInBuffer, 0));
+ iFlags|=EFlagPointerBufferActuallyEnabled;
+ iTimeOutTimer=CTimeOutTimer::NewL(*this);
+ }
+
+void CTstScribbleWindow::Draw(const TRect&) const
+ {
+ CWindowGc& graphicsContext=SystemGc();
+ graphicsContext.SetBrushStyle(CGraphicsContext::ESolidBrush);
+ graphicsContext.SetBrushColor(KRgbWhite);
+ graphicsContext.SetPenStyle(CGraphicsContext::ESolidPen);
+ graphicsContext.SetPenColor(KRgbWhite);
+ graphicsContext.DrawRect(Rect());
+ graphicsContext.SetPenColor(KRgbBlack);
+ for (TInt i=iArrayOfPolyLines.Count()-1; i>=0; --i)
+ {
+ graphicsContext.DrawPolyLine(iArrayOfPolyLines[i]); // draws the end-point of the last line segment of the poly-line
+ }
+ }
+
+// CTstScribbleWindow::CTimeOutTimer
+
+CTstScribbleWindow::CTimeOutTimer* CTstScribbleWindow::CTimeOutTimer::NewL(CTstScribbleWindow& aScribbleWindow)
+ {
+ CTimeOutTimer* const timeOutTimer=new(ELeave) CTimeOutTimer(aScribbleWindow);
+ CleanupStack::PushL(timeOutTimer);
+ CActiveScheduler::Add(timeOutTimer);
+ timeOutTimer->ConstructL();
+ CleanupStack::Pop(); // timeOutTimer
+ return timeOutTimer;
+ }
+
+CTstScribbleWindow::CTimeOutTimer::~CTimeOutTimer()
+ {
+ Cancel();
+ }
+
+CTstScribbleWindow::CTimeOutTimer::CTimeOutTimer(CTstScribbleWindow& aScribbleWindow)
+ :CTimer(EPriorityLow),
+ iScribbleWindow(aScribbleWindow)
+ {
+ }
+
+void CTstScribbleWindow::CTimeOutTimer::RunL()
+ {
+ iScribbleWindow.HandleTimeOutL();
+ }
+
+// CTstWholeScreenScribbleArea
+
+CTstWholeScreenScribbleArea* CTstWholeScreenScribbleArea::NewL(RWsSession& aWindowServerSession, RWindowGroup& aWindowGroup, const TSize& aScreenSize, TDisplayMode aDisplayMode, const TDesC& aDllName)
+ {
+ CTstWholeScreenScribbleArea* const wholeScreenScribbleArea=new(ELeave) CTstWholeScreenScribbleArea(aWindowServerSession);
+ CleanupStack::PushL(wholeScreenScribbleArea);
+ wholeScreenScribbleArea->ConstructL(aWindowGroup, aScreenSize, aDisplayMode, aDllName);
+ CleanupStack::Pop(); // wholeScreenScribbleArea
+ return wholeScreenScribbleArea;
+ }
+
+CTstWholeScreenScribbleArea::~CTstWholeScreenScribbleArea()
+ {
+ if (iFlags&EFlagMutexIsConstructed)
+ {
+ iMutex.Wait();
+ iHandWritingRecognizer.Close();
+ iSprite.Close();
+ iDll.Close();
+ delete iSpriteMember.iBitmap;
+ delete iSpriteMember.iMaskBitmap;
+ iMutex.Signal();
+ }
+ }
+
+CTstWholeScreenScribbleArea::CTstWholeScreenScribbleArea(RWsSession& aWindowServerSession)
+ :iFlags(0),
+ iDll(aWindowServerSession),
+ iSprite(aWindowServerSession)
+ {
+ iSpriteMember.iBitmap=NULL;
+ iSpriteMember.iMaskBitmap=NULL;
+ }
+
+void CTstWholeScreenScribbleArea::ConstructL(RWindowGroup& aWindowGroup, const TSize& aScreenSize, TDisplayMode aDisplayMode, const TDesC& aDllName)
+ {
+ // the mutex *must* be created first as it is used in the construction and destruction routines of this class
+ TInt error=iMutex.CreateGlobal(KLitBitmapHandleSynchronizationMutexName);
+ if (error==KErrAlreadyExists)
+ {
+ error=iMutex.OpenGlobal(KLitBitmapHandleSynchronizationMutexName);
+ }
+ User::LeaveIfError(error);
+ iFlags|=EFlagMutexIsConstructed;
+ iMutex.Wait();
+ CleanupStack::PushL(TCleanupItem(SignalMutex, &iMutex));
+ User::LeaveIfError(iDll.Load(aDllName));
+ User::LeaveIfError(iSprite.Construct(aWindowGroup, TPoint(0, 0), ESpriteNoChildClip|ESpriteNoShadows));
+ STstBitmapHandles bitmapHandles;
+ iHandWritingRecognizer=RHandWritingRecognizer(iDll);
+ iHandWritingRecognizer.ConstructL(iSprite, bitmapHandles);
+ iSpriteMember.iBitmap=CreateBitmapL(bitmapHandles.iMain, aScreenSize, aDisplayMode);
+ iSpriteMember.iMaskBitmap=CreateBitmapL(bitmapHandles.iMask, aScreenSize, aDisplayMode);
+ iSpriteMember.iInvertMask=ETrue;
+ iSpriteMember.iDrawMode=CGraphicsContext::EDrawModePEN;
+ iSpriteMember.iOffset.iX=0;
+ iSpriteMember.iOffset.iY=0;
+ iSpriteMember.iInterval=0;
+ User::LeaveIfError(iSprite.AppendMember(iSpriteMember));
+ iHandWritingRecognizer.FinishConstructionL();
+ CleanupStack::PopAndDestroy(); // TCleanupItem(SignalMutex, &iMutex)
+ }
+
+CFbsBitmap* CTstWholeScreenScribbleArea::CreateBitmapL(TInt aHandleOfBitmapToUse, const TSize& aScreenSize, TDisplayMode aDisplayMode)
+ {
+ CFbsBitmap* const bitmap=new(ELeave) CFbsBitmap;
+ CleanupStack::PushL(bitmap);
+ if (aHandleOfBitmapToUse!=0)
+ {
+ User::LeaveIfError(bitmap->Duplicate(aHandleOfBitmapToUse));
+ }
+ else
+ {
+ User::LeaveIfError(bitmap->Create(aScreenSize, aDisplayMode)); // bitmaps are automatically cleared to white when first created
+ }
+ CleanupStack::Pop(); // bitmap
+ return bitmap;
+ }
+
+void CTstWholeScreenScribbleArea::SignalMutex(TAny* aMutex)
+ {
+ STATIC_CAST(RMutex*, aMutex)->Signal();
+ }
+
+// CTstWholeScreenScribbleArea::RHandWritingRecognizer
+
+void CTstWholeScreenScribbleArea::RHandWritingRecognizer::ConstructL(const RWsSprite& aSprite, STstBitmapHandles& aBitmapHandles)
+ {
+ TPckg<STstBitmapHandles> bitmapHandles(aBitmapHandles);
+ TIpcArgs ipcArgs;
+ ipcArgs.Set(EIpcSlot, &bitmapHandles);
+ User::LeaveIfError(RAnim::Construct(aSprite, EAnimTypeHandWritingRecognizer, KNullDesC8, ipcArgs));
+ }
+
+void CTstWholeScreenScribbleArea::RHandWritingRecognizer::FinishConstructionL()
+ {
+ const TInt error=CommandReply(EHandWritingRecognizerCommandFinishConstructionL, KNullDesC8());
+ __ASSERT_ALWAYS(error==KErrNone, Panic(EPanicUnexpectedError1));
+ }
+
+void CTstWholeScreenScribbleArea::RHandWritingRecognizer::RequestNotificationOfStartOfTransaction(TRequestStatus& aRequestStatus)
+ {
+ AsyncCommandReply(aRequestStatus, EHandWritingRecognizerCommandRequestNotificationOfStartOfTransaction, TIpcArgs());
+ }
+
+void CTstWholeScreenScribbleArea::RHandWritingRecognizer::CancelRequestForNotificationOfStartOfTransaction()
+ {
+ const TInt error=CommandReply(EHandWritingRecognizerCommandCancelRequestForNotificationOfStartOfTransaction);
+ __ASSERT_ALWAYS(error==KErrNone, Panic(EPanicUnexpectedError3));
+ }
+
+void CTstWholeScreenScribbleArea::RHandWritingRecognizer::RequestCharacters(TRequestStatus& aRequestStatus, TDes8& aCharacterBuffer, TBool /*aUpperCase*/)
+ {
+ TIpcArgs ipcArgs;
+ ipcArgs.Set(EAsyncIpcSlot, &aCharacterBuffer);
+ AsyncCommandReply(aRequestStatus, EHandWritingRecognizerCommandRequestCharacters, ipcArgs);
+ }
+
+void CTstWholeScreenScribbleArea::RHandWritingRecognizer::CancelRequestForCharacters()
+ {
+ const TInt error=CommandReply(EHandWritingRecognizerCommandCancelRequestForCharacters);
+ __ASSERT_ALWAYS(error==KErrNone, Panic(EPanicUnexpectedError5));
+ }
+
+void CTstWholeScreenScribbleArea::RHandWritingRecognizer::SetUpperCase(TBool aUpperCase)
+ {
+ TPckgBuf<STstParametersForHandWritingRecognizerCommandSetUpperCase> parameters;
+ parameters().iUpperCase=aUpperCase;
+ const TInt error=CommandReply(EHandWritingRecognizerCommandSetUpperCase, parameters);
+ __ASSERT_ALWAYS(error==KErrNone, Panic(EPanicUnexpectedError6));
+ }
+
+// 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()
+ {
+ delete iScribbleWindow;
+ delete iHandlerForStartOfTransaction;
+ delete iHandlerForCharacters;
+ delete iWholeScreenScribbleArea; // must be deleted after iHandlerForStartOfTransaction and iHandlerForCharacters as they both have a reference to it
+ iCoeEnv->ReleaseScreenFont(iStatusFont);
+ STATIC_CAST(CCoeAppUi*, iCoeEnv->AppUi())->RemoveFromStack(this);
+ }
+
+void CTstControl::CancelTransaction()
+ {
+ iScribbleWindow->CancelTransactionAndDrawNow();
+ }
+
+void CTstControl::IsOnHasChangedState()
+ {
+ ChangeSetupAndDrawNow(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 if (aWindowOwningControl==iScribbleWindow)
+ {
+ aEventResponse=CCoeFep::EEventWasConsumed;
+ iScribbleWindow->HandlePointerEventL(aPointerEvent);
+ }
+ else
+ {
+ aEventResponse=CCoeFep::EEventWasNotConsumed;
+ }
+ }
+
+void CTstControl::OfferPointerBufferReadyEventL(CCoeFep::TEventResponse& aEventResponse, const CCoeControl* aWindowOwningControl)
+ {
+ // this function must correctly set aEventResponse *before* calling anything that can leave
+ if (aWindowOwningControl==iScribbleWindow)
+ {
+ aEventResponse=CCoeFep::EEventWasConsumed;
+ iScribbleWindow->HandlePointerBufferReadyL();
+ }
+ else
+ {
+ aEventResponse=CCoeFep::EEventWasNotConsumed;
+ }
+ }
+
+TInt CTstControl::NumberOfAttributes()
+ {
+ return 3;
+ }
+
+TUid CTstControl::AttributeAtIndex(TInt aIndex)
+ {
+ switch (aIndex)
+ {
+ case 0:
+ return TUid::Uid(ETstUpperCaseUid);
+ case 1:
+ return TUid::Uid(ETstWholeScreenUid);
+ case 2:
+ return TUid::Uid(ETstPointerBufferEnabledUid);
+#if defined(_DEBUG)
+ default:
+ Panic(EPanicBadIndex1);
+ break;
+#endif
+ }
+ return KNullUid;
+ }
+
+void CTstControl::WriteAttributeDataToStreamL(TUid aAttributeUid, RWriteStream& aStream) const
+ {
+ switch (aAttributeUid.iUid)
+ {
+ case ETstUpperCaseUid:
+ aStream.WriteUint8L((iFlags&EFlagUpperCase)!=0);
+ break;
+ case ETstWholeScreenUid:
+ aStream.WriteUint8L((iFlags&EFlagWholeScreen)!=0);
+ break;
+ case ETstPointerBufferEnabledUid:
+ aStream.WriteUint8L((iFlags&EFlagPointerBufferEnabled)!=0);
+ break;
+#if defined(_DEBUG)
+ default:
+ Panic(EPanicBadAttributeUid1);
+ break;
+#endif
+ }
+ }
+
+void CTstControl::ReadAttributeDataFromStreamL(TUid aAttributeUid, RReadStream& aStream)
+ {
+ switch (aAttributeUid.iUid)
+ {
+ case ETstUpperCaseUid:
+ ChangeSetupAndDrawNow(SetUpperCase, aStream.ReadUint8L());
+ break;
+ case ETstWholeScreenUid:
+ ChangeSetupAndDrawNow(SetWholeScreen, aStream.ReadUint8L());
+ break;
+ case ETstPointerBufferEnabledUid:
+ ChangeSetupAndDrawNow(SetPointerBufferEnabled, aStream.ReadUint8L());
+ break;
+#if defined(_DEBUG)
+ default:
+ Panic(EPanicBadAttributeUid2);
+ break;
+#endif
+ }
+ }
+
+void CTstControl::WriteAttributeDataToStreamL(TUid aAttributeUid, RWriteStream& aStream, TBool aUpperCase, TBool aWholeScreen, TBool aPointerBufferEnabled)
+ {
+ switch (aAttributeUid.iUid)
+ {
+ case ETstUpperCaseUid:
+ aStream.WriteUint8L(aUpperCase!=EFalse);
+ break;
+ case ETstWholeScreenUid:
+ aStream.WriteUint8L(aWholeScreen!=EFalse);
+ break;
+ case ETstPointerBufferEnabledUid:
+ aStream.WriteUint8L(aPointerBufferEnabled!=EFalse);
+ break;
+#if defined(_DEBUG)
+ default:
+ Panic(EPanicBadAttributeUid3);
+ break;
+#endif
+ }
+ }
+
+void CTstControl::ReadAttributeDataFromStreamL(TUid aAttributeUid, RReadStream& aStream, TBool& aUpperCase, TBool& aWholeScreen, TBool& aPointerBufferEnabled)
+ {
+ switch (aAttributeUid.iUid)
+ {
+ case ETstUpperCaseUid:
+ aUpperCase=aStream.ReadUint8L();
+ break;
+ case ETstWholeScreenUid:
+ aWholeScreen=aStream.ReadUint8L();
+ break;
+ case ETstPointerBufferEnabledUid:
+ aPointerBufferEnabled=aStream.ReadUint8L();
+ break;
+#if defined(_DEBUG)
+ default:
+ Panic(EPanicBadAttributeUid4);
+ break;
+#endif
+ }
+ }
+
+void CTstControl::HandleGainingForeground()
+ {
+ DrawableWindow()->MoveToGroup(iCoeEnv->WsSession().GetFocusWindowGroup()); // ignore the error returned
+ ChangeSetupAndDrawNow(SetForeground, ETrue);
+ }
+
+void CTstControl::HandleLosingForeground()
+ {
+ ChangeSetupAndDrawNow(SetForeground, EFalse);
+ }
+
+void CTstControl::HandleChangeInFocus()
+ {
+ ChangeSetupAndDrawNow(SetInputCapabilities);
+ }
+
+void CTstControl::HandleDestructionOfFocusedItem()
+ {
+ if (!IsBeingDestroyed())
+ {
+ ChangeSetupAndDrawNow(SetInputCapabilities);
+ }
+ }
+
+CTstControl::CTstControl(CTstFep& aFep)
+ :iFep(aFep),
+ iFlags(0),
+ iInputCapabilities(TCoeInputCapabilities::ENone),
+ iScribbleWindow(NULL),
+ iWholeScreenScribbleArea(NULL),
+ iHandlerForStartOfTransaction(NULL),
+ iHandlerForCharacters(NULL),
+ iStatusFont(NULL),
+ iPositionOnWindowBeingDragged(0, 0)
+ {
+ }
+
+void CTstControl::ConstructL()
+ {
+ RWindowGroup& windowGroup=iCoeEnv->RootWin();
+ CreateWindowL();
+ EnableDragEvents();
+ ClaimPointerGrab();
+ SetNonFocusing();
+ RDrawableWindow& window=*DrawableWindow();
+ window.SetOrdinalPosition(0, ECoeWinPriorityFep);
+ window.SetShadowHeight(3);
+ iScribbleWindow=CTstScribbleWindow::NewL(iFep, window);
+ RWsSession& windowServerSession=iCoeEnv->WsSession();
+ CWsScreenDevice& screenDevice=*iCoeEnv->ScreenDevice();
+ const TSize screenSize=screenDevice.SizeInPixels();
+ iWholeScreenScribbleArea=CTstWholeScreenScribbleArea::NewL(windowServerSession, windowGroup, screenSize, screenDevice.DisplayMode(), KLitDllNameOfWindowServerPlugIn);
+ iHandlerForStartOfTransaction=CHandlerForStartOfTransaction::NewL(*iWholeScreenScribbleArea, *iCoeEnv);
+ const TBool foreground=(windowGroup.Identifier()==windowServerSession.GetFocusWindowGroup());
+ iHandlerForCharacters=CHandlerForCharacters::NewL(*iWholeScreenScribbleArea, iFep, foreground);
+ iStatusFont=iCoeEnv->CreateScreenFontL(TFontSpec(KLitStatusFontTypefaceName, 120));
+ const TInt statusFontHeightInPixels=iStatusFont->HeightInPixels();
+ const TSize size(320, 1+EHeightOfScribbleWindow+EGapAboveTopLine+statusFontHeightInPixels+(4*(EGapBetweenEachLine+statusFontHeightInPixels))+EGapBelowBottomLine+1);
+ SetExtent(TPoint(screenSize.iWidth-(size.iWidth+10), screenSize.iHeight-(size.iHeight+10)), size);
+ iScribbleWindow->SetExtent(TPoint(1, 1), TSize(size.iWidth-2, EHeightOfScribbleWindow));
+ STATIC_CAST(CCoeAppUi*, iCoeEnv->AppUi())->AddToStackL(this, ECoeStackPriorityFep, ECoeStackFlagRefusesFocus|ECoeStackFlagSharable);
+ __ASSERT_DEBUG((iFlags&EFlagActuallyWholeScreen)==0, Panic(EPanicLowLevelFlagsDoNotReflectStateOfRemoteObjects));
+ ChangeSetupAndDrawNow(SetForeground, foreground);
+ ChangeSetupAndDrawNow(SetFocus, EFalse);
+ ChangeSetupAndDrawNow(SetUpperCase, EFalse);
+ ChangeSetupAndDrawNow(SetWholeScreen, ETrue);
+ ChangeSetupAndDrawNow(SetPointerBufferEnabled, ETrue);
+ ChangeSetupAndDrawNow(SetInputCapabilities);
+ }
+
+void CTstControl::SetForeground(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter)
+ {
+ SetFlag(aControl, aChangeWasMade, aParameter, EFlagForeground);
+ if (aChangeWasMade)
+ {
+ aControl.iHandlerForCharacters->SetForeground(aParameter); // background TFEP2 instances must not have a request for characters outstanding, as the corresponding server-side object may intercept raw events from the rightful TFEP2 instance in the foreground, hence the need for this function
+ if (aParameter)
+ {
+ aControl.iHandlerForCharacters->SetUpperCase(aControl.iFlags&EFlagUpperCase);
+ aControl.DoSetWholeScreen(aControl.iFlags&EFlagWholeScreen);
+ aControl.iScribbleWindow->SetPointerBufferEnabled(aControl.iFlags&EFlagPointerBufferEnabled);
+ }
+ }
+ }
+
+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();
+ aControl.iScribbleWindow->MakeVisible(!aParameter);
+ aChangeWasMade=ETrue;
+ }
+ }
+
+void CTstControl::SetUpperCase(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter)
+ {
+ SetFlag(aControl, aChangeWasMade, aParameter, EFlagUpperCase);
+ if (aChangeWasMade && (aControl.iFlags&EFlagForeground))
+ {
+ aControl.iHandlerForCharacters->SetUpperCase(aParameter);
+ }
+ }
+
+void CTstControl::SetWholeScreen(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter)
+ {
+ SetFlag(aControl, aChangeWasMade, aParameter, EFlagWholeScreen);
+ if (aChangeWasMade && (aControl.iFlags&EFlagForeground))
+ {
+ aControl.DoSetWholeScreen(aParameter);
+ }
+ }
+
+void CTstControl::SetPointerBufferEnabled(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter)
+ {
+ SetFlag(aControl, aChangeWasMade, aParameter, EFlagPointerBufferEnabled);
+ if (aChangeWasMade && (aControl.iFlags&EFlagForeground))
+ {
+ aControl.iScribbleWindow->SetPointerBufferEnabled(aParameter);
+ }
+ }
+
+void CTstControl::SetInputCapabilities(CTstControl& aControl, TBool& aChangeWasMade, TInt)
+ {
+ aChangeWasMade=EFalse;
+ if (!aControl.IsFocused())
+ {
+ const TCoeInputCapabilities inputCapabilities(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::DoSetWholeScreen(TBool aWholeScreen)
+ {
+ if (!aWholeScreen!=!(iFlags&EFlagActuallyWholeScreen)) // fold non-zero values on both sides before comparing for inequality
+ {
+ TInt windowAdjustmentY;
+ TInt scribbleWindowPositionY;
+ if (aWholeScreen)
+ {
+ windowAdjustmentY=EHeightOfScribbleWindow;
+ scribbleWindowPositionY=-EHeightOfScribbleWindow;
+ iFlags|=EFlagActuallyWholeScreen;
+ }
+ else
+ {
+ windowAdjustmentY=-EHeightOfScribbleWindow;
+ scribbleWindowPositionY=1;
+ iFlags&=~EFlagActuallyWholeScreen;
+ }
+ iHandlerForCharacters->SetWholeScreen(aWholeScreen);
+ iScribbleWindow->SetPosition(TPoint(1, scribbleWindowPositionY));
+ 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);
+ }
+ }
+
+void CTstControl::ChangeSetupAndDrawNow(FChangeFunction aChangeFunction, TInt aParameter)
+ {
+ TBool needToDraw=EFalse;
+ {
+ TBool changeWasMade;
+ iScribbleWindow->CancelTransaction(changeWasMade);
+ if (changeWasMade)
+ {
+ needToDraw=ETrue;
+ }
+ }
+ if (aChangeFunction!=NULL)
+ {
+ TBool changeWasMade;
+ (*aChangeFunction)(*this, changeWasMade, aParameter);
+ if (changeWasMade)
+ {
+ needToDraw=ETrue;
+ }
+ }
+ const TBool isOn=iFep.IsOn();
+ iHandlerForCharacters->SetIsOn(isOn);
+ const TBool shouldBeVisible=(isOn && (iFlags&EFlagForeground));
+ if (!IsVisible()!=!shouldBeVisible) // fold non-zero values on both sides before comparing for inequality
+ {
+ MakeVisible(shouldBeVisible);
+ needToDraw=EFalse;
+ }
+ if (needToDraw)
+ {
+ DrawNow();
+ }
+ }
+
+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;
+ if ((aKeyEvent.iModifiers&EModifierRightShift) && !isFocused)
+ {
+ switch (keyCodeInUpperCase)
+ {
+ case 'F':
+ ChangeSetupAndDrawNow(SetFocus, ETrue);
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
+ case 'C':
+ ChangeSetupAndDrawNow(SetUpperCase, !(iFlags&EFlagUpperCase));
+ iFep.WriteAttributeDataAndBroadcastL(TUid::Uid(ETstUpperCaseUid));
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
+ case 'W':
+ ChangeSetupAndDrawNow(SetWholeScreen, !(iFlags&EFlagWholeScreen));
+ iFep.WriteAttributeDataAndBroadcastL(TUid::Uid(ETstWholeScreenUid));
+ FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
+ case 'P':
+ ChangeSetupAndDrawNow(SetPointerBufferEnabled, !(iFlags&EFlagPointerBufferEnabled));
+ iFep.WriteAttributeDataAndBroadcastL(TUid::Uid(ETstPointerBufferEnabledUid));
+ 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()+1;
+ 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(), EMaximumLengthOfDisplayOfContextInformation+1);
+ {
+ 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
+ }
+ }
+ }
+ switch (keyCodeInUpperCase)
+ {
+ case EKeyEnter:
+ case EKeyEscape:
+ if (isFocused)
+ {
+ ChangeSetupAndDrawNow(SetFocus, EFalse);
+ 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(EPanicBadKeyCode2);
+ 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
+ }
+ break;
+ default:
+ if (isFocused)
+ {
+ 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:
+ case TPointerEvent::EDrag:
+ if (iFlags&EFlagWindowIsBeingDragged)
+ {
+ SetPosition(aPointerEvent.iParentPosition-iPositionOnWindowBeingDragged);
+ }
+ else
+ {
+ iFlags|=EFlagWindowIsBeingDragged;
+ iPositionOnWindowBeingDragged=aPointerEvent.iPosition;
+ }
+ break;
+ case TPointerEvent::EButton1Up:
+ iFlags&=~EFlagWindowIsBeingDragged;
+ break;
+#if defined(__GCC32__)
+ default:
+ break;
+#endif
+ }
+ }
+
+TInt CTstControl::CountComponentControls() const
+ {
+ return 1;
+ }
+
+CCoeControl* CTstControl::ComponentControl(TInt aIndex) const
+ {
+ switch (aIndex)
+ {
+ case 0:
+ return iScribbleWindow;
+ default:
+#if defined(_DEBUG)
+ Panic(EPanicBadIndex2);
+#endif
+ return NULL;
+ }
+ }
+
+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())
+ {
+ // 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);
+ if (~iFlags&EFlagWholeScreen)
+ {
+ temp.iTl.iY+=EHeightOfScribbleWindow;
+ }
+ temp.iBr.iY=temp.iTl.iY;
+ graphicsContext.SetBrushColor(KRgbGray);
+ graphicsContext.UseFont(iStatusFont);
+ TBuf<200> textToDisplay;
+ const TInt statusFontHeightInPixels=iStatusFont->HeightInPixels();
+ const TInt statusFontAscentInPixels=iStatusFont->AscentInPixels();
+ textToDisplay=KLitUpperCaseColonSpace;
+ textToDisplay.Append((iFlags&EFlagUpperCase)? KLitOn(): KLitOff());
+ temp.iBr.iY+=EGapAboveTopLine+statusFontHeightInPixels+EGapBetweenEachLine;
+ graphicsContext.DrawText(textToDisplay, temp, EGapAboveTopLine+statusFontAscentInPixels, CGraphicsContext::ELeft, EGapLeftOfEachLine);
+ textToDisplay=KLitScribbleAreaColonSpace;
+ textToDisplay.Append((iFlags&EFlagWholeScreen)? KLitWholeScreen(): KLitWindow());
+ temp.iTl.iY=temp.iBr.iY;
+ temp.iBr.iY+=statusFontHeightInPixels+EGapBetweenEachLine;
+ graphicsContext.DrawText(textToDisplay, temp, statusFontAscentInPixels, CGraphicsContext::ELeft, EGapLeftOfEachLine);
+ textToDisplay=KLitPointerBufferColonSpace;
+ textToDisplay.Append((iFlags&EFlagPointerBufferEnabled)? KLitEnabled(): KLitDisabled());
+ temp.iTl.iY=temp.iBr.iY;
+ temp.iBr.iY+=statusFontHeightInPixels+EGapBetweenEachLine;
+ 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+EGapBetweenEachLine;
+ 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;
+ }
+ 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+EGapBelowBottomLine, Panic(EPanicBadHeight));
+ graphicsContext.DrawText(textToDisplay, temp, statusFontAscentInPixels, CGraphicsContext::ELeft, EGapLeftOfEachLine);
+ graphicsContext.DiscardFont();
+ }
+ }
+
+// CTstControl::CHandlerForStartOfTransaction
+
+CTstControl::CHandlerForStartOfTransaction* CTstControl::CHandlerForStartOfTransaction::NewL(CTstWholeScreenScribbleArea& aWholeScreenScribbleArea, CCoeEnv& aConeEnvironment)
+ {
+ return new(ELeave) CHandlerForStartOfTransaction(aWholeScreenScribbleArea, aConeEnvironment);
+ }
+
+CTstControl::CHandlerForStartOfTransaction::~CHandlerForStartOfTransaction()
+ {
+ Cancel();
+ }
+
+CTstControl::CHandlerForStartOfTransaction::CHandlerForStartOfTransaction(CTstWholeScreenScribbleArea& aWholeScreenScribbleArea, CCoeEnv& aConeEnvironment)
+ :CActive(EActivePriorityWsEvents),
+ iWholeScreenScribbleArea(aWholeScreenScribbleArea),
+ iConeEnvironment(aConeEnvironment)
+ {
+ CActiveScheduler::Add(this);
+ RequestNotificationOfStartOfTransaction();
+ }
+
+void CTstControl::CHandlerForStartOfTransaction::RequestNotificationOfStartOfTransaction()
+ {
+ iWholeScreenScribbleArea.RequestNotificationOfStartOfTransaction(iStatus);
+ SetActive();
+ }
+
+void CTstControl::CHandlerForStartOfTransaction::DoCancel()
+ {
+ iWholeScreenScribbleArea.CancelRequestForNotificationOfStartOfTransaction();
+ }
+
+void CTstControl::CHandlerForStartOfTransaction::RunL()
+ {
+ RequestNotificationOfStartOfTransaction();
+ iConeEnvironment.ForEachFepObserverCall(FepObserverHandleStartOfTransactionL); // called at the end of handling this event as it may launch a waiting dialog
+ }
+
+// CTstControl::CHandlerForCharacters
+
+CTstControl::CHandlerForCharacters* CTstControl::CHandlerForCharacters::NewL(CTstWholeScreenScribbleArea& aWholeScreenScribbleArea, CTstFep& aFep, TBool aForeground)
+ {
+ return new(ELeave) CHandlerForCharacters(aWholeScreenScribbleArea, aFep, aForeground);
+ }
+
+CTstControl::CHandlerForCharacters::~CHandlerForCharacters()
+ {
+ Cancel();
+ }
+
+void CTstControl::CHandlerForCharacters::SetUpperCase(TBool aUpperCase)
+ {
+ if (!aUpperCase!=!(iFlags&EFlagUpperCase)) // fold non-zero values on both sides before comparing for inequality
+ {
+ iFlags^=EFlagUpperCase;
+ if (IsActive())
+ {
+ iWholeScreenScribbleArea.SetUpperCase(aUpperCase);
+ }
+ }
+ __ASSERT_DEBUG(!(iFlags&EFlagUpperCase)==!aUpperCase, Panic(EPanicInconsistentUpperCaseSetting)); // fold non-zero values on both sides before comparing for equality
+ }
+
+CTstControl::CHandlerForCharacters::CHandlerForCharacters(CTstWholeScreenScribbleArea& aWholeScreenScribbleArea, CTstFep& aFep, TBool aForeground)
+ :CActive(EActivePriorityWsEvents),
+ iWholeScreenScribbleArea(aWholeScreenScribbleArea),
+ iFep(aFep),
+ iFlags(aForeground? EFlagForeground: 0)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+void CTstControl::CHandlerForCharacters::SetFlagAffectingWhetherActive(TUint aFlagAffectingWhetherActive, TBool aSetting)
+ {
+ const TUint flagsAffectingWhetherActive=(EFlagWholeScreen|EFlagIsOn|EFlagForeground);
+ __ASSERT_DEBUG(aFlagAffectingWhetherActive&flagsAffectingWhetherActive, Panic(EPanicBadFlagAffectingWhetherActive));
+ const TUint oldFlags=iFlags;
+ if (aSetting)
+ {
+ iFlags|=aFlagAffectingWhetherActive;
+ }
+ else
+ {
+ iFlags&=~aFlagAffectingWhetherActive;
+ }
+ if ((iFlags^oldFlags)&flagsAffectingWhetherActive)
+ {
+ if ((iFlags&flagsAffectingWhetherActive)==flagsAffectingWhetherActive)
+ {
+ RequestCharacters();
+ }
+ else if ((oldFlags&flagsAffectingWhetherActive)==flagsAffectingWhetherActive)
+ {
+ Cancel();
+ }
+ }
+ }
+
+void CTstControl::CHandlerForCharacters::RequestCharacters()
+ {
+ iWholeScreenScribbleArea.RequestCharacters(iStatus, iCharacterBuffer, iFlags&EFlagUpperCase);
+ SetActive();
+ }
+
+TInt CTstControl::CHandlerForCharacters::NumberOfCharactersInBuffer(const CBase* aCharacterBuffer)
+ {
+ const TDesC8& characterBuffer=*REINTERPRET_CAST(const TDesC8*, aCharacterBuffer);
+ return characterBuffer.Length()/sizeof(TUint);
+ }
+
+const TAny* CTstControl::CHandlerForCharacters::CharacterInBuffer(const CBase* aCharacterBuffer, TInt aIndex)
+ {
+ const TDesC8& characterBuffer=*REINTERPRET_CAST(const TDesC8*, aCharacterBuffer);
+ return characterBuffer.Ptr()+(aIndex*sizeof(TUint));
+ }
+
+void CTstControl::CHandlerForCharacters::DoCancel()
+ {
+ iWholeScreenScribbleArea.CancelRequestForCharacters();
+ }
+
+void CTstControl::CHandlerForCharacters::RunL()
+ {
+ TBuf8<EMaximumLengthOfCharacterBuffer> characterBuffer=iCharacterBuffer;
+ RequestCharacters(); // calling RequestCharacters may complete immediately (thus trashing iCharacterBuffer), hence why iCharacterBuffer was copied to a temporary buffer first
+ iFep.SimulateKeyEventsL(TArray<TUint>(NumberOfCharactersInBuffer, CharacterInBuffer, REINTERPRET_CAST(const CBase*, &characterBuffer)));
+ }
+
+// 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* aWindowOwningControl)
+ {
+ iControl->OfferPointerBufferReadyEventL(aEventResponse, aWindowOwningControl);
+ }
+
+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()
+ :iFlags(0)
+ {
+ }
+
+TUint CTstSettingsDialog::CheckBoxStateAsFlag(TInt aControlId, TUint aFlag) const
+ {
+ switch (STATIC_CAST(CEikCheckBox*, Control(aControlId))->State())
+ {
+ case CEikButtonBase::EClear:
+ return 0;
+ case CEikButtonBase::ESet:
+ return aFlag;
+ case CEikButtonBase::EIndeterminate:
+ default:
+#if defined(_DEBUG)
+ Panic(EPanicBadCheckBoxState);
+#endif
+ return 0;
+ }
+ }
+
+void CTstSettingsDialog::SetCheckBoxState(TInt aControlId, TUint aFlag)
+ {
+ STATIC_CAST(CEikCheckBox*, Control(aControlId))->SetState(iFlags&aFlag? CEikButtonBase::ESet: CEikButtonBase::EClear);
+ }
+
+TBool CTstSettingsDialog::OkToExitL(TInt aButtonId)
+ {
+ __ASSERT_ALWAYS(aButtonId==EEikBidOk, Panic(EPanicUnexpectedButtonId));
+ iFlags=CheckBoxStateAsFlag(EControlIdUpperCase, EFlagUpperCase)|
+ CheckBoxStateAsFlag(EControlIdWholeScreen, EFlagWholeScreen)|
+ CheckBoxStateAsFlag(EControlIdPointerBufferEnabled, EFlagPointerBufferEnabled);
+ TFixedArray<TUid, 3> attributeUids;
+ __ASSERT_DEBUG(NumberOfAttributes()==3, Panic(EPanicBadNumberOfAttributes));
+ attributeUids[0].iUid=AttributeAtIndex(0).iUid;
+ attributeUids[1].iUid=AttributeAtIndex(1).iUid;
+ attributeUids[2].iUid=AttributeAtIndex(2).iUid;
+ WriteAttributeDataAndBroadcastL(*iCoeEnv, attributeUids.Array());
+ return ETrue;
+ }
+
+void CTstSettingsDialog::PreLayoutDynInitL()
+ {
+ ReadAllAttributesL(*iCoeEnv);
+ SetCheckBoxState(EControlIdUpperCase, EFlagUpperCase);
+ SetCheckBoxState(EControlIdWholeScreen, EFlagWholeScreen);
+ SetCheckBoxState(EControlIdPointerBufferEnabled, EFlagPointerBufferEnabled);
+ }
+
+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, iFlags&EFlagUpperCase, iFlags&EFlagWholeScreen, iFlags&EFlagPointerBufferEnabled);
+ }
+
+void CTstSettingsDialog::ReadAttributeDataFromStreamL(TUid aAttributeUid, RReadStream& aStream)
+ {
+ TBool upperCase;
+ TBool wholeScreen;
+ TBool pointerBufferEnabled;
+ CTstControl::ReadAttributeDataFromStreamL(aAttributeUid, aStream, upperCase, wholeScreen, pointerBufferEnabled);
+ iFlags=0;
+ if (upperCase)
+ {
+ iFlags|=EFlagUpperCase;
+ }
+ if (wholeScreen)
+ {
+ iFlags|=EFlagWholeScreen;
+ }
+ if (pointerBufferEnabled)
+ {
+ iFlags|=EFlagPointerBufferEnabled;
+ }
+ }
+