textrendering/word/SRC/WPTEXTED.CPP
changeset 0 1fb32624e06b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textrendering/word/SRC/WPTEXTED.CPP	Tue Feb 02 02:02:46 2010 +0200
@@ -0,0 +1,533 @@
+/*
+* Copyright (c) 1997-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 "WPTEXTED.H"
+#include <txtrich.h>
+#include <eikenv.h>
+#include <word.rsg>
+#include <baclipb.h>
+#include <conlist.h>
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include "txtfmlyr_internal.h"
+#include <txtclipboard.h>
+#endif
+
+inline TBool IsSurrogate(TText a) { return 0xD800 == (a & 0xF800); }
+inline TBool IsHighSurrogate(TText a) { return 0xD800 == (a & 0xFC00); }
+inline TBool IsLowSurrogate(TText a) { return 0xDC00 == (a & 0xFC00); }
+inline TChar JoinSurrogates(TText aHigh, TText aLow)
+	{
+	return ((aHigh - 0xd7f7) << 10) + aLow;
+	}
+
+
+inline TText16 GetHighSurrogate(TUint aChar)
+	{
+	return STATIC_CAST(TText16, 0xD7C0 + (aChar >> 10));
+	}
+
+inline TText16 GetLowSurrogate(TUint aChar)
+	{
+	return STATIC_CAST(TText16, 0xDC00 | (aChar & 0x3FF));
+	}
+
+
+class CTestCommand : public UndoSystem::CSingleCommand
+	{
+	TInt ExecuteL() const { return KErrNone; }
+	};
+
+TBool CWordUndoGatekeeper::AllowNotUndoableL(TInt aReason)
+	{
+	if (aReason != KErrNotSupported)
+		return MNotUndoableGatekeeper::AllowNotUndoableL(aReason);
+	// ask user if operation should continue
+	return CEikonEnv::Static()->QueryWinL(R_WORD_NOT_UNDOABLE_TITLE, R_WORD_NOT_UNDOABLE_TEXT);
+	}
+
+CWordTextEditor::CWordTextEditor(const TGulBorder& aBorder):
+	CEikRichTextEditor(aBorder)
+	{
+	}
+
+TKeyResponse CWordTextEditor::OfferKeyEventL(const TKeyEvent& /*aKeyEvent*/,TEventCode /*aType*/)
+	{
+	return EKeyWasNotConsumed;
+	}
+
+CWordTextEditor::~CWordTextEditor()
+	{
+	if (iCommandManager)
+		iCommandManager->Release();
+	delete iEditorWithUndo;
+	}
+
+MUnifiedEditor& CWordTextEditor::UnifiedEditor()
+	{
+	ASSERT(iEditorWithUndo);
+	return *iEditorWithUndo;
+	}
+
+const MUnifiedEditor& CWordTextEditor::UnifiedEditor() const
+	{
+	ASSERT(iEditorWithUndo);
+	return *iEditorWithUndo;
+	}
+
+void CWordTextEditor::InitialiseUnifiedEditorL()
+	{
+	iFormAndEtextEditor.Set(*TextView(),*RichText());
+	if (iCommandManager)
+		{
+		iCommandManager->Release();
+		iCommandManager = 0;
+		}
+	delete iEditorWithUndo;
+	iEditorWithUndo = 0;
+	iCommandManager = UndoSystem::CCommandManager::NewL();
+	iEditorWithUndo = CEditorWithUndo::NewL(iFormAndEtextEditor, iCommandManager);
+	iEditorWithUndo->SetGatekeeper(&iGatekeeper);
+	}
+
+void CWordTextEditor::TestRunNotUndoableCommandL()
+	{
+	CTestCommand* command = new(ELeave) CTestCommand;
+	CleanupStack::PushL(command);
+	iCommandManager->ExecuteL(*command);
+	CleanupStack::PopAndDestroy(command);
+	}
+
+void CWordTextEditor::InsertCharacterL(TChar aCharacter)
+	{
+	if ( aCharacter < 0x10000 )
+		{
+		//    Only surrogate high part or low part is inserted
+		//    Ignore it
+		if ( IsSurrogate( aCharacter ) )
+		    return;
+		
+		TText c = (TText)aCharacter;
+		TPtrC p(&c, 1);
+		InsertTextL(iTextView->Selection().LowerPos(), p);
+		}
+	else
+		{
+		TText c[2];
+		c[0] = GetHighSurrogate( aCharacter );
+		c[1] = GetLowSurrogate( aCharacter );
+		TPtrC p(c, 2);
+		InsertTextL(iTextView->Selection().LowerPos(), p);
+		}
+	}
+
+TBool CWordTextEditor::DeleteSelectionL()
+	{
+	TCursorSelection sel = iTextView->Selection();
+	if (sel.Length())
+		{
+		DeleteTextL(sel.LowerPos(),sel.Length());
+		return TRUE;
+		}
+	else
+		return FALSE;
+	}
+
+void CWordTextEditor::DeleteLeftL()
+	{
+	if (!DeleteSelectionL())
+		{
+		TCursorSelection sel = iTextView->Selection();
+		if (sel.iCursorPos > 0)
+			DeleteTextL(sel.iCursorPos - 1, 1);
+		}
+	}
+
+void CWordTextEditor::DeleteRightL()
+	{
+	if (!DeleteSelectionL())
+		{
+		TCursorSelection sel = iTextView->Selection();
+		if (sel.iCursorPos < DocumentLength())
+			DeleteTextL(sel.iCursorPos, 1);
+		}
+	}
+
+void CWordTextEditor::HighlightL(TUint aEffects)
+	{
+	TTmCharFormatLayer format;
+	format.iFormat.iEffects = aEffects;
+	format.iFormat.iBackgroundColor = KRgbYellow;
+	format.iMask.iFlags = TTmCharFormatMask::EBackground | TTmCharFormatMask::EBackgroundColor |
+						  TTmCharFormatMask::EUnderline | TTmCharFormatMask::EStrikethrough |
+						  TTmCharFormatMask::EShadow | TTmCharFormatMask::EUserDefinedEffects;
+	TCursorSelection sel = iTextView->Selection();
+	UnifiedEditor().SetCharFormatL(sel.LowerPos(),sel.Length(),format);
+	}
+
+void CWordTextEditor::RemoveHighlightL(TUint)
+	{
+	TCursorSelection sel = iTextView->Selection();
+	TInt pos = sel.LowerPos();
+	TInt length = sel.Length();
+
+	TInt allowedFlags = ~(TTmCharFormatMask::EBackground | TTmCharFormatMask::EBackgroundColor |
+						  TTmCharFormatMask::EUnderline | TTmCharFormatMask::EStrikethrough |
+						  TTmCharFormatMask::EShadow | TTmCharFormatMask::EUserDefinedEffects);
+	if (length == 0)
+		{
+		CRichText* rtext = RichText();
+		TCharFormat tcf;
+		TTmCharFormatMask notAllowed;
+		notAllowed.iFlags = ~allowedFlags;
+		TCharFormatMask tcfm;
+		notAllowed.GetTCharFormatMask(tcfm);
+		if (rtext)
+			rtext->SetInsertCharFormatL(tcf, tcfm, pos);
+		return;
+		}
+
+	iCommandManager->BeginBatchLC();
+	MUnifiedEditor& ed = UnifiedEditor();
+	while (0 < length)
+		{
+		TTmCharFormatLayer format;
+		TInt runLength;
+		ed.GetCharFormat(pos,
+			MUnifiedEditor::ESpecific, format, runLength);
+		format.iMask.iFlags &= allowedFlags;
+		ed.DeleteCharFormatL(pos, length);
+		ed.SetCharFormatL(pos, length, format);
+		pos += runLength;
+		length -= runLength;
+		}
+
+	CleanupStack::PopAndDestroy();	// batch
+	}
+
+CWordTextEditor::TAttributeValue CWordTextEditor::IsHighlighted(TUint aEffects) const
+	{
+	TCursorSelection sel = iTextView->Selection();
+	TInt pos = sel.LowerPos();
+	TInt length = sel.Length();
+	const CRichText* rtext = RichText();
+	if (length == 0 && rtext)
+		{
+		// need to find out if there is a zero length phrase. There is no
+		// concept of this in MUnifiedEditor
+		TCharFormat tcf;
+		TCharFormatMask tcfm;
+		rtext->GetCharFormat(tcf, tcfm, pos, 0);
+		TTmCharFormat charFormat;
+		charFormat = tcf;
+		return (charFormat.iEffects & aEffects) == aEffects?
+			EAttributeSet : EAttributeClear;
+		}
+	TUint retval = 0;
+	while (retval != EAttributeIndeterminate && 0 < length)
+		{
+		TTmCharFormatLayer format;
+		TInt runLength;
+		UnifiedEditor().GetCharFormat(pos,
+			MUnifiedEditor::EEffective, format, runLength);
+		if ((format.iFormat.iEffects & aEffects) == aEffects)
+			retval |= EAttributeSet;
+		else
+			retval |= EAttributeClear;
+		pos += runLength;
+		length -= runLength;
+		}
+
+	return static_cast<TAttributeValue>(retval);
+	}
+
+void CWordTextEditor::ToggleHighlightL(TUint aEffects)
+	{
+	if (IsHighlighted(aEffects) == EAttributeSet)
+		RemoveHighlightL(aEffects);
+	else
+		HighlightL(aEffects);
+	}
+
+void CWordTextEditor::BoldItalicUnderlineEventL(TInt aFontFlag)
+	{
+	TCursorSelection sel = iTextView->Selection();
+	if (sel.Length())
+		{
+		TTmCharFormatLayer old_format;
+		TInt run_length;
+		GetCharFormat(sel.LowerPos(),MUnifiedEditor::EEffective,old_format,run_length);
+		TTmCharFormatLayer new_format;
+		new_format.iMask.iFlags = 0;
+		if (aFontFlag & EBold)
+			{
+			new_format.iMask.Set(TTmCharFormatMask::EBold);
+			new_format.iFormat.iFontSpec.SetBold(!old_format.iFormat.iFontSpec.IsBold());
+			}
+		if (aFontFlag & EItalic)
+			{
+			new_format.iMask.Set(TTmCharFormatMask::EItalic);
+			new_format.iFormat.iFontSpec.SetItalic(!old_format.iFormat.iFontSpec.IsItalic());
+			}
+		if (aFontFlag & EUnderline)
+			{
+			new_format.iMask.Set(TTmCharFormatMask::EUnderline);
+			if (!(old_format.iFormat.iEffects & TTmCharFormat::EUnderline))
+				new_format.iFormat.iEffects |= TTmCharFormat::EUnderline;
+			}
+		SetCharFormatL(sel.LowerPos(),sel.Length(),new_format);
+		}
+	else
+		CEikGlobalTextEditor::BoldItalicUnderlineEventL(aFontFlag);
+	}
+
+TInt CWordTextEditor::DocumentLength() const
+	{
+	return UnifiedEditor().DocumentLength();
+	}
+
+void CWordTextEditor::GetText(TInt aPos,TPtrC& aText) const
+	{
+	UnifiedEditor().GetText(aPos,aText);
+	}
+
+void CWordTextEditor::GetBaseFormatL(TTmCharFormat& aCharFormat,RTmParFormat& aParFormat) const
+	{
+	UnifiedEditor().GetBaseFormatL(aCharFormat,aParFormat);
+	}
+
+void CWordTextEditor::GetCharFormat(TInt aPos,TFormatLevel aLevel,
+		TTmCharFormatLayer& aFormat,TInt& aRunLength) const
+	{
+	UnifiedEditor().GetCharFormat(aPos,aLevel,aFormat,aRunLength);
+	}
+
+void CWordTextEditor::GetParFormatL(TInt aPos,TFormatLevel aLevel,
+		RTmParFormatLayer& aFormat,TInt& aRunLength) const
+	{
+	UnifiedEditor().GetParFormatL(aPos,aLevel,aFormat,aRunLength);
+	}
+
+void CWordTextEditor::InsertTextL(TInt aPos,const TDesC& aText,
+		 const TDesC* aStyle,
+		 const TTmCharFormatLayer* aCharFormat,
+		 const RTmParFormatLayer* aParFormat)
+	{
+	DeleteSelectionL();
+	UnifiedEditor().InsertTextL(aPos,aText,aStyle,aCharFormat,aParFormat);
+	UpdateScrollBarsL();
+	}
+
+void CWordTextEditor::DeleteTextL(TInt aPos,TInt aLength)
+	{
+	UnifiedEditor().DeleteTextL(aPos,aLength);
+	UpdateScrollBarsL();
+	}
+
+void CWordTextEditor::SetBaseFormatL(const TTmCharFormat& aCharFormat,const RTmParFormat& aParFormat)
+	{
+	UnifiedEditor().SetBaseFormatL(aCharFormat,aParFormat);
+	UpdateScrollBarsL();
+	}
+
+void CWordTextEditor::SetCharFormatL(TInt aPos,TInt aLength,const TTmCharFormatLayer& aFormat)
+	{
+	UnifiedEditor().SetCharFormatL(aPos,aLength,aFormat);
+	UpdateScrollBarsL();
+	}
+
+void CWordTextEditor::SetParFormatL(TInt aPos,TInt aLength,const RTmParFormatLayer& aFormat)
+	{
+	UnifiedEditor().SetParFormatL(aPos,aLength,aFormat);
+	UpdateScrollBarsL();
+	}
+
+void CWordTextEditor::DeleteCharFormatL(TInt aPos,TInt aLength)
+	{
+	UnifiedEditor().DeleteCharFormatL(aPos,aLength);
+	UpdateScrollBarsL();
+	}
+
+void CWordTextEditor::DeleteParFormatL(TInt aPos,TInt aLength)
+	{
+	UnifiedEditor().DeleteParFormatL(aPos,aLength);
+	UpdateScrollBarsL();
+	}
+
+MTmOptionalInterface* CWordTextEditor::Interface(TUint aId)
+	{
+	return UnifiedEditor().Interface(aId);
+	}
+
+void CWordTextEditor::HandleResourceChange(TInt aType)
+	{
+	CEikBorderedControl::HandleResourceChange(aType);
+	switch (aType)
+		{
+	case KEikMessageCapsLock:
+		break;
+	case KEikMessageVirtualCursorStateChange:
+		{
+		TEikVirtualCursor& cursor=iEikonEnv->VirtualCursor();
+		if(!(iEdwinUserFlags&EIgnoreVirtualCursor) && IsFocused()
+			&& cursor.CursorState(*iEikonEnv)==TEikVirtualCursor::EOn)
+			{
+			// This doesn't leave
+			cursor.SetCursorStateL(TEikVirtualCursor::ESuspended,*iEikonEnv);
+			}
+		}
+		break;
+	default:
+		break;
+		}
+
+	}
+
+void CWordTextEditor::FocusChanged(TDrawNow /*aDrawNow*/)
+	{
+	if (!iTextView)
+		return;
+	const TBool focused=IsFocused();
+	const TCursor::TVisibility textCursor=(focused? TCursor::EFCursorFlashing : TCursor::EFCursorInvisible);
+	const TCursor::TVisibility lineCursor=((iEdwinUserFlags&ELineCursor && focused)? 
+										TCursor::EFCursorVisible : TCursor::EFCursorInvisible);
+	TRAPD(ignored,iTextView->SetCursorVisibilityL(lineCursor,textCursor));
+	if (!focused && iEdwinUserFlags&EAlwaysShowSelection)
+		;
+	else
+		{
+		TRAP(ignored,iTextView->SetSelectionVisibilityL(focused)); // !! inefficient
+		}
+	//TRAP(ignored,SetVirtualCursorStateL(focused));	// virtual cursor not supported in RefUi word.
+	}
+
+TInt CWordTextEditor::ClipboardPasteL()
+	{
+	MUnifiedEditor::MClipboardSupport* ci = iEditorWithUndo->ClipboardSupport();
+	if (!ci)
+		return KErrNotSupported;
+	CClipboard* cb = CClipboard::NewForReadingLC(iCoeEnv->FsSession());
+	if (cb->StreamDictionary().At(KClipboardUidTypePlainText) == KNullStreamId)
+		{
+		CleanupStack::PopAndDestroy(cb);
+		return KErrNotFound;
+		}
+	iCommandManager->BeginBatchLC();		// batch together the delete and insert
+
+	DeleteSelectionL();
+	ci->PasteFromStoreL(cb->Store(), cb->StreamDictionary(),
+		iTextView->Selection().iCursorPos);
+
+	CleanupStack::PopAndDestroy();		// close batch
+	CleanupStack::PopAndDestroy(cb);
+	UpdateScrollBarsL();
+
+	return KErrNone;
+	}
+
+void CWordTextEditor::ClipboardCutL()
+	{
+	ClipboardCopyL();
+	DeleteSelectionL();
+	}
+
+void CWordTextEditor::ClipboardCopyL() const
+	{
+	MUnifiedEditor::MClipboardSupport* ci = iEditorWithUndo->ClipboardSupport();
+	if (!ci)
+		return;
+	TCursorSelection sel = iTextView->Selection();
+	if (!sel.Length())
+		return;
+	CClipboard* cb = CClipboard::NewForWritingLC(iCoeEnv->FsSession());
+	ci->CopyToStoreL(cb->Store(), cb->StreamDictionary(), sel.LowerPos(), sel.Length());
+	cb->CommitL();
+	CleanupStack::PopAndDestroy(cb);
+	}
+
+void CWordTextEditor::SetBookmark()
+	{
+	iCommandManager->SetBookmark();
+	}
+
+TBool CWordTextEditor::IsAtBookmark() const
+	{
+	return iCommandManager->IsAtBookmark();
+	}
+
+void CWordTextEditor::ResetUndo()
+	{
+	iCommandManager->ResetUndo();
+	}
+
+void CWordTextEditor::InsertFromHtmlFileL(const TDesC& aFileName)
+	{
+	//get converter
+	CCnaConverterList* convList=CCnaConverterList::NewLC();
+	const TUid KUidCHtmlToCrtConverter = {0x1000a90e};
+	CConverterBase* conv = convList->NewConverterL(KUidCHtmlToCrtConverter);
+
+	if (conv)
+		{
+		//do conversion
+		CleanupStack::PushL(conv);
+		
+		_LIT(KTempRichTextDestinationFile, "_:\\System\\Temp\\TempRichText");
+		TFileName richtextdestFile(KTempRichTextDestinationFile);
+		richtextdestFile[0] = 'A' + static_cast<TInt>(RFs::GetSystemDrive());
+		
+		conv->ConvertL(aFileName, richtextdestFile);	
+		CleanupStack::PopAndDestroy(conv);
+
+		CancelFepTransaction();
+		const TInt oldLength = iText->DocumentLength();
+		const TInt cursorPos=CursorPos();
+		CDirectFileStore* directFileStore=CDirectFileStore::OpenLC(iCoeEnv->FsSession(), richtextdestFile, EFileShareReadersOnly);
+		TStreamId streamId(directFileStore->Root());
+		RStoreReadStream readStream;
+		CStreamDictionary* dictionary=CStreamDictionary::NewLC();
+		readStream.OpenLC(*directFileStore, streamId);
+		readStream>>*dictionary;
+		User::LeaveIfError(iText->PasteFromStoreL(*directFileStore, *dictionary, cursorPos));
+
+		CleanupStack::PopAndDestroy(3);//readStream, dictionary, directFileStore
+		iCoeEnv->FsSession().Delete(richtextdestFile);
+
+		const TInt KFullFormattingUpperThreshold=2000;//already defined in \uikon\coctlsrc\eikedwin.cpp
+
+		CheckValidityOfChars(oldLength,(iText->DocumentLength()-oldLength));
+		const TInt newLength=iText->DocumentLength();
+		const TInt newCursorPos=cursorPos+newLength-oldLength;
+		iTextView->SetPendingSelection(TCursorSelection(newCursorPos,newCursorPos));
+		if (newLength>KFullFormattingUpperThreshold &&
+			oldLength<=KFullFormattingUpperThreshold)
+			SetAmountToFormatL();
+		else
+			iTextView->HandleInsertDeleteL(TCursorSelection(newCursorPos,cursorPos),0,ETrue);
+		DrawContents();
+		UpdateScrollBarsL();
+		ReportEventL(MCoeControlObserver::EEventStateChanged);
+		iEikonEnv->BusyMsgCancel();
+		}
+	else
+		{
+		iEikonEnv->InfoMsg(R_WORD_NO_HTML_CONVERTER);
+		}
+
+	CleanupStack::PopAndDestroy(convList);
+	}