fep/frontendprocessor/source/FEPBASE.CPP
changeset 0 eb1f2e154e89
child 20 ebd48d2de13c
equal deleted inserted replaced
-1:000000000000 0:eb1f2e154e89
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <e32std.h>
       
    17 #include <e32base.h>
       
    18 #include <centralrepository.h>
       
    19 #include <w32std.h>
       
    20 #include <coemain.h>
       
    21 #include <coedef.h>
       
    22 #include "coedatastorage.h"
       
    23 #include <fepbase.h>
       
    24 #include <fepitfr.h>
       
    25 #include <fepbpanic.h>
       
    26 #include "FEPBPRIV.H"
       
    27 #include <graphics/cone/coedefkeys.h>
       
    28 
       
    29 inline TBool IsSurrogate(TText a) { return 0xD800 == (a & 0xF800); }
       
    30 inline TBool IsHighSurrogate(TText a) { return 0xD800 == (a & 0xFC00); }
       
    31 inline TBool IsLowSurrogate(TText a) { return 0xDC00 == (a & 0xFC00); }
       
    32 inline TChar JoinSurrogates(TText aHigh, TText aLow)
       
    33 	{
       
    34 	return ((aHigh - 0xd7f7) << 10) + aLow;
       
    35 	}
       
    36 
       
    37 LOCAL_C void Panic(TFepBasePanic aPanic)
       
    38 	{
       
    39 	User::Panic(KLitFepBasePanicText, aPanic);
       
    40 	}
       
    41 
       
    42 enum { EUndefinedEventResponse=100 };
       
    43 
       
    44 enum TFlags
       
    45 	{
       
    46 	EFlagOnState			=0x00000001,
       
    47 	EFlagIsHandlingKeyEvent	=0x00000002,
       
    48 	EFlagNoDownUpFilter		=0x00000004
       
    49 	};
       
    50 
       
    51 // internal class definitions
       
    52 
       
    53 struct CCoeFep::SKeyEvent
       
    54 	{
       
    55 	TEventCode iEventCode;
       
    56 	TKeyEvent iKeyEvent;
       
    57 	TKeyResponse iKeyResponse;
       
    58 	};
       
    59 
       
    60 class CCoeFep::CHighPriorityActive : public CActive
       
    61 	{
       
    62 public:
       
    63 	static CHighPriorityActive* NewL(CCoeEnv& aConeEnvironment);
       
    64 	virtual ~CHighPriorityActive();
       
    65 	void MakeDeferredFunctionCall(MDeferredFunctionCall& aDeferredFunctionCall);
       
    66 	void SimulateKeyEventL(const TKeyEvent& aKeyEvent);
       
    67 	inline TBool IsSimulatingKeyEvent() const {return (iFlags&EFlagIsSimulatingKeyEvent);}
       
    68 	void SendKeyEventToApplicationNowL(TEventCode aEventCode, const TKeyEvent& aKeyEvent);
       
    69 	TBool MustBeAndNowWillBeDestroyedLater();
       
    70 private:
       
    71 	enum
       
    72 		{
       
    73 		EFlagIsSimulatingKeyEvent		=0x00000001,
       
    74 		EFlagOwnsSelf					=0x00000002,
       
    75 		EFlagRecursionLevelIncremented	=0x00000004
       
    76 		};
       
    77 	struct SStackedFlags
       
    78 		{
       
    79 		inline SStackedFlags(TUint& aFlags) :iFlags(aFlags), iOldFlags(aFlags) {}
       
    80 		TUint& iFlags;
       
    81 		const TUint iOldFlags;
       
    82 		};
       
    83 	class CFlagClearer : public CActive
       
    84 		{
       
    85 	public:
       
    86 		static CFlagClearer* NewL();
       
    87 		virtual ~CFlagClearer();
       
    88 		void TurnOffFlagIsSimulatingKeyEventDeferred(SStackedFlags& aStackedFlags);
       
    89 	private:
       
    90 		CFlagClearer();
       
    91 		// from CActive
       
    92 		virtual void DoCancel();
       
    93 		virtual void RunL();
       
    94 	private:
       
    95 		SStackedFlags* iStackedFlags;
       
    96 		};
       
    97 private:
       
    98 	CHighPriorityActive(CCoeEnv& aConeEnvironment);
       
    99 	void ConstructL();
       
   100 	void MakeReadyToRun();
       
   101 	void DoSendKeyEventToApplicationNowL(TEventCode aEventCode, const TKeyEvent& aKeyEvent);
       
   102 	static void DecrementRecursionLevelAndDestroySelfIfZeroAndOwnsSelf(TAny* aThis);
       
   103 	static void CancelFlagClearer(TAny* aFlagClearer);
       
   104 	static void TurnOffFlagIsSimulatingKeyEvent(TAny* aStackedFlags);
       
   105 	static void DoTurnOffFlagIsSimulatingKeyEvent(SStackedFlags& aStackedFlags);
       
   106 	// from CActive
       
   107 	virtual void DoCancel();
       
   108 	virtual void RunL();
       
   109 	virtual TInt RunError(TInt aError);
       
   110 private:
       
   111 	CCoeEnv& iConeEnvironment;
       
   112 	TUint iFlags;
       
   113 	MDeferredFunctionCall* iDeferredFunctionCall;
       
   114 	RArray<TKeyEvent> iArrayOfKeyEvents;
       
   115 	CFlagClearer* iFlagClearer;
       
   116 	TInt iRecursionLevel;
       
   117 private:
       
   118 	friend class CFlagClearer;
       
   119 	};
       
   120 
       
   121 class CCoeFep::CLowPriorityActive : public CActive
       
   122 	{
       
   123 public:
       
   124 	static CLowPriorityActive* NewL(CHighPriorityActive& aHighPriorityActive);
       
   125 	virtual ~CLowPriorityActive();
       
   126 	void SendKeyEventToApplicationDeferred(TEventCode aEventCode, const TKeyEvent& aKeyEvent);
       
   127 private:
       
   128 	CLowPriorityActive(CHighPriorityActive& aHighPriorityActive);
       
   129 	// from CActive
       
   130 	virtual void DoCancel();
       
   131 	virtual void RunL();
       
   132 private:
       
   133 	CHighPriorityActive& iHighPriorityActive;
       
   134 	TEventCode iEventCode;
       
   135 	TKeyEvent iKeyEvent;
       
   136 	};
       
   137 
       
   138 
       
   139 NONSHARABLE_CLASS(COnStateTracker) : public CActive
       
   140 	{
       
   141 public:
       
   142 	static COnStateTracker* NewL(CCoeFep& aFep);
       
   143 	virtual ~COnStateTracker();
       
   144 private:
       
   145 	COnStateTracker(CCoeFep& aFep);
       
   146 	void ConstructL();
       
   147 	void Queue();
       
   148 	void SetOnState();
       
   149 	// from CActive
       
   150 	virtual void DoCancel();
       
   151 	virtual void RunL();
       
   152 private:
       
   153 	CCoeFep& iFep;
       
   154 	CRepository* iRepository;
       
   155 	};
       
   156 
       
   157 // non-class-member functions
       
   158 
       
   159 EXPORT_C void FepObserverHandleStartOfTransactionL(MCoeFepObserver& aFepObserver)
       
   160 	{
       
   161 	aFepObserver.HandleStartOfTransactionL();
       
   162 	}
       
   163 
       
   164 LOCAL_C void FepObserverHandleCompletionOfTransactionL(MCoeFepObserver& aFepObserver)
       
   165 	{
       
   166 	aFepObserver.HandleCompletionOfTransactionL();
       
   167 	}
       
   168 
       
   169 // CCoeFep::CLowPriorityActive
       
   170 
       
   171 CCoeFep::CLowPriorityActive* CCoeFep::CLowPriorityActive::NewL(CHighPriorityActive& aHighPriorityActive)
       
   172 	{
       
   173 	return new(ELeave) CLowPriorityActive(aHighPriorityActive);
       
   174 	}
       
   175 
       
   176 CCoeFep::CLowPriorityActive::~CLowPriorityActive()
       
   177 	{
       
   178 	Cancel();
       
   179 	}
       
   180 
       
   181 void CCoeFep::CLowPriorityActive::SendKeyEventToApplicationDeferred(TEventCode aEventCode, const TKeyEvent& aKeyEvent)
       
   182 	{
       
   183 	Cancel();
       
   184 	iEventCode=aEventCode;
       
   185 	iKeyEvent=aKeyEvent;
       
   186 	TRequestStatus* requestStatus=&iStatus;
       
   187 	User::RequestComplete(requestStatus, KErrNone);
       
   188 	SetActive();
       
   189 	}
       
   190 
       
   191 CCoeFep::CLowPriorityActive::CLowPriorityActive(CHighPriorityActive& aHighPriorityActive)
       
   192 	:CActive(EActivePriorityWsEvents-1), // the priority of CLowPriorityActive objects just needs to be less than the priority with which key-events are handled
       
   193 	 iHighPriorityActive(aHighPriorityActive)
       
   194 	{
       
   195 	CActiveScheduler::Add(this);
       
   196 	}
       
   197 
       
   198 void CCoeFep::CLowPriorityActive::DoCancel()
       
   199 	{
       
   200 	}
       
   201 
       
   202 void CCoeFep::CLowPriorityActive::RunL()
       
   203 	{
       
   204 	iHighPriorityActive.SendKeyEventToApplicationNowL(iEventCode, iKeyEvent);
       
   205 	}
       
   206 
       
   207 
       
   208 
       
   209 // COnStateTracker
       
   210 
       
   211 COnStateTracker* COnStateTracker::NewL(CCoeFep& aFep)
       
   212 	{ // static
       
   213 	COnStateTracker* const self=new(ELeave) COnStateTracker(aFep);
       
   214 	CleanupStack::PushL(self);
       
   215 	self->ConstructL();
       
   216 	CleanupStack::Pop(self);
       
   217 	return self;
       
   218 	}
       
   219 
       
   220 COnStateTracker::~COnStateTracker()
       
   221 	{
       
   222 	Cancel();
       
   223 	delete iRepository;
       
   224 	}
       
   225 
       
   226 COnStateTracker::COnStateTracker(CCoeFep& aFep)
       
   227 	:CActive(EActivePriorityWsEvents+30),
       
   228 	 iFep(aFep)
       
   229 	{
       
   230 	CActiveScheduler::Add(this);
       
   231 	}
       
   232 
       
   233 void COnStateTracker::ConstructL()
       
   234 	{
       
   235 	iRepository=CRepository::NewL(TUid::Uid(KUidFepFrameworkRepository));
       
   236 
       
   237 	// We'd like to call "Queue" and "SetOnState" here, but we can't call SetOnState from here as it involves the CCoeFep-derived object's implementation of IsOnHasChangedState being called inside the CCoeFep::BaseConstructL, which probably happens at the start of its contruction routine, before it's ready for its implementation of IsOnHasChangedState to be called. So instead we just make ourselves ready to run so that our RunL gets called as soon as it can
       
   238 	TRequestStatus* requestStatus=&iStatus;
       
   239 	User::RequestComplete(requestStatus, KErrNone);
       
   240 	SetActive();
       
   241 	}
       
   242 
       
   243 void COnStateTracker::Queue()
       
   244 	{
       
   245 #if defined(_DEBUG)
       
   246 	const TInt error=
       
   247 #endif
       
   248 	iRepository->NotifyRequest(ERepositoryKeyMask_OnState, ERepositoryKeyMask_OnState, iStatus);
       
   249 	__ASSERT_DEBUG(error==KErrNone, Panic(EPanicUnexpectedError2));
       
   250 	SetActive();
       
   251 	}
       
   252 
       
   253 void COnStateTracker::SetOnState()
       
   254 	{
       
   255 	TBool onState=EFalse;
       
   256 	CFepGenericGlobalSettings::ReadOnState(*iRepository, onState);
       
   257 	iFep.SetOnState(onState);
       
   258 	}
       
   259 
       
   260 void COnStateTracker::DoCancel()
       
   261 	{
       
   262 	iRepository->NotifyCancel(ERepositoryKeyMask_OnState, ERepositoryKeyMask_OnState);
       
   263 	}
       
   264 
       
   265 void COnStateTracker::RunL()
       
   266 	{
       
   267 	const TInt error=iStatus.Int();
       
   268 	Queue();
       
   269 	User::LeaveIfError(error);
       
   270 	SetOnState();
       
   271 	}
       
   272 
       
   273 
       
   274 // MCoeFepObserver
       
   275 
       
   276 /** Handles the start of a FEP transaction. 
       
   277 
       
   278 The implementation of this function might move focus to an existing edit window, 
       
   279 or might launch a new dialog (if the dialog should appear as soon 
       
   280 as the user starts composing their text in the FEP rather than when the text 
       
   281 contained in the FEP is committed to it).
       
   282 
       
   283 This function should be called by the FEP when it receives the first event 
       
   284 which begins a FEP transaction. It should be called after using CoeFep::MakeDeferredFunctionCall() 
       
   285 to handle the event.
       
   286 
       
   287 The FEP calls this function indirectly by calling CCoeEnv::ForEachFepObserverCall() 
       
   288 passing in FepObserverHandleStartOfTransactionL. Internally, this calls HandleStartOfTransactionL() 
       
   289 for each MCoeFepObserver object that has been registered with the control 
       
   290 environment by calling CCoeEnv::AddFepObserverL().
       
   291 
       
   292 @see CCoeFep::MakeDeferredFunctionCall() */
       
   293 EXPORT_C void MCoeFepObserver::HandleStartOfTransactionL()
       
   294 	{
       
   295 	}
       
   296 
       
   297 /** If an application needs to get more information about a FEP transaction than 
       
   298 is provided by the FEP framework, (for example, a Japanese FEP may want the 
       
   299 pronunciation of the transaction's text as well as the text itself), then 
       
   300 it should override this function to retrieve the information it wants from the 
       
   301 FEP.
       
   302 
       
   303 This assumes that the application knows which concrete FEP is above it so 
       
   304 that it can call the specialised functions in that FEP. An application can 
       
   305 safely do this by calling CCoeEnv::Fep() to get the address of the current 
       
   306 FEP (this is NULL if there is no FEP above it) and downcasting this address 
       
   307 to the specific derived class of the FEP it is expecting, on condition that 
       
   308 the CCoeEnv::FepUid() function returns the UID of the FEP it is expecting.
       
   309 
       
   310 This function is called by the FEP framework. If the FEP is doing inline editing, 
       
   311 HandleCompletionOfTransactionL() is called inside MCoeFepAwareTextEditor's 
       
   312 CommitFepInlineEditL(). If it isn't doing inline editing, HandleCompletionOfTransactionL() 
       
   313 is called (inside an active object) after the key events generated by one 
       
   314 or more calls to CCoeFep's SimulateKeyEventsL() have been sent to the application. */
       
   315 EXPORT_C void MCoeFepObserver::HandleCompletionOfTransactionL()
       
   316 	{
       
   317 	}
       
   318 
       
   319 EXPORT_C void MCoeFepObserver::MCoeFepObserver_Reserved_1()
       
   320 	{
       
   321 	}
       
   322 
       
   323 EXPORT_C void MCoeFepObserver::MCoeFepObserver_Reserved_2()
       
   324 	{
       
   325 	}
       
   326 
       
   327 // TArrayTransformer
       
   328 
       
   329 class TArrayTransformer : private CCoeFep::MModifiedCharacter
       
   330 	{
       
   331 public:
       
   332 	TArrayTransformer(const TArray<TUint>& aArrayOfCharacters);
       
   333 	TArray<CCoeFep::MModifiedCharacter> ArrayOfModifiedCharacters(); // this function is deliberately non-const so that its client is not tempted to create an anonymous (temporary) TArrayTransformer object whose lifetime may turn out to be too short
       
   334 private:
       
   335 	static TInt NumberOfModifiedCharacters(const CBase* aThis); // aThis is really a TArrayTransformer
       
   336 	static const TAny* ModifiedCharacter(const CBase* aThis, TInt aIndex); // aThis is really a TArrayTransformer
       
   337 	// from CCoeFep::MModifiedCharacter
       
   338 	virtual TUint CharacterCode() const;
       
   339 	virtual TUint ModifierMask() const;
       
   340 	virtual TUint ModifierValues() const;
       
   341 private:
       
   342 	const TArray<TUint>& iArrayOfCharacters;
       
   343 	TInt iCurrentIndex;
       
   344 	};
       
   345 
       
   346 TArrayTransformer::TArrayTransformer(const TArray<TUint>& aArrayOfCharacters)
       
   347 	:iArrayOfCharacters(aArrayOfCharacters),
       
   348 	 iCurrentIndex(-1)
       
   349 	{
       
   350 	}
       
   351 
       
   352 TArray<CCoeFep::MModifiedCharacter> TArrayTransformer::ArrayOfModifiedCharacters()
       
   353 	{
       
   354 	return TArray<CCoeFep::MModifiedCharacter>(NumberOfModifiedCharacters, ModifiedCharacter, REINTERPRET_CAST(const CBase*, this));
       
   355 	}
       
   356 
       
   357 TInt TArrayTransformer::NumberOfModifiedCharacters(const CBase* aThis)
       
   358 	{
       
   359 	return REINTERPRET_CAST(TArrayTransformer*, CONST_CAST(CBase*, aThis))->iArrayOfCharacters.Count();
       
   360 	}
       
   361 
       
   362 const TAny* TArrayTransformer::ModifiedCharacter(const CBase* aThis, TInt aIndex)
       
   363 	{
       
   364 	TArrayTransformer& thisObject=*REINTERPRET_CAST(TArrayTransformer*, CONST_CAST(CBase*, aThis));
       
   365 	__ASSERT_ALWAYS(aIndex>=0, Panic(EPanicBadIndex1));
       
   366 	__ASSERT_ALWAYS(aIndex<thisObject.iArrayOfCharacters.Count(), Panic(EPanicBadIndex2));
       
   367 	thisObject.iCurrentIndex=aIndex;
       
   368 	return aThis;
       
   369 	}
       
   370 
       
   371 TUint TArrayTransformer::CharacterCode() const
       
   372 	{
       
   373 	__ASSERT_ALWAYS(iCurrentIndex>=0, Panic(EPanicBadIndex3));
       
   374 	__ASSERT_ALWAYS(iCurrentIndex<iArrayOfCharacters.Count(), Panic(EPanicBadIndex4));
       
   375 	return iArrayOfCharacters[iCurrentIndex];
       
   376 	}
       
   377 
       
   378 /**
       
   379 Returns a <code>TUint</code> which indicates which modifiers to
       
   380 override, rather than using the current state of the keyboard's
       
   381 modifiers.
       
   382 
       
   383 @return   "TUint"
       
   384             The modifiers to override in the key combination.
       
   385 */
       
   386 TUint TArrayTransformer::ModifierMask() const
       
   387 	{
       
   388 	return 0;
       
   389 	}
       
   390 
       
   391 /**
       
   392 Returns a <code>TUint</code> which indicates which of the modifiers
       
   393 specified in the mask (returned by <code>ModifierMask()</code>) must
       
   394 be on and which must be off.
       
   395 
       
   396 @return   "TUint"
       
   397             Indicates which of the modifiers specified in the mask
       
   398             (returned by <code>ModifierMask()</code>) must be on
       
   399             and which must be off.
       
   400 */            
       
   401 TUint TArrayTransformer::ModifierValues() const
       
   402 	{
       
   403 	return 0;
       
   404 	}
       
   405 
       
   406 
       
   407 // CCoeFep::CCoeFepExtra
       
   408 
       
   409 NONSHARABLE_CLASS(CCoeFep)::CCoeFepExtra : public CBase
       
   410 	{
       
   411 public:
       
   412 	CCoeFepExtra();
       
   413 	virtual ~CCoeFepExtra();
       
   414 public:
       
   415 	CCoeFep::CLowPriorityActive* iLowPriorityActive;
       
   416 	CFepSettingsTracker* iSettingsTracker;
       
   417 	COnStateTracker* iOnStateTracker;
       
   418 	};
       
   419 
       
   420 
       
   421 CCoeFep::CCoeFepExtra::CCoeFepExtra()
       
   422 	{
       
   423 	}
       
   424 
       
   425 CCoeFep::CCoeFepExtra::~CCoeFepExtra()
       
   426 	{
       
   427 	delete iLowPriorityActive;
       
   428 	delete iSettingsTracker;
       
   429 	delete iOnStateTracker;
       
   430 	}
       
   431 
       
   432 
       
   433 // CCoeFep
       
   434 
       
   435 /** Destructor.
       
   436 
       
   437 Removes the FEP from the control environment's message observer list prior 
       
   438 to its destruction. */
       
   439 EXPORT_C CCoeFep::~CCoeFep()
       
   440 	{
       
   441 	iConeEnvironment.RemoveForegroundObserver(*this);
       
   442 	iConeEnvironment.RemoveFocusObserver(*this);
       
   443 	iConeEnvironment.RemoveMessageObserver(*this);
       
   444 	if (iHighPriorityActive!=NULL)
       
   445 		{
       
   446 		if (!iHighPriorityActive->MustBeAndNowWillBeDestroyedLater()) // if this return "true", the iHighPriorityActive object now "owns itself", i.e. it will be destroyed just before the outermost CHighPriorityActive::SendKeyEventToApplicationNowL call on the call-stack returns
       
   447 			{
       
   448 			delete iHighPriorityActive;
       
   449 			}
       
   450 		}
       
   451 	delete iExtra;
       
   452 	delete iLastKeyEvent;
       
   453 	}
       
   454 
       
   455 /** Tests whether or not the FEP is simulating key events.
       
   456 
       
   457 This function should be called early in the FEP's implementation of OfferKeyEventL(). 
       
   458 If it returns ETrue, OfferKeyEventL() should immediately return EKeyWasNotConsumed 
       
   459 so that the application gets the key event as intended. 
       
   460 
       
   461 It is called by the FEP_START_KEY_EVENT_HANDLER_L and FEP_START_KEY_EVENT_HANDLER_NO_DOWN_UP_FILTER_L 
       
   462 macros.
       
   463 
       
   464 @return ETrue if the FEP is simulating key events, EFalse if not. */
       
   465 EXPORT_C TBool CCoeFep::IsSimulatingKeyEvent() const
       
   466 	{
       
   467 	return iHighPriorityActive->IsSimulatingKeyEvent();
       
   468 	}
       
   469 
       
   470 /** Since the advent of Platform security in Symbian OS, the turning on/off of FEPs is handled
       
   471 via a different means (which is secure). Hence this function now only ever returns EFalse. 
       
   472 
       
   473 @deprecated
       
   474 @param aKeyEvent No longer used.
       
   475 @return Always returns EFalse.
       
   476 */
       
   477 EXPORT_C TBool CCoeFep::IsTurnedOnByL(const TKeyEvent& /*aKeyEvent*/) const
       
   478 	{
       
   479 	return EFalse;
       
   480 	}
       
   481 
       
   482 /** Since the advent of Platform security in Symbian OS, the turning on/off of FEPs is handled
       
   483 via a different means (which is secure). Hence this function now only ever returns EFalse. 
       
   484 
       
   485 @deprecated
       
   486 @param aKeyEvent No longer used.
       
   487 @return Always returns EFalse.
       
   488 */
       
   489 EXPORT_C TBool CCoeFep::IsTurnedOffByL(const TKeyEvent& /*aKeyEvent*/) const
       
   490 	{
       
   491 	return EFalse;
       
   492 	}
       
   493 
       
   494 /**
       
   495 @internalComponent
       
   496 
       
   497 Note that we should maintain BC for this function as it is used by 
       
   498 the published-All macro FEP_START_KEY_EVENT_HANDLER_L
       
   499 */
       
   500 EXPORT_C void CCoeFep::OnStartingHandlingKeyEvent_WithDownUpFilterLC()
       
   501 	{
       
   502 	DoOnStartingHandlingKeyEventLC(0);
       
   503 	}
       
   504 
       
   505 
       
   506 /**
       
   507 @internalComponent
       
   508 
       
   509 Note that we should maintain BC for this function as it is used by 
       
   510 the published-All macro FEP_START_KEY_EVENT_HANDLER_NO_DOWN_UP_FILTER_L
       
   511 */
       
   512 EXPORT_C void CCoeFep::OnStartingHandlingKeyEvent_NoDownUpFilterLC()
       
   513 	{
       
   514 	DoOnStartingHandlingKeyEventLC(EFlagNoDownUpFilter);
       
   515 	}
       
   516 
       
   517 
       
   518 /**
       
   519 @internalComponent
       
   520 
       
   521 Note that we should maintain BC for this function as it is used by 
       
   522 the published-All macros FEP_START_KEY_EVENT_HANDLER_L and FEP_END_KEY_EVENT_HANDLER_L
       
   523 */
       
   524 EXPORT_C TKeyResponse CCoeFep::OnFinishingHandlingKeyEvent_WithDownUpFilterL(TEventCode aEventCode, const TKeyEvent& aKeyEvent, TKeyResponse aKeyResponse)
       
   525 	{
       
   526 	__ASSERT_ALWAYS((iFlags&EFlagNoDownUpFilter)==0, Panic(EPanicNoDownUpFilter));
       
   527 	return DoOnFinishingHandlingKeyEventL(aEventCode, aKeyEvent, aKeyResponse);
       
   528 	}
       
   529 
       
   530 /**
       
   531 @internalComponent
       
   532 
       
   533 Note that we should maintain BC for this function as it is used by 
       
   534 the published-All macros FEP_START_KEY_EVENT_HANDLER_NO_DOWN_UP_FILTER_L and 
       
   535 FEP_END_KEY_EVENT_HANDLER_NO_DOWN_UP_FILTER_L
       
   536 */
       
   537 EXPORT_C TKeyResponse CCoeFep::OnFinishingHandlingKeyEvent_NoDownUpFilterL(TEventCode aEventCode, const TKeyEvent& aKeyEvent, TKeyResponse aKeyResponse)
       
   538 	{
       
   539 	__ASSERT_ALWAYS(iFlags&EFlagNoDownUpFilter, Panic(EPanicWithDownUpFilter));
       
   540 	return DoOnFinishingHandlingKeyEventL(aEventCode, aKeyEvent, aKeyResponse);
       
   541 	}
       
   542 
       
   543 /** Protected C++ constructor. 
       
   544 
       
   545 This function should be called from within the FEP's constructor.
       
   546 
       
   547 @param aConeEnvironment Control environment. Provides an interface to the 
       
   548 window server, so that the FEP control can receive pointer and key events. */
       
   549 EXPORT_C CCoeFep::CCoeFep(CCoeEnv& aConeEnvironment)
       
   550 	:iConeEnvironment(aConeEnvironment),
       
   551 	 iFlags(0),
       
   552 	 iHighPriorityActive(NULL)
       
   553 	{
       
   554 	}
       
   555 
       
   556 /** Initialises the FEP's generic settings (whether the FEP is on or off and what 
       
   557 key events should turn it on or off). 
       
   558 
       
   559 During construction, all FEPs must call this member function. It also initialises the 
       
   560 FEP as an observer so that it receives notification of changes from the control 
       
   561 environment. Examples of such changes are the target control gaining or losing focus 
       
   562 or changes to the generic FEP settings made by another running instance of the same FEP.
       
   563 
       
   564 @param aFepParameters No longer used. */
       
   565 EXPORT_C void CCoeFep::BaseConstructL(const CCoeFepParameters& /*aFepParameters*/)
       
   566 	{
       
   567 	__ASSERT_ALWAYS(iHighPriorityActive==NULL, Panic(EPanicAlreadyCalledBaseConstructL));
       
   568 	iHighPriorityActive=CHighPriorityActive::NewL(iConeEnvironment);
       
   569 	iExtra = new(ELeave) CCoeFepExtra;
       
   570 	iExtra->iLowPriorityActive = CLowPriorityActive::NewL(*iHighPriorityActive);
       
   571 	iExtra->iSettingsTracker = CFepSettingsTracker::NewL(iConeEnvironment, *this);
       
   572 	iExtra->iOnStateTracker = COnStateTracker::NewL(*this);
       
   573 	iLastKeyEvent=new(ELeave) SKeyEvent;
       
   574 	iConeEnvironment.AddForegroundObserverL(*this);
       
   575 	iConeEnvironment.AddFocusObserverL(*this);
       
   576 	iConeEnvironment.AddMessageObserverL(*this);
       
   577 	}
       
   578 
       
   579 /** Sets this FEP's attributes with values from the global settings.
       
   580 
       
   581 Calls the FEP's implementation of MFepAttributeStorer::ReadAttributeDataFromStreamL() 
       
   582 for each FEP attribute which needs to be synchronised. */
       
   583 EXPORT_C void CCoeFep::ReadAllAttributesL()
       
   584 	{
       
   585 	MFepAttributeStorer::ReadAllAttributesL(iConeEnvironment);
       
   586 	}
       
   587 
       
   588 /** Uses a high-priority active object to call the specified object's ExecuteFunctionL().
       
   589 
       
   590 This function must be used to handle an event if that event starts a transaction 
       
   591 and if handling that event is dependent on the target control's input 
       
   592 capabilities. In such a case, MakeDeferredFunctionCall() should be called 
       
   593 by the FEP, (passing in the relevant MDeferredFunctionCall-derived object) 
       
   594 before calling HandleStartOfTransactionL().
       
   595 
       
   596 Note:
       
   597 
       
   598 The reason why key event handling must be done inside a high priority active 
       
   599 object is as follows:
       
   600 
       
   601 In some UI situations, pressing a key should move focus to a previously non-focused 
       
   602 or non-existent text editor control, and should insert the character corresponding 
       
   603 to that key event into the newly focused control.
       
   604 
       
   605 When text entry is via a FEP, for this focus-shift to occur at the right time, 
       
   606 when the FEP receives its first key event, it should call MCoeFepObserver::HandleStartOfTransactionL(). 
       
   607 The implementation of this function should do whatever focus shift is required 
       
   608 (e.g. launch the dialog).
       
   609 
       
   610 However, if it is a waiting dialog, text cannot now be entered into the FEP 
       
   611 until the dialog's RunLD() or ExecuteLD() returns (this occurs when the 
       
   612 dialog is either cancelled or committed). Therefore, HandleStartOfTransactionL() 
       
   613 will block. The solution is for the FEP to handle the key event from within 
       
   614 a high priority active object.
       
   615 
       
   616 @param aDeferredFunctionCall Implements key event handling in its ExecuteFunctionL() 
       
   617 function. This is deferred in that it is executed when the active object's 
       
   618 RunL() is called. */
       
   619 EXPORT_C void CCoeFep::MakeDeferredFunctionCall(MDeferredFunctionCall& aDeferredFunctionCall)
       
   620 	{
       
   621 	iHighPriorityActive->MakeDeferredFunctionCall(aDeferredFunctionCall);
       
   622 	}
       
   623 
       
   624 /** 
       
   625 Simulates a key event for each of the character codes in the array passed to 
       
   626 it.
       
   627 
       
   628 This function should be called in order to send key events to the application 
       
   629 underneath the FEP (unless inline editing is taking place, in which case a 
       
   630 different mechanism is used). FEPs should not use CCoeEnv::SimulateKeyEventL() 
       
   631 to simulate key events.
       
   632 
       
   633 @param aArrayOfCharacters An array of characters. 
       
   634 */
       
   635 EXPORT_C void CCoeFep::SimulateKeyEventsL(const TArray<TUint>& aArrayOfCharacters)
       
   636 	{
       
   637 	TArrayTransformer arrayTransformer(aArrayOfCharacters); // the TArrayTransformer object cannot be an anonymous (temporary) object as its lifetime must be guaranteed to last until SimulateKeyEventsL returns
       
   638 	SimulateKeyEventsL(arrayTransformer.ArrayOfModifiedCharacters());
       
   639 	}
       
   640 
       
   641 EXPORT_C void CCoeFep::SimulateKeyEventsL(const TArray<MModifiedCharacter>& aArrayOfModifiedCharacters)
       
   642 	{
       
   643 	const TUint baseModifiers=iConeEnvironment.WsSession().GetModifierState()|EModifierSpecial;
       
   644 	TKeyEvent keyEvent;
       
   645 	keyEvent.iScanCode=0;
       
   646 	keyEvent.iRepeats=0;
       
   647 
       
   648 	const TInt numberOfCharacters=aArrayOfModifiedCharacters.Count();
       
   649 	for (TInt i=0; i<numberOfCharacters; ++i)
       
   650 		{
       
   651 		const MModifiedCharacter& modifiedCharacter=aArrayOfModifiedCharacters[i];
       
   652 		const TUint modifierMask=modifiedCharacter.ModifierMask();
       
   653 		const TUint modifierValues=modifiedCharacter.ModifierValues();
       
   654 
       
   655 		__ASSERT_ALWAYS(!(modifierValues&~modifierMask), Panic(EPanicInconsistentModifierMaskAndValues));
       
   656 		keyEvent.iCode=modifiedCharacter.CharacterCode();
       
   657 		
       
   658 		//	Combine surrogate pair as one keyEvent.iCode
       
   659 		//	skip single surrogate part
       
   660 		if ( IsSurrogate( keyEvent.iCode ) )
       
   661 			{
       
   662 			// Combine surrogate pair
       
   663 			if (i >= numberOfCharacters - 1)
       
   664 				{
       
   665 				//	skip it
       
   666 				continue;
       
   667 				}
       
   668 
       
   669 			// If not surrogate high part
       
   670 			if ( !IsHighSurrogate( keyEvent.iCode ) )
       
   671 				{
       
   672 				continue;
       
   673 				}
       
   674 			const MModifiedCharacter &nextModifiedCharacter = aArrayOfModifiedCharacters[i+1];
       
   675 			TUint nextCode = nextModifiedCharacter.CharacterCode();
       
   676 			//	If not surrogate low part
       
   677 			if ( !IsLowSurrogate( nextCode ) )
       
   678 				{
       
   679 				continue;
       
   680 				}
       
   681 			// Combine surrogate pair
       
   682 			keyEvent.iCode = JoinSurrogates( keyEvent.iCode, nextCode );
       
   683 			i++;
       
   684 			}
       
   685 
       
   686 		keyEvent.iModifiers=baseModifiers;
       
   687 		keyEvent.iModifiers&=~(modifierMask&~modifierValues);
       
   688 		keyEvent.iModifiers|=(modifierMask&modifierValues);
       
   689 
       
   690 		iHighPriorityActive->SimulateKeyEventL(keyEvent);
       
   691 		}
       
   692 	}
       
   693 
       
   694 /** After changing the value of a single FEP attribute that needs to be synchronised, 
       
   695 call this function to synchronise other running instances of the FEP.
       
   696 
       
   697 It first calls MFepAttributeStorer::WriteAttributeDataToStreamL() which writes 
       
   698 the attribute's new value to the stream and then it causes all other running 
       
   699 instances of the FEP to be notified of the change.
       
   700 
       
   701 @param aAttributeUid The UID of the attribute that has changed.
       
   702 @capability WriteDeviceData */
       
   703 EXPORT_C void CCoeFep::WriteAttributeDataAndBroadcastL(TUid aAttributeUid)
       
   704 	{
       
   705 	MFepAttributeStorer::WriteAttributeDataAndBroadcastL(iConeEnvironment, aAttributeUid);
       
   706 	}
       
   707 
       
   708 /** After changing the value of multiple FEP attributes that need to be synchronised, 
       
   709 call this function to synchronise other running instances of the FEP.
       
   710 
       
   711 It first calls MFepAttributeStorer::WriteAttributeDataToStreamL() which writes 
       
   712 the attributes' new values to the stream and then it causes all other running 
       
   713 instances of the FEP to be notified of the changes.
       
   714 
       
   715 @param aAttributeUids Array of UIDs for the attribute that have changed.
       
   716 @capability WriteDeviceData */
       
   717 EXPORT_C void CCoeFep::WriteAttributeDataAndBroadcastL(const TArray<TUid>& aAttributeUids)
       
   718 	{
       
   719 	MFepAttributeStorer::WriteAttributeDataAndBroadcastL(iConeEnvironment, aAttributeUids);
       
   720 	}
       
   721 
       
   722 /** Tests whether the FEP is on or off.
       
   723 
       
   724 @return Non-zero if the FEP is on, EFalse if the FEP is off. */
       
   725 EXPORT_C TBool CCoeFep::IsOn() const
       
   726 	{
       
   727 	return iFlags&EFlagOnState;
       
   728 	}
       
   729 
       
   730 /** @internalComponent */
       
   731 void CCoeFep::SetOnState(TBool aOnState)
       
   732 	{
       
   733 	const TUint oldFlags=iFlags;
       
   734 	if (aOnState)
       
   735 		iFlags|=EFlagOnState;
       
   736 	else
       
   737 		iFlags&=~EFlagOnState;
       
   738 
       
   739 	if (oldFlags!=iFlags)
       
   740 		IsOnHasChangedState();
       
   741 	}
       
   742 
       
   743 void CCoeFep::DoOnStartingHandlingKeyEventLC(TUint aFlagNoDownUpFilter)
       
   744 	{
       
   745 	__ASSERT_DEBUG((aFlagNoDownUpFilter&~EFlagNoDownUpFilter)==0, Panic(EPanicBadFlag));
       
   746 	__ASSERT_ALWAYS((iFlags&EFlagIsHandlingKeyEvent)==0, Panic(EPanicAlreadyHandlingKeyEvent));
       
   747 	CleanupStack::PushL(TCleanupItem(TurnOffKeyEventHandlingFlags, &iFlags));
       
   748 	iFlags|=(EFlagIsHandlingKeyEvent|aFlagNoDownUpFilter);
       
   749 	}
       
   750 
       
   751 TKeyResponse CCoeFep::DoOnFinishingHandlingKeyEventL(TEventCode aEventCode, const TKeyEvent& aKeyEvent, TKeyResponse aKeyResponse)
       
   752 	{
       
   753 	__ASSERT_ALWAYS(iFlags&EFlagIsHandlingKeyEvent, Panic(EPanicNotHandlingKeyEvent));
       
   754 	if (~iFlags&EFlagNoDownUpFilter)
       
   755 		{
       
   756 		switch (aEventCode)
       
   757 			{
       
   758 		case EEventKeyDown:
       
   759 			__ASSERT_DEBUG(aKeyResponse==EKeyWasConsumed, Panic(EPanicBadKeyResponse1));
       
   760 			iExtra->iLowPriorityActive->SendKeyEventToApplicationDeferred(aEventCode, aKeyEvent); // this is so that applications get EEventKeyDown events for keys such as shift, ctrl, etc, (i.e. keys for which no EEventKey events occur when they are pressed)
       
   761 			break;
       
   762 		case EEventKey:
       
   763 			iExtra->iLowPriorityActive->Cancel();
       
   764 			if ((aKeyResponse==EKeyWasNotConsumed) &&
       
   765 				(iLastKeyEvent->iEventCode==EEventKeyDown) &&
       
   766 				(iLastKeyEvent->iKeyEvent.iScanCode==aKeyEvent.iScanCode))
       
   767 				{
       
   768 				__ASSERT_DEBUG(iLastKeyEvent->iKeyResponse==EKeyWasConsumed, Panic(EPanicBadKeyResponse2));
       
   769 				iHighPriorityActive->SendKeyEventToApplicationNowL(iLastKeyEvent->iEventCode, iLastKeyEvent->iKeyEvent);
       
   770 				}
       
   771 			break;
       
   772 		case EEventKeyUp:
       
   773 			if ((iLastKeyEvent->iEventCode==EEventKey) &&
       
   774 				(iLastKeyEvent->iKeyEvent.iScanCode==aKeyEvent.iScanCode) &&
       
   775 				(iLastKeyEvent->iKeyResponse==EKeyWasNotConsumed))
       
   776 				{
       
   777 				__ASSERT_DEBUG(aKeyResponse==EKeyWasConsumed, Panic(EPanicBadKeyResponse3));
       
   778 				aKeyResponse=EKeyWasNotConsumed;
       
   779 				}
       
   780 			if ((iLastKeyEvent->iEventCode==EEventKeyDown) &&
       
   781 				(iLastKeyEvent->iKeyEvent.iScanCode==aKeyEvent.iScanCode))
       
   782 				{
       
   783 				__ASSERT_DEBUG(iLastKeyEvent->iKeyResponse==EKeyWasConsumed, Panic(EPanicBadKeyResponse4));
       
   784 				__ASSERT_DEBUG(aKeyResponse==EKeyWasConsumed, Panic(EPanicBadKeyResponse5));
       
   785 				aKeyResponse=EKeyWasNotConsumed;
       
   786 				}
       
   787 			break;
       
   788 		default:
       
   789 			break;
       
   790 			}
       
   791 		}
       
   792 
       
   793 	iLastKeyEvent->iEventCode=aEventCode;
       
   794 	iLastKeyEvent->iKeyEvent=aKeyEvent;
       
   795 	iLastKeyEvent->iKeyResponse=aKeyResponse;
       
   796 	CleanupStack::PopAndDestroy(&iFlags); // turns the EFlagIsHandlingKeyEvent (and EFlagNoDownUpFilter if it's on) flags off
       
   797 	return aKeyResponse;
       
   798 	}
       
   799 
       
   800 void CCoeFep::TurnOffKeyEventHandlingFlags(TAny* aFlags)
       
   801 	{
       
   802 	*STATIC_CAST(TUint*, aFlags)&=~(EFlagIsHandlingKeyEvent|EFlagNoDownUpFilter);
       
   803 	}
       
   804 
       
   805 EXPORT_C void CCoeFep::MFepAttributeStorer_Reserved_1()
       
   806 	{
       
   807 	}
       
   808 
       
   809 EXPORT_C void CCoeFep::MFepAttributeStorer_Reserved_2()
       
   810 	{
       
   811 	}
       
   812 
       
   813 EXPORT_C void CCoeFep::MCoeForegroundObserver_Reserved_1()
       
   814 	{
       
   815 	}
       
   816 
       
   817 EXPORT_C void CCoeFep::MCoeForegroundObserver_Reserved_2()
       
   818 	{
       
   819 	}
       
   820 
       
   821 EXPORT_C void CCoeFep::MCoeFocusObserver_Reserved_1()
       
   822 	{
       
   823 	}
       
   824 
       
   825 EXPORT_C void CCoeFep::MCoeFocusObserver_Reserved_2()
       
   826 	{
       
   827 	}
       
   828 
       
   829 
       
   830 /**
       
   831 @publishedAll 
       
   832 @released 
       
   833 */
       
   834 EXPORT_C MCoeMessageObserver::TMessageResponse CCoeFep::HandleMessageL(TUint32, TUid, const TDesC8&)
       
   835 	{
       
   836 	return EMessageNotHandled;
       
   837 	}
       
   838 
       
   839 EXPORT_C void CCoeFep::MCoeMessageObserver_Reserved_1()
       
   840 	{
       
   841 	}
       
   842 
       
   843 EXPORT_C void CCoeFep::MCoeMessageObserver_Reserved_2()
       
   844 	{
       
   845 	}
       
   846 
       
   847 EXPORT_C void CCoeFep::CCoeFep_Reserved_1()
       
   848 	{
       
   849 	}
       
   850 
       
   851 EXPORT_C void CCoeFep::CCoeFep_Reserved_2()
       
   852 	{
       
   853 	}
       
   854 
       
   855 // CCoeFep::MDeferredFunctionCall
       
   856 
       
   857 EXPORT_C void CCoeFep::MDeferredFunctionCall::MDeferredFunctionCall_Reserved_1()
       
   858 	{
       
   859 	}
       
   860 
       
   861 EXPORT_C void CCoeFep::MDeferredFunctionCall::MDeferredFunctionCall_Reserved_2()
       
   862 	{
       
   863 	}
       
   864 
       
   865 // CCoeFep::MModifiedCharacter
       
   866 
       
   867 EXPORT_C void CCoeFep::MModifiedCharacter::MModifiedCharacter_Reserved_1()
       
   868 	{
       
   869 	}
       
   870 
       
   871 EXPORT_C void CCoeFep::MModifiedCharacter::MModifiedCharacter_Reserved_2()
       
   872 	{
       
   873 	}
       
   874 
       
   875 // CCoeFep::CHighPriorityActive
       
   876 
       
   877 CCoeFep::CHighPriorityActive* CCoeFep::CHighPriorityActive::NewL(CCoeEnv& aConeEnvironment)
       
   878 	{
       
   879 	CHighPriorityActive* const highPriorityActive=new(ELeave) CHighPriorityActive(aConeEnvironment);
       
   880 	CleanupStack::PushL(highPriorityActive);
       
   881 	highPriorityActive->ConstructL();
       
   882 	CleanupStack::Pop(highPriorityActive);
       
   883 	return highPriorityActive;
       
   884 	}
       
   885 
       
   886 CCoeFep::CHighPriorityActive::~CHighPriorityActive()
       
   887 	{
       
   888 	Cancel();
       
   889 	iArrayOfKeyEvents.Close();
       
   890 	delete iFlagClearer;
       
   891 	}
       
   892 
       
   893 void CCoeFep::CHighPriorityActive::MakeDeferredFunctionCall(MDeferredFunctionCall& aDeferredFunctionCall)
       
   894 	{
       
   895 	__ASSERT_ALWAYS(iDeferredFunctionCall==NULL, Panic(EPanicDeferredFunctionCallOutstanding));
       
   896 	iDeferredFunctionCall=&aDeferredFunctionCall;
       
   897 
       
   898 	if (!IsActive())
       
   899 		MakeReadyToRun();
       
   900 	}
       
   901 	
       
   902 /**
       
   903 The function appends a key event to the array of keyevents
       
   904 
       
   905 @param const TKeyEvent& aKeyEvent The key event to be appended
       
   906 */
       
   907 void CCoeFep::CHighPriorityActive::SimulateKeyEventL(const TKeyEvent& aKeyEvent)
       
   908 	{
       
   909 	User::LeaveIfError(iArrayOfKeyEvents.Append(aKeyEvent));
       
   910 	if (!IsActive())
       
   911 		MakeReadyToRun();
       
   912 	}
       
   913 
       
   914 void CCoeFep::CHighPriorityActive::SendKeyEventToApplicationNowL(TEventCode aEventCode, const TKeyEvent& aKeyEvent)
       
   915 	{
       
   916 	++iRecursionLevel; // must be done *before* pushing DecrementRecursionLevelAndDestroySelfIfZeroAndOwnsSelf on the cleanup-stack in case that PushL leaves and decrements iRecursionLevel without us actually having incremented it first
       
   917 	CleanupStack::PushL(TCleanupItem(DecrementRecursionLevelAndDestroySelfIfZeroAndOwnsSelf, this));
       
   918 	DoSendKeyEventToApplicationNowL(aEventCode, aKeyEvent);
       
   919 	CleanupStack::PopAndDestroy(this); // custom cleanup-item DecrementRecursionLevelAndDestroySelfIfZeroAndOwnsSelf
       
   920 	}
       
   921 	
       
   922 void CCoeFep::CHighPriorityActive::DoSendKeyEventToApplicationNowL(TEventCode aEventCode, const TKeyEvent& aKeyEvent)
       
   923 	{
       
   924 	SStackedFlags stackedFlags(iFlags);
       
   925 	iFlagClearer->TurnOffFlagIsSimulatingKeyEventDeferred(stackedFlags);
       
   926 	CleanupStack::PushL(TCleanupItem(CancelFlagClearer, iFlagClearer));
       
   927 	CleanupStack::PushL(TCleanupItem(TurnOffFlagIsSimulatingKeyEvent, &stackedFlags));
       
   928 	iFlags|=EFlagIsSimulatingKeyEvent;
       
   929 	iConeEnvironment.SimulateKeyEventL(aKeyEvent, aEventCode); // this may launch a *waiting* dialog, in which case we want to restore the EFlagIsSimulatingKeyEvent flag in iFlags to its original setting as soon as possible, hence the need for the iFlagClearer active-object
       
   930 	CleanupStack::PopAndDestroy(2, iFlagClearer);
       
   931 	}
       
   932 
       
   933 TBool CCoeFep::CHighPriorityActive::MustBeAndNowWillBeDestroyedLater()
       
   934 	{
       
   935 	if (iRecursionLevel>0)
       
   936 		{
       
   937 		iFlags|=EFlagOwnsSelf;
       
   938 		return ETrue;
       
   939 		}
       
   940 
       
   941 	return EFalse;
       
   942 	}
       
   943 	
       
   944 void CCoeFep::CHighPriorityActive::DecrementRecursionLevelAndDestroySelfIfZeroAndOwnsSelf(TAny* aThis)
       
   945 	{ // static
       
   946 	CHighPriorityActive* const self=STATIC_CAST(CHighPriorityActive*, aThis);
       
   947 	--self->iRecursionLevel;
       
   948 	__ASSERT_DEBUG(self->iRecursionLevel>=0, Panic(EPanicBadRecursionLevel));
       
   949 
       
   950 	if ((self->iRecursionLevel<=0) && (self->iFlags&EFlagOwnsSelf))
       
   951 		delete self;
       
   952 	}
       
   953 		
       
   954 CCoeFep::CHighPriorityActive::CHighPriorityActive(CCoeEnv& aConeEnvironment)
       
   955 	:CActive(EActivePriorityWsEvents+20), // this priority must be less than CCoeEnvExtra::CHighPriorityActive's priority (a CONE class) so that FEPs receive notification of any change in focus (resulting from them calling HandleStartOfTransactionL) *before* any deferred function (i.e. one overriding MDeferredFunctionCall::ExecuteFunctionL) is called - this is necessary as the deferred function may depend on the deferred capabilities of the newly focused control (e.g. for inline editing)
       
   956 	 iConeEnvironment(aConeEnvironment),
       
   957 	 iFlags(0),
       
   958 	 iDeferredFunctionCall(NULL),
       
   959 	 iArrayOfKeyEvents(10),
       
   960 	 iRecursionLevel(0)
       
   961 	{
       
   962 	CActiveScheduler::Add(this);
       
   963 	}
       
   964 
       
   965 void CCoeFep::CHighPriorityActive::ConstructL()
       
   966 	{
       
   967 	iFlagClearer=CFlagClearer::NewL();
       
   968 	}
       
   969 
       
   970  void CCoeFep::CHighPriorityActive::MakeReadyToRun()
       
   971 	{
       
   972 	TRequestStatus* requestStatus=&iStatus;
       
   973 	User::RequestComplete(requestStatus, KErrNone);
       
   974 	SetActive();
       
   975 	}
       
   976 
       
   977 void CCoeFep::CHighPriorityActive::CancelFlagClearer(TAny* aFlagClearer)
       
   978 	{
       
   979 	CFlagClearer& flagClearer=*STATIC_CAST(CFlagClearer*, aFlagClearer);
       
   980 	flagClearer.Cancel();
       
   981 	}
       
   982 
       
   983 void CCoeFep::CHighPriorityActive::TurnOffFlagIsSimulatingKeyEvent(TAny* aStackedFlags)
       
   984 	{
       
   985 	DoTurnOffFlagIsSimulatingKeyEvent(*STATIC_CAST(SStackedFlags*, aStackedFlags));
       
   986 	}
       
   987 
       
   988 void CCoeFep::CHighPriorityActive::DoTurnOffFlagIsSimulatingKeyEvent(SStackedFlags& aStackedFlags)
       
   989 	{
       
   990 	aStackedFlags.iFlags&=~EFlagIsSimulatingKeyEvent;
       
   991 	aStackedFlags.iFlags|=(aStackedFlags.iOldFlags&EFlagIsSimulatingKeyEvent);
       
   992 	}
       
   993 
       
   994 void CCoeFep::CHighPriorityActive::DoCancel()
       
   995 	{
       
   996 	}
       
   997 
       
   998 void CCoeFep::CHighPriorityActive::RunL()
       
   999 	{
       
  1000 	if (iDeferredFunctionCall!=NULL)
       
  1001 		{
       
  1002 		if (iArrayOfKeyEvents.Count()>0)
       
  1003 			MakeReadyToRun();
       
  1004 
       
  1005 		MDeferredFunctionCall* deferredFunctionCall=iDeferredFunctionCall;
       
  1006 		iDeferredFunctionCall=NULL;
       
  1007 		deferredFunctionCall->ExecuteFunctionL();
       
  1008 		}
       
  1009 	else
       
  1010 		{
       
  1011 		const TKeyEvent keyEvent=iArrayOfKeyEvents[0];
       
  1012 		iArrayOfKeyEvents.Remove(0);
       
  1013 		if (iArrayOfKeyEvents.Count()>0)
       
  1014 			MakeReadyToRun();
       
  1015 
       
  1016 		++iRecursionLevel;
       
  1017 		iFlags|=EFlagRecursionLevelIncremented;
       
  1018 		DoSendKeyEventToApplicationNowL(EEventKey, keyEvent);
       
  1019 
       
  1020 		const TBool handleCompletionOfTransaction=(iArrayOfKeyEvents.Count()==0);
       
  1021 		CCoeEnv& coneEnvironment=iConeEnvironment;
       
  1022 		iFlags&=~EFlagRecursionLevelIncremented;
       
  1023 		DecrementRecursionLevelAndDestroySelfIfZeroAndOwnsSelf(this);
       
  1024 
       
  1025 		// the "this" object may have been deleted from this point onwards, so we can't access any member objects or call any other functions that will access any member objects
       
  1026 		if (handleCompletionOfTransaction)
       
  1027 			coneEnvironment.ForEachFepObserverCall(FepObserverHandleCompletionOfTransactionL);
       
  1028 		}
       
  1029 	}
       
  1030 
       
  1031 TInt CCoeFep::CHighPriorityActive::RunError(TInt aError)
       
  1032 	{
       
  1033 	if (iFlags&EFlagRecursionLevelIncremented)
       
  1034 		{
       
  1035 		iFlags&=~EFlagRecursionLevelIncremented;
       
  1036 		DecrementRecursionLevelAndDestroySelfIfZeroAndOwnsSelf(this);
       
  1037 		}
       
  1038 
       
  1039 	return aError;
       
  1040 	}
       
  1041 	
       
  1042 // CCoeFep::CHighPriorityActive::CFlagClearer
       
  1043 
       
  1044 CCoeFep::CHighPriorityActive::CFlagClearer* CCoeFep::CHighPriorityActive::CFlagClearer::NewL()
       
  1045 	{
       
  1046 	return new(ELeave) CFlagClearer;
       
  1047 	}
       
  1048 
       
  1049 CCoeFep::CHighPriorityActive::CFlagClearer::~CFlagClearer()
       
  1050 	{
       
  1051 	Cancel();
       
  1052 	}
       
  1053 
       
  1054 void CCoeFep::CHighPriorityActive::CFlagClearer::TurnOffFlagIsSimulatingKeyEventDeferred(SStackedFlags& aStackedFlags)
       
  1055 	{
       
  1056 	Cancel();
       
  1057 	TRequestStatus* requestStatus=&iStatus;
       
  1058 	User::RequestComplete(requestStatus, KErrNone);
       
  1059 	SetActive();
       
  1060 	iStackedFlags=&aStackedFlags;
       
  1061 	}
       
  1062 
       
  1063 CCoeFep::CHighPriorityActive::CFlagClearer::CFlagClearer()
       
  1064 	:CActive(EActivePriorityWsEvents-1), // the priority of CHighPriorityActive objects just needs to be less than the priority with which key-events are handled
       
  1065 	 iStackedFlags(NULL)
       
  1066 	{
       
  1067 	CActiveScheduler::Add(this);
       
  1068 	}
       
  1069 
       
  1070 void CCoeFep::CHighPriorityActive::CFlagClearer::DoCancel()
       
  1071 	{
       
  1072 	iStackedFlags=NULL;
       
  1073 	}
       
  1074 
       
  1075 void CCoeFep::CHighPriorityActive::CFlagClearer::RunL()
       
  1076 	{
       
  1077 	DoTurnOffFlagIsSimulatingKeyEvent(*iStackedFlags);
       
  1078 	iStackedFlags=NULL;
       
  1079 	}
       
  1080 
       
  1081 
       
  1082 // MFepPointerEventHandlerDuringInlineEdit
       
  1083 
       
  1084 EXPORT_C void MFepPointerEventHandlerDuringInlineEdit::MFepPointerEventHandlerDuringInlineEdit_Reserved_1()
       
  1085 	{
       
  1086 	}
       
  1087 
       
  1088 EXPORT_C void MFepPointerEventHandlerDuringInlineEdit::MFepPointerEventHandlerDuringInlineEdit_Reserved_2()
       
  1089 	{
       
  1090 	}
       
  1091 
       
  1092 // MFepInlineTextFormatRetriever
       
  1093 
       
  1094 EXPORT_C void MFepInlineTextFormatRetriever::MFepInlineTextFormatRetriever_Reserved_1()
       
  1095 	{
       
  1096 	}
       
  1097 
       
  1098 EXPORT_C void MFepInlineTextFormatRetriever::MFepInlineTextFormatRetriever_Reserved_2()
       
  1099 	{
       
  1100 	}
       
  1101 
       
  1102 // MCoeFepAwareTextEditor_Extension1
       
  1103 
       
  1104 /**
       
  1105  Starts a FEP inline editing transaction.
       
  1106  
       
  1107  Before starting the transaction, sets the range of characters in the
       
  1108  text editor which should be selected using <code>aCursorSelection</code>,
       
  1109  without visually highlighting the selected characters.
       
  1110  
       
  1111  This method can be used to avoid flicker when selecting a range of characters
       
  1112  followed by starting a FEP inline editing transaction.
       
  1113  
       
  1114  Inserts a descriptor containing the initial inline text into the text
       
  1115  editor. The inline text should normally replace any selected text.
       
  1116  
       
  1117  @param     "TBool& aSetToTrue"
       
  1118             The implementor of this method must set
       
  1119             <code>aSetToTrue</code> to <code>ETrue</code>
       
  1120  @param     "const TCursorSelection& aCursorSelection"
       
  1121             Contains the cursor and anchor positions for the
       
  1122             selection.
       
  1123  @param     "const TDesC& aInitialInlineText"
       
  1124             The inline text to insert into the text editor.
       
  1125  @param     "TInt aPositionOfInsertionPointInInlineText"
       
  1126             An insertion position within the inline text. This is
       
  1127             an offset from the start of the inline text.
       
  1128  @param     "TBool aCursorVisibility"
       
  1129            <code>ETrue</code> for visible text cursor,
       
  1130             <code>EFalse</code> for invisible text cursor in the
       
  1131             text editor.
       
  1132  @param     "const MFormCustomDraw* aCustomDraw"
       
  1133             Pointer to a custom drawing object. May be used to do
       
  1134             advanced formatting of the inline text. This parameter
       
  1135             is optional - a <code>NULL</code> pointer may be
       
  1136             specified.
       
  1137  @param     "MFepInlineTextFormatRetriever&
       
  1138 			aInlineTextFormatRetriever"
       
  1139              Defines a single member function,
       
  1140              <code>GetFormatOfFepInlineText()</code> which is used
       
  1141              by the text editor to find out the formatting to apply
       
  1142              to the inline text. It is also possible to apply
       
  1143              different formatting to different parts of the inline
       
  1144              text.
       
  1145  @param     "MFepPointerEventHandlerDuringInlineEdit&
       
  1146 			aPointerEventHandlerDuringInlineEdit"
       
  1147              Defines a single function,
       
  1148             <code>HandlePointerEventInInlineTextL</code>() which
       
  1149              is called when a pointer event is received within the
       
  1150              inline text. This function might update the cursor
       
  1151              position within the inline text and do text selection.
       
  1152  */
       
  1153 EXPORT_C void MCoeFepAwareTextEditor_Extension1::StartFepInlineEditL(TBool& /*aSetToTrue*/, const TCursorSelection&, const TDesC&, TInt, TBool, const MFormCustomDraw*, MFepInlineTextFormatRetriever&, MFepPointerEventHandlerDuringInlineEdit&)
       
  1154 // StartFepInlineEditL - By not setting aSetToTrue to ETrue, we're explicitly saying that this method is not implemented here
       
  1155 	{
       
  1156 	}
       
  1157 
       
  1158 /** 
       
  1159 By not setting aSetToTrue to ETrue, we're explicitly saying that this method is not implemented here
       
  1160 
       
  1161 @param aSetToTrue  set to ETrue if method implemented.
       
  1162 */
       
  1163 EXPORT_C void MCoeFepAwareTextEditor_Extension1::SetCursorType(TBool& /*aSetToTrue*/, const TTextCursor&)
       
  1164 	{
       
  1165 	}
       
  1166 
       
  1167 /**
       
  1168 By not setting aSetToTrue to ETrue, we're explicitly saying that this method is not implemented here
       
  1169 
       
  1170 @param  aSetToTrue is set to Etrue if the method implemented.
       
  1171 */
       
  1172 EXPORT_C MCoeFepLayDocExtension* MCoeFepAwareTextEditor_Extension1::GetFepLayDocExtension(TBool& /*aSetToTrue*/)
       
  1173 	{
       
  1174 	return NULL;
       
  1175 	}
       
  1176 
       
  1177 
       
  1178 EXPORT_C void MCoeFepAwareTextEditor_Extension1::MCoeFepAwareTextEditor_Extension1_Reserved_4()
       
  1179 	{
       
  1180 	}
       
  1181 
       
  1182 EXPORT_C void MCoeFepLayDocExtension::MCoeFepLayDocExtension_Reserved_1()
       
  1183 	{
       
  1184 	}
       
  1185 
       
  1186 EXPORT_C void MCoeFepLayDocExtension::MCoeFepLayDocExtension_Reserved_2()
       
  1187 	{
       
  1188 	}
       
  1189 
       
  1190 
       
  1191 // MCoeFepAwareTextEditor_Extension1::CState
       
  1192 
       
  1193 /** Empty default constructor. */
       
  1194 EXPORT_C MCoeFepAwareTextEditor_Extension1::CState::CState()
       
  1195 	{
       
  1196 	}
       
  1197 
       
  1198 /** Empty second phase base class constructor. 
       
  1199 
       
  1200 This function should be called from derived classes at the beginning of their 
       
  1201 ConstructL() even though it is currently empty. This is because this class may 
       
  1202 be extended in future to own resources, which will be allocated in BaseConstructL(). */
       
  1203 EXPORT_C void MCoeFepAwareTextEditor_Extension1::CState::BaseConstructL()
       
  1204 	{
       
  1205 	}
       
  1206 
       
  1207 /** Empty virtual destructor. 
       
  1208 	
       
  1209 This is present because the class may be extended in the future to own resources. */
       
  1210 EXPORT_C MCoeFepAwareTextEditor_Extension1::CState::~CState()
       
  1211 	{
       
  1212 	}
       
  1213 
       
  1214 EXPORT_C void MCoeFepAwareTextEditor_Extension1::CState::CState_Reserved_1()
       
  1215 	{
       
  1216 	}
       
  1217 
       
  1218 EXPORT_C void MCoeFepAwareTextEditor_Extension1::CState::CState_Reserved_2()
       
  1219 	{
       
  1220 	}
       
  1221 
       
  1222 EXPORT_C void MCoeFepAwareTextEditor_Extension1::CState::CState_Reserved_3()
       
  1223 	{
       
  1224 	}
       
  1225 
       
  1226 EXPORT_C void MCoeFepAwareTextEditor_Extension1::CState::CState_Reserved_4()
       
  1227 	{
       
  1228 	}
       
  1229 
       
  1230 // MCoeFepAwareTextEditor
       
  1231 
       
  1232 /** Commits the inline text to the document. 
       
  1233 
       
  1234 This function's implementation calls the text editor's implementation of 
       
  1235 DoCommitFepInlineEditL() then calls HandleCompletionOfTransactionL() 
       
  1236 for each FEP observer which has been added to the control environment's FEP 
       
  1237 observer list (see CCoeEnv::AddFepObserverL()).
       
  1238 
       
  1239 @param aConeEnvironment The control's environment. */
       
  1240 EXPORT_C void MCoeFepAwareTextEditor::CommitFepInlineEditL(CCoeEnv& aConeEnvironment)
       
  1241 	{
       
  1242 	DoCommitFepInlineEditL();
       
  1243 	aConeEnvironment.ForEachFepObserverCall(FepObserverHandleCompletionOfTransactionL);
       
  1244 	}
       
  1245 
       
  1246 /** Returns a pointer to an instance of the interface class MCoeFepAwareTextEditor_Extension1, 
       
  1247 or NULL, if the interface is not supported. 
       
  1248 
       
  1249 Calls the private virtual function of the same name.
       
  1250 
       
  1251 @return A pointer to an instance of the interface class MCoeFepAwareTextEditor_Extension1, 
       
  1252 or NULL, if the interface is not supported. */
       
  1253 EXPORT_C MCoeFepAwareTextEditor_Extension1* MCoeFepAwareTextEditor::Extension1()
       
  1254 	{
       
  1255 	TBool setToTrue=EFalse;
       
  1256 	MCoeFepAwareTextEditor_Extension1* const extension1=Extension1(setToTrue);
       
  1257 	return setToTrue? extension1: NULL;
       
  1258 	}
       
  1259 
       
  1260 
       
  1261 /** This private function should be overridden by text editors which support the 
       
  1262 MCoeFepAwareTextEditor_Extension1 interface. 
       
  1263 
       
  1264 The implementation of this function should simply return a pointer to itself 
       
  1265 (this), and set aSetToTrue to ETrue. If not overridden, the function returns 
       
  1266 NULL to indicate that the interface is not supported. Called by the public 
       
  1267 overload of MCoeFepAwareTextEditor::Extension1(). 
       
  1268 
       
  1269 @param aSetToTrue This should always be set to ETrue.
       
  1270 @return A pointer to the object for which the function is invoked (this). 
       
  1271 @publishedAll
       
  1272 @released */
       
  1273 EXPORT_C MCoeFepAwareTextEditor_Extension1* MCoeFepAwareTextEditor::Extension1(TBool& aSetToTrue)
       
  1274 	{
       
  1275 	aSetToTrue=ETrue;
       
  1276 	return NULL;
       
  1277 	}
       
  1278 
       
  1279 EXPORT_C void MCoeFepAwareTextEditor::MCoeFepAwareTextEditor_Reserved_2()
       
  1280 	{
       
  1281 	}
       
  1282 
       
  1283 // MCoeCaptionRetrieverForFep
       
  1284 
       
  1285 EXPORT_C void MCoeCaptionRetrieverForFep::MCoeCaptionRetrieverForFep_Reserved_1()
       
  1286 	{
       
  1287 	}
       
  1288 
       
  1289 EXPORT_C void MCoeCaptionRetrieverForFep::MCoeCaptionRetrieverForFep_Reserved_2()
       
  1290 	{
       
  1291 	}
       
  1292