diff -r 000000000000 -r 2f259fa3e83a uifw/eikctl/src/EIKRTED.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uifw/eikctl/src/EIKRTED.CPP Tue Feb 02 01:00:49 2010 +0200 @@ -0,0 +1,892 @@ +/* +* Copyright (c) 1997-1999 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef SYMBIAN_ENABLE_SPLIT_HEADERS +#include +#else +#include +#include +#include +#endif +#include +#include +#include +#include +#include +#include + +#include +GLDEF_C void Panic(TEikEdwinPanic aPanic) + { + _LIT(KPanicCat,"EIKON-EDWIN"); + User::Panic(KPanicCat,aPanic); + } + +// +// class CEikParserManager +// + +const TInt KParseScanDelay =750000; // 0.75s +const TInt KNullStartPos =-1; + +NONSHARABLE_CLASS(CEikParserManager) : public CBase, public MEikEdwinObserver + { +public: + static CEikParserManager* NewL(CEikRichTextEditor& aEditor); + ~CEikParserManager(); +public: + void SetParserObserver(MEikRichTextEditorParserObserver* aObserver); + void Start(TInt aStartPos,TInt aLength); +private: + CEikParserManager(CEikRichTextEditor& aEditor); + void ConstructL(); + void Start(); + void StartTimer(); + void Reset(); + static TInt ParseTextCallbackL(TAny* aSelf); + void ParseTextL(); +private: // from MEikEdwinObserver + void HandleEdwinEventL(CEikEdwin* aEdwin,TEdwinEvent aEventType); +private: + CPeriodic* iTimer; + CEikRichTextEditor& iEditor; + MEikRichTextEditorParserObserver* iParserObserver; + TInt iStartPos; // start of changed area + TInt iLength; // length of changed area + MParser* iParser; + TInt iTagStart; // start of tag cursor is over + TInt iTagLength; // length of tag cursor is over + TBool iStateChanged; + TBool iParseWholeText; + +public: // new methods + void ForceFullParseL(); + + }; + +CEikParserManager* CEikParserManager::NewL(CEikRichTextEditor& aEditor) + { // static + CEikParserManager* self=new(ELeave) CEikParserManager(aEditor); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); // self + return self; + } + +CEikParserManager::~CEikParserManager() + { + if (iTimer) + iTimer->Cancel(); + delete iTimer; + } + +void CEikParserManager::SetParserObserver(MEikRichTextEditorParserObserver* aObserver) + { + iParserObserver=aObserver; + } + +void CEikParserManager::Start(TInt aStartPos,TInt aLength) + { + if (iStartPos==KNullStartPos) + iStartPos=aStartPos; + else + iStartPos=Min(iStartPos,aStartPos); + if (iLength==0 || aLength>=0) + iLength=Max(iLength,aLength); + else // aLength<0 + iLength=Max(iLength+aLength,0); + iStateChanged=ETrue; + StartTimer(); + } + +CEikParserManager::CEikParserManager(CEikRichTextEditor& aEditor) + : iEditor(aEditor) + { + Reset(); + } + +void CEikParserManager::ConstructL() + { + iTimer=CPeriodic::NewL(CActive::EPriorityStandard); + iEditor.AddEdwinObserverL(this); + } + +void CEikParserManager::Start() + { + StartTimer(); + } + +void CEikParserManager::StartTimer() + { + if (iTimer->IsActive()) + iTimer->Cancel(); + iTimer->Start(KParseScanDelay,KParseScanDelay,TCallBack(ParseTextCallbackL,this)); + } + +void CEikParserManager::Reset() + { + iStartPos=KNullStartPos; + iLength=0; + } + +TInt CEikParserManager::ParseTextCallbackL(TAny* aSelf) + { // static + REINTERPRET_CAST(CEikParserManager*,aSelf)->ParseTextL(); + return 0; + } + +void CEikParserManager::ParseTextL() + { + TInt startPos=iStartPos; + TInt length=iLength; + Reset(); + iTimer->Cancel(); + const TBool foundParser=(iStateChanged && iEditor.RichText()->ParseText(startPos,length,iParseWholeText)); + iStateChanged=EFalse; + MParser* parser=iParser; + TInt tagStart=iTagStart; + TInt tagLength=iTagLength; + TInt err=KErrNone; + TBool overNewTag=EFalse; + if (iEditor.RichText()->CursorOverTag(iEditor.CursorPos(),parser,tagStart,tagLength)) + { + // are we over a new tag? Update members if so + if ((TInt)parser!=(TInt)iParser || tagStart!=iTagStart || tagLength!=iTagLength) + { + overNewTag=ETrue; + iParser=parser; + if (iTagStart!=KNullStartPos) + { + TRAP(err,iEditor.TextView()->HandleRangeFormatChangeL(TCursorSelection(iTagStart,iTagStart+iTagLength),ETrue)); + } + iTagStart=tagStart; + iTagLength=tagLength; + // the tag may be drawn differently when the cursor is over it + TRAP(err,iEditor.TextView()->HandleRangeFormatChangeL(TCursorSelection(tagStart,tagStart+tagLength),ETrue)); + } + } + else + { + if (iParser) + { + overNewTag=ETrue; // if iParser!=NULL, we used to be over a tag and are now over a null one + // the tag may be drawn differently now the cursor isn't over it + TRAP(err,iEditor.TextView()->HandleRangeFormatChangeL(TCursorSelection(iTagStart,iTagStart+iTagLength),ETrue)); + } + iParser=NULL; + iTagStart=KNullStartPos; + iTagLength=0; + } + if (foundParser && (startPos!=tagStart || length!=tagLength)) + { + // newly identified parser is different from the one the cursor is over so... + // change the text format for the parser also + TRAPD(err2,iEditor.TextView()->HandleRangeFormatChangeL(TCursorSelection(startPos,startPos+length),ETrue)); + if (err==KErrNone) + err=err2; + } + if (overNewTag && iParserObserver) + { + if (iParser) + { + iParserObserver->HandleCursorOverParserL(iParser->CreateDoItText(*(iEditor.RichText()),startPos,length)); + } + else + { + TBuf<4> nullText(KNullDesC); + iParserObserver->HandleCursorOverParserL(nullText); + } + } + User::LeaveIfError(err); + } + +void CEikParserManager::HandleEdwinEventL(CEikEdwin* aEdwin,TEdwinEvent aEventType) + { + if ((TInt)aEdwin==(TInt)&iEditor && aEventType==MEikEdwinObserver::EEventNavigation) + Start(); + } + +void CEikParserManager::ForceFullParseL() + { + iParseWholeText = ETrue; + iStateChanged = ETrue; + ParseTextL(); + iParseWholeText = EFalse; + } +// +// class CEikRichTextEditor +// + +EXPORT_C CEikRichTextEditor::CEikRichTextEditor() + { + iEdwinUserFlags=EAllowPictures|EAllowUndo; + iEdwinInternalFlags=ERichText; + iDefaultIconicDoorSize=KDefaultIconicDoorSize; + AKNTASHOOK_ADD( this, "CEikRichTextEditor" ); + } + +EXPORT_C CEikRichTextEditor::CEikRichTextEditor(const TGulBorder& aBorder) + : CEikGlobalTextEditor(aBorder) + { + iEdwinUserFlags=EAllowPictures|EAllowUndo; + iEdwinInternalFlags=ERichText; + iDefaultIconicDoorSize=KDefaultIconicDoorSize; + AKNTASHOOK_ADD( this, "CEikRichTextEditor" ); + } + +EXPORT_C CEikRichTextEditor::~CEikRichTextEditor() + { + AKNTASHOOK_REMOVE(); + CRichText* text=RichText(); + if (text) + { + text->SetEditObserver(NULL); + } + delete iEmbeddedDocUpdate; + if (iEmbeddedDoc.iPicture.IsPtr()) + delete iEmbeddedDoc.iPicture.AsPtr(); + delete iParserManager; + } + +EXPORT_C void CEikRichTextEditor::ConstructL(const CCoeControl* aParent,TInt aNumberOfLines,TInt aTextLimit, + TInt aEdwinFlags,TInt aFontControlFlags,TInt aFontNameFlags) + { + CEikGlobalTextEditor::ConstructL(aParent,aNumberOfLines,aTextLimit,aEdwinFlags,aFontControlFlags,aFontNameFlags); + CommonConstructL(); + } + +EXPORT_C void CEikRichTextEditor::ConstructFromResourceL(TResourceReader& aReader) + { + CEikGlobalTextEditor::ConstructFromResourceL(aReader); + CommonConstructL(); + } + +void CEikRichTextEditor::CommonConstructL() + { + iEmbeddedDocUpdate=CIdle::NewL(EActivePriorityWsEvents+1); + if (!(iEdwinUserFlags&ENoTextParsers)) + iParserManager=CEikParserManager::NewL(*this); + } + +EXPORT_C void CEikRichTextEditor::Draw(const TRect& aRect) const + { + CEikEdwin::Draw(aRect); + } + +EXPORT_C TKeyResponse CEikRichTextEditor::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) + { + if (aType!=EEventKey) + return EKeyWasNotConsumed; + if (iEdwinUserFlags&EDisplayOnly) + return EKeyWasConsumed; + const TInt code=aKeyEvent.iCode; + if ((code==EKeySpace || code==EKeyEnter) && CheckForObjectL()) + return EKeyWasConsumed; + const TInt modifiers=aKeyEvent.iModifiers; + if (modifiers&EModifierCtrl) + { + TBool consumed=ETrue; + TBuf<24> buf; + if (aKeyEvent.iModifiers&EModifierShift) + iCoeEnv->ReadResource(buf,R_EIK_EDWIN_SHIFT_CTRL_HOTKEYS); + else + iCoeEnv->ReadResource(buf,R_EIK_EDWIN_CTRL_HOTKEYS); + const TInt pos=buf.Locate(TChar(code+'a'-1)); + switch (pos) + { + case EHotKeyInsertObject: + CheckNotReadOnlyL(); + if (!(iEdwinUserFlags&EAllowPictures)) + iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_CANNOT_INSERT_OBJECTS); + InsertObjectL(EGlassIfPossible); + break; + case EHotKeyEditObject: + CheckNotReadOnlyL(); + if (!(iEdwinUserFlags&EAllowPictures)) + return EKeyWasConsumed; + ReEditObjectL(); + break; + case EHotKeyFormatObject: + CheckNotReadOnlyL(); + if (!(iEdwinUserFlags&EAllowPictures)) + return EKeyWasConsumed; + EditPictureFormatL(); + break; + default: + consumed=EFalse; + } + if (consumed) + return EKeyWasConsumed; + } + TKeyResponse response=CEikGlobalTextEditor::OfferKeyEventL(aKeyEvent,aType); + UpdateButtonGroup(); + return response; + } + +EXPORT_C void CEikRichTextEditor::HandlePointerEventL(const TPointerEvent& aPointerEvent) + { + CEikEdwin::HandlePointerEventL(aPointerEvent); + } + +EXPORT_C void* CEikRichTextEditor::ExtensionInterface( TUid /*aInterface*/ ) + { + return NULL; + } + +EXPORT_C void CEikRichTextEditor::ActivateL() + { + SetTextObserver(*RichText()); + const TInt docLength=iText->DocumentLength(); + if( iParserManager ) + iParserManager->Start(0,docLength); + UpdatePictureFormatL(0,docLength); + UpdatePictureSizeL(0,docLength); + CEikGlobalTextEditor::ActivateL(); + } + +EXPORT_C void CEikRichTextEditor::HandleTextPastedL(TInt aStartPos,TInt& aLength) + { + UpdatePictureFormatL(aStartPos,aLength); + UpdatePictureSizeL(aStartPos,aLength); + } + +EXPORT_C void CEikRichTextEditor::NotifyExit(TExitMode aMode) + { + if (aMode==MApaEmbeddedDocObserver::EEmpty) + { + if (iEdwinInternalFlags&EReEditingObject) + iEmbeddedDocUpdate->Start(TCallBack(CEikRichTextEditor::TryDeleteEmbeddedDocL, this)); + else + iEmbeddedDocUpdate->Start(TCallBack(CEikRichTextEditor::DeleteEmbeddedDoc, this)); + } + else if (aMode==MApaEmbeddedDocObserver::ENoChanges) + { + if (iEdwinInternalFlags&EReEditingObject) + iEmbeddedDoc=TPictureHeader(); + else // apps should call back with EEmpty in this case + iEmbeddedDocUpdate->Start(TCallBack(CEikRichTextEditor::DeleteEmbeddedDoc, this)); + } + else + { + if (iEdwinInternalFlags&EReEditingObject) + iEmbeddedDocUpdate->Start(TCallBack(CEikRichTextEditor::UpdateEmbeddedDocL, this)); + else + iEmbeddedDocUpdate->Start(TCallBack(CEikRichTextEditor::InsertEmbeddedDocL, this)); + } + } + +TInt CEikRichTextEditor::TryDeleteEmbeddedDocL(TAny *aThis) + { // static + CEikRichTextEditor* editor=REINTERPRET_CAST(CEikRichTextEditor*,aThis); + editor->iEdwinInternalFlags&=~EReEditingObject; + if (!(CEikonEnv::Static()->QueryWinL(R_EIK_TBUF_DEL_EMPTY_OBJECT_CONFIRM_1,R_EIK_TBUF_DEL_EMPTY_OBJECT_CONFIRM_2))) + editor->iTextView->HandleRangeFormatChangeL(editor->Selection(),EFalse); + else + { + TInt docPos; + TRect rect; + editor->iTextView->IsPictureFrameSelected(rect,docPos); + TBool changed=EFalse; + editor->DeleteL(changed,TCursorSelection(docPos,docPos+1),ETrue); + editor->iTextView->SetPendingSelection(TCursorSelection(docPos,docPos)); + editor->iTextView->HandleInsertDeleteL(TCursorSelection(docPos,docPos),1,changed); + editor->UpdateScrollBarsL(); + if (changed) + editor->ReportEdwinEventL(MEikEdwinObserver::EEventFormatChanged); + } + editor->ReportEventL(MCoeControlObserver::EEventStateChanged); + editor->UpdateScrollBarsL(); + return 0; + } + +TInt CEikRichTextEditor::DeleteEmbeddedDoc(TAny *aThis) + { // static + CEikRichTextEditor* editor=REINTERPRET_CAST(CEikRichTextEditor*,aThis); + if (editor->iEmbeddedDoc.iPicture.IsPtr()) + delete editor->iEmbeddedDoc.iPicture.AsPtr(); + editor->iEmbeddedDoc=TPictureHeader(); + return 0; + } + +TInt CEikRichTextEditor::InsertEmbeddedDocL(TAny *aThis) + { // static + CEikRichTextEditor* editor=REINTERPRET_CAST(CEikRichTextEditor*,aThis); + TInt err=KErrNone; + if (editor->iEdwinUserFlags&EShowAllPicturesAsIconic) + { + TRAPD(err,STATIC_CAST(CApaDoor*,editor->iEmbeddedDoc.iPicture.AsPtr())->SetFormatToTemporaryIconL()); + if (err) + goto errorCheck; + } + TRAP(err,editor->InsertPictureL(editor->iEmbeddedDoc)); +errorCheck: + editor->iEmbeddedDoc=TPictureHeader(); + User::LeaveIfError(err); + return 0; + } + +TInt CEikRichTextEditor::UpdateEmbeddedDocL(TAny* aThis) + { // static + CEikRichTextEditor* editor=REINTERPRET_CAST(CEikRichTextEditor*,aThis); + editor->iEdwinInternalFlags&=~EReEditingObject; + editor->iText->SetHasChanged(ETrue); + editor->iTextView->HandleRangeFormatChangeL(editor->Selection(),EFalse); + editor->ReportEventL(MCoeControlObserver::EEventStateChanged); + editor->UpdateScrollBarsL(); + return 0; + } + +EXPORT_C void CEikRichTextEditor::CopyDocumentContentL(CGlobalText& aInText,CGlobalText& aOutText) + { + __ASSERT_DEBUG(&aInText,Panic(EEikPanicNullPointer)); + __ASSERT_DEBUG(&aOutText,Panic(EEikPanicNullPointer)); + aOutText.Reset(); + aOutText.SetFieldFactory(CONST_CAST(MTextFieldFactory*,aInText.FieldFactory())); + ((CRichText&)aInText).DetachFromStoreL(CPicture::EDetachFull); + iBufStore=CBufStore::NewLC(4096); + ((CRichText&)aOutText).SetPictureFactory(iEikonEnv->PictureFactory(),this); + TStreamId streamId=aInText.StoreL(*iBufStore); + aOutText.RestoreL(*iBufStore,streamId); + ((CRichText&)aOutText).DetachFromStoreL(CPicture::EDetachFull); + RStoreWriteStream paraWriteStream; + TStreamId paraStreamId=paraWriteStream.CreateLC(*iBufStore); + (aInText.GlobalParaFormatLayer())->ExternalizeL(paraWriteStream); + CleanupStack::PopAndDestroy(); // paraStreamId + RStoreReadStream paraReadStream; + paraReadStream.OpenLC(*iBufStore,paraStreamId); + ((CParaFormatLayer*)(aOutText.GlobalParaFormatLayer()))->InternalizeL(paraReadStream); + CleanupStack::PopAndDestroy(); // paraReadStream + RStoreWriteStream charWriteStream; + TStreamId charStreamId=charWriteStream.CreateLC(*iBufStore); + (aInText.GlobalCharFormatLayer())->ExternalizeL(charWriteStream); + CleanupStack::PopAndDestroy(); // charStreamId + RStoreReadStream charReadStream; + charReadStream.OpenLC(*iBufStore,charStreamId); + ((CCharFormatLayer*)(aOutText.GlobalCharFormatLayer()))->InternalizeL(charReadStream); + CleanupStack::PopAndDestroy(2); // iBufStore and charReadStream + iBufStore=NULL; + } + +EXPORT_C const CStreamStore& CEikRichTextEditor::StreamStoreL(TInt /*aPos*/) const + { + return *iBufStore; + } + +EXPORT_C void CEikRichTextEditor::NewPictureL(TPictureHeader& aHdr,const CStreamStore& aDeferredPictureStore)const + { + iEikonEnv->PictureFactory()->NewPictureL(aHdr,aDeferredPictureStore); + } + +EXPORT_C void CEikRichTextEditor::EditObserver(TInt aStartEdit,TInt aEditLength) + { + if (iParserManager) + iParserManager->Start(aStartEdit,aEditLength); + CEikEdwin::EditObserver(aStartEdit,aEditLength); + } + +EXPORT_C CRichText* CEikRichTextEditor::RichText() const + { + return (CRichText*)iText; + } + +void CEikRichTextEditor::InsertPictureL(const TPictureHeader& aPictureHeader) + { + __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); + __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView)); + TBool formatHasChanged=EFalse; + TCursorSelection selection=iTextView->Selection(); + const TInt selLength=selection.Length(); + const TInt oldLength=iText->DocumentLength(); + TRAPD(err,DoInsertPictureL(formatHasChanged,aPictureHeader)); + if (err!=KErrNone) + { + delete aPictureHeader.iPicture.AsPtr(); + ClearUndo(); + } + if (selLength==0) + { + ClearUndo(); + if (err==KErrNone) + iTextView->HandleCharEditL(CTextLayout::EFCharacterInsert); + } + else + { + const TInt lower=selection.LowerPos(); + selection=TCursorSelection(lower,(err==KErrNone? lower+1 : lower)); + if (err==KErrNone) + SetUndoableText(selection); + if (err==KErrNone || oldLength>iText->DocumentLength()) + iTextView->HandleInsertDeleteL(selection,selLength,formatHasChanged); + } + User::LeaveIfError(err); + ReportEventL(MCoeControlObserver::EEventStateChanged); + UpdateScrollBarsL(); + if (iText->DocumentLength()==UpperFullFormattingLength()+1) + SetAmountToFormatL(); + } + +void CEikRichTextEditor::DoInsertPictureL(TBool& aFormatHasChanged,const TPictureHeader& aPictureHeader) + { + TCursorSelection selection=iTextView->Selection(); + const TInt selLength=selection.Length(); + if (selLength) + { + iTextView->CancelSelectionL(); + SetCursorPosL(selection.LowerPos(),EFalse); + DeleteL(aFormatHasChanged,selection); + } + else if (iTextLimit && TextLength()>=iTextLimit) + { + CEikonEnv::Beep(); + iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_MAX_CHARACTERS_REACHED); + } + STATIC_CAST(CRichText*,iText)->InsertL(CursorPos(),aPictureHeader); + } + +void CEikRichTextEditor::RoomForObjectL() + { + if (iTextLimit && TextLength()>=iTextLimit) + { + CEikonEnv::Beep(); + iEikonEnv->InfoMsg(R_EIK_TBUF_MAX_CHARACTERS_REACHED); + CBaActiveScheduler::LeaveNoAlert(); + } + } + +EXPORT_C void CEikRichTextEditor::InsertObjectL(TObjectFormat aFormat) + { + RoomForObjectL(); + CEikEmbeddableAppList* list=new(ELeave) CEikEmbeddableAppList; + CleanupStack::PushL(list); + list->ConstructL(); + TInt count=list->Count(); + if (!count) + iEikonEnv->InfoMsg(R_EIK_NO_EMBEDDABLE_APPS_FOUND); + else + { + ASSERT(iEikonEnv->CDlgDialogFactory()); + TInt choice=0; + if(iEikonEnv->CDlgDialogFactory()->RunInsertObjectDlgLD(list, choice)) + { + if (!OkToDeleteSelectionL()) + { + CleanupStack::PopAndDestroy(); // list + return; + } + CEikDocument* newDoc=list->CreateEmbeddedDocumentL(choice,iEikonEnv->Process()); + TApaDocCleanupItem cleanup(iEikonEnv->Process(),newDoc); + CleanupStack::PushL(cleanup); + newDoc->NewDocumentL(); + CleanupStack::Pop(); // cleanup + InsertObjectL(newDoc,aFormat); + } + } + CleanupStack::PopAndDestroy(); // list + } + +EXPORT_C void CEikRichTextEditor::InsertObjectL() + { + InsertObjectL(EGlassIfPossible); + } + +EXPORT_C void CEikRichTextEditor::InsertObjectL(const TDesC& /*aAppDllName*/,TUid aAppDllUid,TObjectFormat aFormat) + { + RoomForObjectL(); + if (!OkToDeleteSelectionL()) + return; + CApaDocument* newDoc=NULL; + TRAPD(err,newDoc=iEikonEnv->Process()->AddNewDocumentL(aAppDllUid)); + if (err==KErrNotFound) + iEikonEnv->LeaveWithInfoMsg(R_EIK_EMBEDDED_GENERIC_APP_NOT_FOUND); + else if (err!=KErrNone) + User::Leave(err); + TApaDocCleanupItem cleanup(iEikonEnv->Process(),newDoc); + CleanupStack::PushL(cleanup); + newDoc->NewDocumentL(); + CleanupStack::Pop(); + InsertObjectL(newDoc,aFormat); + } + +void CEikRichTextEditor::InsertObjectL(CApaDocument* aDoc,TObjectFormat aFormat) + { + iEmbeddedDoc.iPictureType=KUidPictureTypeDoor; + iEmbeddedDoc.iPicture=CApaDoor::NewL(iEikonEnv->FsSession(),*aDoc,iDefaultIconicDoorSize); // takes ownership of newDoc + // can it draw as glass? change format if so + if (aFormat==EGlassIfPossible) + { + TRAP_IGNORE(STATIC_CAST(CApaDoor*,iEmbeddedDoc.iPicture.AsPtr())->SetFormatToGlassL()); + } + aDoc->EditL(this); + } + +EXPORT_C void CEikRichTextEditor::InsertObjectL(TUid aPictureType,CBase* aData) + { + MEikPictureFactory* factory=iEikonEnv->ExtendedPictureFactory(aPictureType); + if (factory==NULL) + { + User::Leave(KErrNotSupported); + } + TPictureHeader pic=factory->InsertL(aPictureType,aData); + InsertPictureL(pic); + } + +EXPORT_C TBool CEikRichTextEditor::CheckForObjectL() + { + TRect frameRect; + TInt docPos; + if (!iTextView->IsPictureFrameSelected(frameRect,docPos)) + return EFalse; + const TPictureHeader header=((CRichText*)iText)->PictureHeader(docPos); + if (header.iPictureType==KNullUid) + return EFalse; + // stop multiple pointer events launching the same apps several times ??? + iCoeEnv->WsSession().PurgePointerEvents(); + DoReEditObjectL(docPos); + return ETrue; + } + +EXPORT_C void CEikRichTextEditor::ReEditObjectL() + { + const TInt pos=ObjectCursorPos(); + if (pos!=KErrNotFound) + DoReEditObjectL(pos); + } + +EXPORT_C TInt CEikRichTextEditor::ObjectCursorPos() const + { + if (SelectionLength()>1) + { + iEikonEnv->InfoMsg(R_EIK_REGION_SELECTED); + return KErrNotFound; + } + TRect frameRect; + TInt docPos; + if (iTextView->IsPictureFrameSelected(frameRect,docPos)) + { + TPictureHeader header=STATIC_CAST(CRichText*,iText)->PictureHeader(docPos); + if (header.iPictureType!=KNullUid) + return docPos; + } + iEikonEnv->InfoMsg(R_EIK_NO_OBJECT_PRESENT); // no embedded object found + return KErrNotFound; + } + +void CEikRichTextEditor::DoReEditObjectL(TInt aDocPos) + { + TPictureHeader header=RichText()->PictureHeader(aDocPos); + if (header.iPictureType==KUidPictureTypeDoor) + { + CApaDoor* door=NULL; + CApaDocument* embeddedDoc=NULL; + GetEmbeddedAppL(door,embeddedDoc,aDocPos); + iEdwinInternalFlags|=EReEditingObject; + embeddedDoc->EditL(this,IsReadOnly()); + } + else + { + MEikPictureFactory* factory=iEikonEnv->ExtendedPictureFactory(header.iPictureType); + if (factory==NULL) + { + User::Leave(KErrNotSupported); + } + factory->EditL(header,IsReadOnly()); + } + } + +EXPORT_C void CEikRichTextEditor::EditPictureFormatL() + { + const TInt docPos=ObjectCursorPos(); + if (docPos==KErrNotFound) + return; + CApaDoor* door=NULL; + CApaDocument* embeddedDoc=NULL; + GetEmbeddedAppL(door,embeddedDoc,docPos); + // if the doc can display as glass open the full dialog + CApaDocument::TCapability capability=embeddedDoc->Capability(); + MEikCDlgDialogFactory* cdlgDialogFactory = iEikonEnv->CDlgDialogFactory(); + ASSERT(cdlgDialogFactory); + if (capability.CanDrawGlass()) + { + if(cdlgDialogFactory->RunFormatObjectDlgLD(*door, *embeddedDoc, iDefaultIconicDoorSize)) + { + iText->SetHasChanged(ETrue); + iTextView->HandleRangeFormatChangeL(iTextView->Selection(),EFalse); + UpdateScrollBarsL(); + ReportEventL(MCoeControlObserver::EEventStateChanged); + // update the picture size in the header when this becomes possible (post B4 etext) + } + } + else + {// otherwise open the little dialog that does nothing... + cdlgDialogFactory->RunObjectInfoDlgLD(*(door->Caption())); + } + } + + +EXPORT_C void CEikRichTextEditor::PictureFormatChangedL() + { + iText->SetHasChanged(ETrue); + iTextView->HandleRangeFormatChangeL(iTextView->Selection(),EFalse); + UpdateScrollBarsL(); + // update the picture size in the header when this becomes possible (post B4 etext) + ReportEventL(MCoeControlObserver::EEventStateChanged); + } + +EXPORT_C void CEikRichTextEditor::GetEmbeddedAppL(CApaDoor*& aDoor,CApaDocument*& aDoc,TInt aDocPos) + { + aDoor=STATIC_CAST(CApaDoor*,RichText()->PictureHandleL(aDocPos)); + TRAPD(err,aDoc=aDoor->DocumentL(ETrue)); // always prompt for password + if (err==KErrNotFound) + { + TBuf<80> buf; + iCoeEnv->ReadResource(buf,R_EIK_EMBEDDED_APP_NOT_FOUND); + TBuf<128> caption=*aDoor->Caption(); + TextUtils::TruncateToNumChars(caption,RMessageWindow::EMaxTextLength-32); // resource is no longer than 32 chars + HBufC* message=HBufC::NewLC(caption.Length()+buf.Length()); + TPtr ptr=message->Des(); + ptr.Format(buf,&caption); + iEikonEnv->InfoMsg(*message); + CleanupStack::PopAndDestroy(); // message + CBaActiveScheduler::LeaveNoAlert(); + } + User::LeaveIfError(err); + } + +EXPORT_C void CEikRichTextEditor::UpdatePictureFormatL() + { + UpdatePictureFormatL(0,iText->DocumentLength()); + } + +EXPORT_C void CEikRichTextEditor::UpdatePictureFormatL(TInt aStartPos,TInt aLength) + { + TInt count=iText->ComponentInfo().iPictureCount; + if (~iEdwinUserFlags&EShowAllPicturesAsIconic || count==0) + return; + const TInt endPos=aStartPos+aLength; + for (TInt ii=aStartPos;iiPictureHandleL(ii)); + if (door) + { + door->SetFormatToTemporaryIconL(); + --count; + } + } + } + +EXPORT_C void CEikRichTextEditor::SetDefaultIconicDoorSize(const TSize& aSize) + { + iDefaultIconicDoorSize=aSize; + } + +EXPORT_C const TSize& CEikRichTextEditor::DefaultIconicDoorSize() const + { + return iDefaultIconicDoorSize; + } + +EXPORT_C void CEikRichTextEditor::UpdatePictureSizeL() + { + UpdatePictureSizeL(0,iText->DocumentLength()); + } + +EXPORT_C void CEikRichTextEditor::UpdatePictureSizeL(TInt aStartPos,TInt aLength) + { + TInt count=iText->ComponentInfo().iPictureCount; + const TInt endPos=aStartPos+aLength; + for (TInt ii=aStartPos;iiPictureHandleL(ii)); + if (door) + { + if (door->Format()!=CApaDoorBase::EGlassDoor) + door->SetSizeInTwips(iDefaultIconicDoorSize); + else + { + door->SetFormatToTemporaryIconL(ETrue); + door->SetSizeInTwips(iDefaultIconicDoorSize); + door->SetFormatToTemporaryIconL(EFalse); + } + --count; + } + } + } + +EXPORT_C void CEikRichTextEditor::SetParserObserver(MEikRichTextEditorParserObserver* aObserver) + { + if (iParserManager) + iParserManager->SetParserObserver(aObserver); + } + +EXPORT_C void CEikRichTextEditor::SetPhoneNumberGrouping( TBool aEnable ) + { + if ( aEnable ) + iEdwinInternalFlags|=EPhoneNumberGrouping; + else + iEdwinInternalFlags&=(~EPhoneNumberGrouping); + } + +void CEikRichTextEditor::SetTextObserver(CRichText& aText) + { + aText.SetEditObserver(this); + } + +/** + * Writes the internal state of the control and its components to aStream. + * Does nothing in release mode. + * Designed to be overidden and base called by subclasses. + * + * @internal + * @since App-Framework_6.1 + */ +#ifndef _DEBUG +EXPORT_C void CEikRichTextEditor::WriteInternalStateL(RWriteStream&) const + {} +#else +EXPORT_C void CEikRichTextEditor::WriteInternalStateL(RWriteStream& aWriteStream) const + { + CEikGlobalTextEditor::WriteInternalStateL(aWriteStream); + } +#endif + +EXPORT_C void CEikRichTextEditor::Reserved_2() + {} + +EXPORT_C void CEikRichTextEditor::Reserved_3() + {} + +EXPORT_C void CEikRichTextEditor::RefreshParsersL() + { + if (iParserManager) + iParserManager->ForceFullParseL(); + }