uifw/EikStd/coctlsrc/AknInputPolicy.cpp
changeset 0 2f259fa3e83a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/EikStd/coctlsrc/AknInputPolicy.cpp	Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,185 @@
+/*
+* Copyright (c) 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:
+*
+*/
+#include <aknenv.h>
+#include <aknsettingcache.h>
+#include <eikedwin.h>
+#include <txtrich.h>
+#include "akncursormanager.h"
+#include "akninputpolicy.h"
+
+CAknInputPolicyManager* CAknInputPolicyManager::NewL(CEikEdwin* aEdwin)
+	{
+	CAknInputPolicyManager* self = new (ELeave) CAknInputPolicyManager(aEdwin);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+	}
+
+CAknInputPolicyManager::~CAknInputPolicyManager()
+	{
+	}
+
+void CAknInputPolicyManager::HandleInputPolicyManagerEventL(TEventType aEvent, TInt /*aData1*/, TAny* /*aData2*/)
+	{
+	switch (aEvent)
+		{
+		case ECMEventNull:
+			break;
+		case ECMEventInitialise:
+			if (iEdwin->TextLength() == 0)
+				SetCursorUsingLanguageL();
+			break;
+		case ECMEventInlineEditUpdate:
+			break;
+		case ECMEventInsertion:
+			break;
+		case ECMEventDeletion:
+			if (iEdwin->TextLength() == 0)
+				SetCursorUsingLanguageL();
+			else
+				NormaliseCursorPositionFollowingDeleteL();
+			break;
+		case ECMEventNavigation:
+			NormaliseCursorPositionFollowingNavigationL();
+			break;
+		default:
+			break;
+		}
+	}
+
+CAknInputPolicyManager::CAknInputPolicyManager(CEikEdwin* aEdwin) :
+	iEdwin(aEdwin)
+	{
+	}
+
+void CAknInputPolicyManager::ConstructL()
+	{
+	}
+
+
+void CAknInputPolicyManager::NormaliseCursorPositionFollowingDeleteL()
+	{
+	CAknCursorManager* cursorManager = CAknCursorManager::NewL(iEdwin->EditorState());
+	CleanupStack::PushL(cursorManager);
+
+	TTmDocPosSpec pos = cursorManager->DocPos();
+	CTmTextLayout::TTmChunkDescription leftChunk;
+	CTmTextLayout::TTmChunkDescription rightChunk;
+	iEdwin->TextLayout()->TagmaTextLayout().FindAdjacentChunks(pos, leftChunk, rightChunk);
+
+	TBool isRTLPara = cursorManager->IsRightToLeftParagraph(pos);
+	if (!isRTLPara && leftChunk.iRightToLeft ||
+		isRTLPara && !rightChunk.iRightToLeft)
+		cursorManager->ToggleVisualDocPosL();
+	
+	CleanupStack::PopAndDestroy(); // cursorManager
+	}
+
+void CAknInputPolicyManager::NormaliseCursorPositionFollowingNavigationL()
+	{
+	CAknCursorManager* cursorManager = CAknCursorManager::NewL(iEdwin->EditorState());
+	CleanupStack::PushL(cursorManager);
+
+	if (cursorManager->VisualCursorBetweenOpposingChunks())
+		{
+		TTmDocPosSpec pos = cursorManager->DocPos();
+		CTmTextLayout::TTmChunkDescription leftChunk;
+		CTmTextLayout::TTmChunkDescription rightChunk;
+		iEdwin->TextLayout()->TagmaTextLayout().FindAdjacentChunks(pos, leftChunk, rightChunk);
+
+		CAknSettingCache& cache = CAknEnv::Static()->SettingCache();
+		TLanguage currentLanguage = cache.InputLanguage();
+
+		if (leftChunk.iStart == -1)
+			{ // left end of a line
+			if (rightChunk.iRightToLeft)
+				{ // set doc pos trailing at the end of the right chunk
+				pos.iType = TTmDocPosSpec::ETrailing;
+				pos.iPos = rightChunk.iEnd;
+				}
+			else // rightChunk is LTR
+				{ // set doc pos leading at start of right chunk
+				pos.iType = TTmDocPosSpec::ELeading;
+				pos.iPos = rightChunk.iStart;
+				}
+			}
+		else if (rightChunk.iStart == -1)
+			{ // right end of a line
+			if (leftChunk.iRightToLeft)
+				{ // set doc pos leading at start of left chunk
+				pos.iType = TTmDocPosSpec::ELeading;
+				pos.iPos = leftChunk.iStart;
+				}
+			else // leftChunk is LTR
+				{ // set doc pos trailing at the end of the left chunk
+				pos.iType = TTmDocPosSpec::ETrailing;
+				pos.iPos = leftChunk.iEnd;
+				}
+			}
+
+		else // middle of a line
+			{
+			currentLanguage &= KAknLanguageMask;
+			if (currentLanguage == ELangArabic || currentLanguage == ELangHebrew)
+				{
+				if (rightChunk.iRightToLeft)
+					{ // set doc pos trailing at the end of the right chunk
+					pos.iType = TTmDocPosSpec::ETrailing;
+					pos.iPos = rightChunk.iEnd;
+					}
+				else // rightChunk is LTR
+					{ // set doc pos leading at start of left chunk
+					pos.iType = TTmDocPosSpec::ELeading;
+					pos.iPos = leftChunk.iStart;
+					}
+				}
+			else // language is LTR
+				{
+				if (rightChunk.iRightToLeft)
+					{ // set doc pos trailing at the end of left chunk
+					pos.iType = TTmDocPosSpec::ETrailing;
+					pos.iPos = leftChunk.iEnd;
+					}
+				else // rightChunk is LTR
+					{ // set doc pos leading at the start of right chunk
+					pos.iType = TTmDocPosSpec::ELeading;
+					pos.iPos = rightChunk.iStart;
+					}
+				}
+			}
+		// set the doc position...
+		cursorManager->SetDocPosL(pos);
+		}
+	CleanupStack::PopAndDestroy(); // cursorManager
+	}
+
+void CAknInputPolicyManager::SetCursorUsingLanguageL()
+	{
+	CAknSettingCache& cache = CAknEnv::Static()->SettingCache();
+	TLanguage currentLanguage = cache.InputLanguage();
+
+	CRichText* rT = static_cast<CRichText*>(iEdwin->Text());
+	CParaFormat* paraF = CParaFormat::NewLC();
+	paraF->iLanguage = currentLanguage;
+	TParaFormatMask langMask;
+	langMask.SetAttrib(EAttParaLanguage);
+	rT->ApplyParaFormatL(paraF, langMask, iEdwin->CursorPos(), 1);
+	iEdwin->TextView()->HandleRangeFormatChangeL(TCursorSelection(0, iEdwin->TextLength()), ETrue);
+
+	CleanupStack::PopAndDestroy(); // paraF
+	}