sl@0: /*
sl@0: * Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: * All rights reserved.
sl@0: * This component and the accompanying materials are made available
sl@0: * under the terms of "Eclipse Public License v1.0"
sl@0: * which accompanies this distribution, and is available
sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: *
sl@0: * Initial Contributors:
sl@0: * Nokia Corporation - initial contribution.
sl@0: *
sl@0: * Contributors:
sl@0: *
sl@0: * Description: 
sl@0: *
sl@0: */
sl@0: 
sl@0: 
sl@0: #ifndef __TXTRICH_H__
sl@0: #define __TXTRICH_H__
sl@0: 
sl@0: #include <e32std.h>
sl@0: #include <e32base.h>
sl@0: #include <txtglobl.h>
sl@0: #include <txtstyle.h>
sl@0: #include <mparser.h>
sl@0: #include <medobsrv.h>
sl@0: 
sl@0: #ifndef SYMBIAN_ENABLE_SPLIT_HEADERS
sl@0: #include <txtrich_internal.h>
sl@0: #include <txtclipboard.h>
sl@0: #endif
sl@0: 
sl@0: // forward references
sl@0: class CRichTextIndex;
sl@0: class CStreamStore;
sl@0: class CStoreMap;
sl@0: class MPictureFactory;
sl@0: class MRichTextStoreResolver;
sl@0: class TCharFormatX;
sl@0: class TCharFormatXMask;
sl@0: class CParserData;
sl@0: 
sl@0: 
sl@0: class CRichText : public CGlobalText
sl@0: /** 
sl@0: Text with rich formatting.
sl@0: 
sl@0: In rich text, each paragraph can have a different paragraph format, and each 
sl@0: character can have a different character format.
sl@0: 
sl@0: All formatting in a rich text object is based on a global character and 
sl@0: paragraph format layer, and a chain of layers on which they may be based. In 
sl@0: case of conflict, upper layers override lower layers. These two format layers 
sl@0: are specified on construction, and are not owned by the text object. Additional 
sl@0: formatting may then be added to any portion of the text. This is called specific 
sl@0: formatting and in case of conflict, it overrides the formatting in the global 
sl@0: layers. Specific formatting is owned by the text object. So, the effective 
sl@0: formatting of a rich text object may be composed of specific formatting and 
sl@0: formatting specified in a chain of format layers.
sl@0: 
sl@0: Rich text supports styles. A style is a named set of paragraph and character 
sl@0: format attributes. Styles are stored in a list which is passed to the rich 
sl@0: text object on construction, or which is assigned to the object after 
sl@0: construction. Styles can be appended to and removed from the list and existing 
sl@0: styles can be modified. Only paragraph styles are supported. This means that 
sl@0: styles are applied to entire paragraphs, although both character and paragraph 
sl@0: format attributes may be set in the style.
sl@0: 
sl@0: Rich text also supports object embedding. Embedded objects are represented 
sl@0: in rich text by CPicture-derived objects. A rich text object which supports 
sl@0: the display of pictures needs to be supplied with a picture factory.
sl@0: 
sl@0: @see CParagraphStyle 
sl@0: @publishedAll
sl@0: @released
sl@0: */
sl@0: 	{
sl@0: public:
sl@0: 	
sl@0: 	/** Number of paragraphs in the object. */
sl@0: 	enum TParaType 
sl@0: 		{
sl@0: 		/** The text object will contain a single paragraph. */
sl@0: 		ESinglePara, 
sl@0: 		/** The text object will contain multiple paragraphs. */
sl@0: 		EMultiPara
sl@0: 		};
sl@0: public:
sl@0: 	// Create new rich text component whose sole content is an end-of-document character.	
sl@0: 	IMPORT_C static CRichText* NewL(const CParaFormatLayer* aGlobalParaLayer, const CCharFormatLayer* aGlobalCharLayer,
sl@0: 									TDocumentStorage aStorage = ESegmentedStorage,
sl@0: 									TInt aDefaultTextGranularity = EDefaultTextGranularity,
sl@0: 									TParaType aParaType = EMultiPara);
sl@0: 	// Create new rich text component, supporting STYLES, whose sole content is an end-of-document character.
sl@0: 	IMPORT_C static CRichText* NewL(const CParaFormatLayer* aGlobalParaLayer, const CCharFormatLayer* aGlobalCharLayer,
sl@0: 									const CStyleList& aStyleList,
sl@0: 									TDocumentStorage aStorage = ESegmentedStorage,
sl@0: 									TInt aDefaultTextGranularity = EDefaultTextGranularity,
sl@0: 									TParaType aParaType = EMultiPara);
sl@0: 	// Restore into new rich text, using the specified global layers.
sl@0: 	IMPORT_C static CRichText* NewL(const CStreamStore& aStore, TStreamId aStreamId,
sl@0: 									const CParaFormatLayer* aGlobalParaLayer, const CCharFormatLayer* aGlobalCharLayer,
sl@0: 									MTextFieldFactory* aFieldFactory = NULL,
sl@0: 									TDocumentStorage aStorage = ESegmentedStorage);
sl@0: 	// Restore into new rich text, using the specified layers, store & picture factory.
sl@0: 	IMPORT_C static CRichText* NewL(const CStreamStore& aStore, TStreamId aStreamId,
sl@0: 									const CParaFormatLayer* aGlobalParaLayer, const CCharFormatLayer * aGlobalCharLayer,
sl@0: 									MPictureFactory* aPictureFactory, MRichTextStoreResolver* aStoreResolver,
sl@0: 									MTextFieldFactory* aFieldFactory = NULL,
sl@0: 									TDocumentStorage aStorage = ESegmentedStorage);
sl@0: 	IMPORT_C virtual ~CRichText();
sl@0: 	//
sl@0: 	// Default persist functions - Deferred loading of pictures
sl@0: 	IMPORT_C void RestoreWithStyleListL(const CStreamStore& aStore, TStreamId aStreamId, const CStyleList& aExternalStyleList);
sl@0: 	//
sl@0: 	IMPORT_C virtual void StoreComponentsL(CStreamStore& aStore, CStoreMap& aMap) const;
sl@0: 	IMPORT_C virtual void RestoreComponentsL(const CStreamStore& aStore);
sl@0: 	IMPORT_C virtual void ExternalizeL(RWriteStream& aStream) const;
sl@0: 	IMPORT_C virtual void InternalizeL(RReadStream& aStream);
sl@0: 	//
sl@0: 	// Custom persist functions
sl@0: 	IMPORT_C void ExternalizeStyleDataL(RWriteStream& aStream) const;
sl@0: 	IMPORT_C void InternalizeStyleDataL(RReadStream& aStream);
sl@0: 	//
sl@0: 	IMPORT_C void StoreMarkupComponentsL(CStreamStore& aStore, CStoreMap& aMap) const;
sl@0: 	IMPORT_C void ExternalizeMarkupDataL(RWriteStream& aStream) const;
sl@0: 	IMPORT_C void InternalizeMarkupDataL(RReadStream& aStream);
sl@0: 	//
sl@0: 	// Utility persist functions
sl@0: 	IMPORT_C void SetPictureFactory(MPictureFactory* aPictureFactory, MRichTextStoreResolver* aStoreResolver);
sl@0: 	inline MPictureFactory* PictureFactory() const;
sl@0: 	inline MRichTextStoreResolver* StoreResolver() const;
sl@0: 	IMPORT_C TPictureHeader PictureHeader(TInt aPos) const;
sl@0: 	IMPORT_C void DropPictureOwnership(TInt aPos);		// delete picture character. Forget but don't delete picture.
sl@0: 	IMPORT_C void DetachFromStoreL(CPicture::TDetach aDegree);
sl@0: 	IMPORT_C void DetachFromStoreL(CPicture::TDetach aDegree, TInt aPos, TInt aLength);
sl@0: 	IMPORT_C TBool HasMarkupData() const;
sl@0: 	//
sl@0: 	// Copy/Paste
sl@0: 	IMPORT_C virtual void CopyToStoreL(CStreamStore& aStore, CStreamDictionary& aDictionary, TInt aPos, TInt aLength) const;
sl@0: 	IMPORT_C virtual TInt PasteFromStoreL(const CStreamStore& aStore, const CStreamDictionary& aDictionary, TInt aPos);
sl@0: 	IMPORT_C TInt PasteFromStoreL(const CStreamStore& aStore, const CStreamDictionary& aDictionary, TInt aPos, CParagraphStyle::TStylePasteMode aStylePasteMode);
sl@0: 	//
sl@0: 	// Content modifier functions
sl@0: 	IMPORT_C virtual void Reset();
sl@0: 	IMPORT_C virtual void InsertL(TInt aPos, const TChar& aChar);  // Insert a single character.
sl@0: 	IMPORT_C virtual void InsertL(TInt aPos, const TDesC& aBuf);
sl@0: 	IMPORT_C void InsertL(TInt aPos, const TPictureHeader& aHeader);  // Insert a picture header.
sl@0: 	//
sl@0: 	// aPos is the position of the character being deleted, *not* the current cursor position!
sl@0: 	IMPORT_C virtual TBool DeleteL(TInt aPos, TInt aLength);  // Call this for a delete-forward.
sl@0: 	//
sl@0: 	// Leave-safe delete for removing content from *within* a single paragraph only
sl@0: 	IMPORT_C void DeleteFromParagraph(TInt aPos, TInt aLength);
sl@0: 	//
sl@0: 	// Leave-safe delete for removing *entire* paragraphs
sl@0: 	IMPORT_C void DeleteParagraph(TInt aPos, TInt aLength);
sl@0: 	//
sl@0: 	// Special behaviour format modifier functions.
sl@0: 	// Call this when applying a character format to a zero length selection, eg, turning bold on.
sl@0: 	IMPORT_C void SetInsertCharFormatL(const TCharFormat& aFormat, const TCharFormatMask& aMask, TInt aPos);
sl@0: 	//
sl@0: 	// Call this on every cursor movement, page up/down etc...
sl@0: 	IMPORT_C void CancelInsertCharFormat();
sl@0: 	//
sl@0: 	// Delete content, but preserve phrase format if aPos is at a phrase boundary.
sl@0: 	// aPos is the position of the character being deleted, *not* the current cursor position!
sl@0: 	IMPORT_C TBool DelSetInsertCharFormatL(TInt aPos, TInt aLength);
sl@0: 	//
sl@0: 	// MLaydoc implementation
sl@0: 	IMPORT_C virtual void GetParagraphFormatL(CParaFormat* aFormat, TInt aPos) const;
sl@0: 	IMPORT_C virtual void GetChars(TPtrC& aView, TCharFormat& aFormat, TInt aPos) const;
sl@0: 	IMPORT_C virtual TInt GetPictureSizeInTwips(TSize& aSize, TInt aPos) const;
sl@0: 	IMPORT_C virtual CPicture* PictureHandleL(TInt aPos, MLayDoc::TForcePictureLoad aForceLoad = MLayDoc::EForceLoadTrue) const;
sl@0: 	//
sl@0: 	// MFormatText implementation
sl@0: 	// Used only by dialog writers, since they are not interested in the text, but require knowledge
sl@0: 	// of attributes whose values change across the specified range.
sl@0: 	IMPORT_C virtual void GetParaFormatL(CParaFormat* aFormat, TParaFormatMask& aVaries, TInt aPos, TInt aLength,
sl@0: 										CParaFormat::TParaFormatGetMode aMode = CParaFormat::EAllAttributes) const;
sl@0: 	IMPORT_C virtual void ApplyParaFormatL(const CParaFormat* aFormat, const TParaFormatMask& aMask, TInt aPos, TInt aLength);
sl@0: 	IMPORT_C virtual void GetCharFormat(TCharFormat& aFormat, TCharFormatMask& aVaries, TInt aPos, TInt aLength) const;
sl@0: 	IMPORT_C virtual void ApplyCharFormatL(const TCharFormat& aFormat, const TCharFormatMask& aMask, TInt aPos, TInt aLength);
sl@0: 	//
sl@0: 	//
sl@0: 	IMPORT_C void GetSpecificCharFormat(TCharFormat& aFormat, TCharFormatMask& aMask, TInt aPos) const;
sl@0: 	IMPORT_C void GetSpecificCharFormatRight(TCharFormat& aFormat, TCharFormatMask& aMask, TInt aPos) const;
sl@0: 	IMPORT_C void GetSpecificParagraphFormatL(CParaFormat* aFormat, TParaFormatMask& aMask, TInt aPos) const;
sl@0: 	//
sl@0: 	// Paragraph style implementation
sl@0: 	IMPORT_C void ApplyParagraphStyleL(const CParagraphStyle& aStyle, TInt aPos, TInt aLength, CParagraphStyle::TApplyParaStyleMode aMode);
sl@0: 	inline void NotifyStyleDeletedL(const CParagraphStyle* aStyle);
sl@0: 	IMPORT_C void NotifyStyleChangedL(const CParagraphStyle* aTo, const CParagraphStyle* aFrom);
sl@0: 	IMPORT_C const CParaFormatLayer* ParagraphStyle(TBool& aStyleChangesOverRange, TInt aPos, TInt aLength) const;
sl@0: 	//
sl@0: 	// StyleList implementation
sl@0: 	inline TBool StyleListPresent() const;
sl@0: 	inline CStyleList* StyleList() const;
sl@0: 	inline TInt StyleCount() const;
sl@0: 
sl@0: 	inline void SetStyleListExternallyOwned(TBool aExternallyOwned);
sl@0: 	IMPORT_C void SetStyleListExternallyOwned(const CStyleList& aStyleList);
sl@0: 	inline TBool StyleListExternallyOwned() const;
sl@0: 	//
sl@0: 	// Utility functions
sl@0: 	IMPORT_C void RemoveSpecificParaFormatL(TInt aPos, TInt aLength);  
sl@0: 	IMPORT_C void RemoveSpecificCharFormatL(TInt aPos, TInt aLength);
sl@0: 	IMPORT_C TInt PictureCount() const;
sl@0: 	IMPORT_C virtual TInt ParagraphCount() const;
sl@0: 	IMPORT_C virtual TInt CharPosOfParagraph(TInt& aLength, TInt aParaOffset) const;
sl@0: 	IMPORT_C virtual TInt ParagraphNumberForPos(TInt& aPos) const;
sl@0: 	IMPORT_C virtual TEtextComponentInfo ComponentInfo() const;
sl@0: 	//
sl@0: 	// Text field implementation
sl@0: 	IMPORT_C virtual void UpdateFieldL(TInt aPos);  // updates the field at aPos
sl@0: 	// finds number of fields in range. Includes the field containing aPos, if applicable
sl@0: 	// aInfo is set to the first field in the range (if any are found)
sl@0: 	//
sl@0: 	// Speciality functions
sl@0: 	IMPORT_C void AppendTakingSolePictureOwnershipL(const CRichText& aSource);
sl@0: 	IMPORT_C void AppendParagraphL(TInt aReplicas = 1);
sl@0: 	IMPORT_C virtual void SetHasChanged(TBool aHasChanged);
sl@0: 	
sl@0: 	IMPORT_C void ExtendedInterface(TAny*& aInterface, TUid aInterfaceId); // from CEditableText
sl@0: 	
sl@0: 	// non-exported public functions
sl@0: 	void ApplyExtendedCharFormatL(const TCharFormatX& aFormat, const TCharFormatXMask& aMask, TInt aPos, TInt aLength);
sl@0: 	void GetExtendedCharFormat(TCharFormatX& aFormat, TCharFormatXMask& aVaries, TInt aPos, TInt aLength) const;
sl@0: 	void GetTextAndExtendedFormat(TPtrC& aText, TCharFormatX& aFormat, TInt aPos) const;
sl@0: 
sl@0: private:
sl@0: 	CRichText(const CRichText& aRichText);
sl@0: 	CRichText& operator=(const CRichText& aRichText);
sl@0: 	void KillStyleList();
sl@0: 	void KillIndex();
sl@0: 	TBool CreateEmptyMarkupComponentL();
sl@0: 	void CreateAndGenerateMarkupComponentL();
sl@0: 	void GenerateMarkupL();
sl@0: 	void CompletePastePlainTextL(TInt aPos,TInt aCharacterCount);
sl@0: 	TInt DoPasteRtFromStoreL(const CStreamStore& aStore, const CStreamDictionary& aDictionary, TInt aPos, CParagraphStyle::TStylePasteMode aStylePasteMode);
sl@0: 	TBool IndexPresent() const;
sl@0: 	inline void SetParaTypeIsSingle(TBool aBool);
sl@0: 	inline TBool ParaTypeIsSingle() const;
sl@0: 	void SetExtendedInsertCharFormatL(const TCharFormatX& aFormat, const TCharFormatXMask& aMask, TInt aPos);
sl@0: 	void GetSpecificCharFormatLeftRight(TCharFormat& aFormat,
sl@0: 		TCharFormatMask& aMask, TInt aPos, TBool aLeft) const;
sl@0: 	void DoApplyExtendedCharFormatL(const TCharFormatX& aFormat,const TCharFormatXMask& aMask,TInt aPos,TInt aLength);		
sl@0: 
sl@0: protected:
sl@0: 	IMPORT_C CRichText(const CParaFormatLayer* aGlobalParaLayer, const CCharFormatLayer* aGlobalCharLayer,
sl@0: 					   CStyleList* aStyleList = NULL);
sl@0: 	// New constructL's - to be merged post 057
sl@0: 	IMPORT_C void ConstructL(TDocumentStorage aStorage, TInt aDefaultTextGranularity, TParaType aParaType);
sl@0: 	IMPORT_C void ConstructL(const CStreamStore& aStore, TStreamId aStreamId, MPictureFactory* aFactory, MRichTextStoreResolver* aStoreResolver,
sl@0: 							 MTextFieldFactory* aFieldFactory=NULL,
sl@0: 							 TDocumentStorage aStorage = ESegmentedStorage);
sl@0: 	//
sl@0: 	void InternalizeL(RReadStream& aStream, const CStyleList* aExternalStyleList);
sl@0: 	IMPORT_C void DoExternalizeStyleDataL(RWriteStream& aStream) const;
sl@0: 	IMPORT_C void DoInternalizeStyleDataL(RReadStream& aStream);
sl@0: 	void DoInternalizeStyleDataL(RReadStream& aStream, const CStyleList* aExternalStyleList);
sl@0: 	IMPORT_C void DoExternalizeMarkupDataL(RWriteStream& aStream) const;
sl@0: 	IMPORT_C void DoInternalizeMarkupDataL(RReadStream& aStream);
sl@0: 	void StoreStylesL(CStreamStore& aStore,CStoreMap& aMap) const;
sl@0: 	void RestoreStylesL(const CStreamStore& aStore, TStreamId aId, const CParaFormatLayer* aParaFormatLayer, const CCharFormatLayer* aCharFormatLayer);
sl@0: 	void StoreMarkupL(CStreamStore& aStore,CStoreMap& aMap)const;
sl@0: 	//
sl@0: 	IMPORT_C void RtInsertL(TInt aPos,const TDesC& aBuf);
sl@0: 	//
sl@0: 	TStreamId DoCopyToStoreL(CStreamStore& aStore, TInt aPos, TInt aLength, TStreamId aGlobalTextId, TBool aCopyStyles) const;
sl@0: 	IMPORT_C void CopyComponentsL(CStreamStore& aStore, CStoreMap& aMap, TInt aPos,TInt aLength, TStreamId aGlobalTextId) const;
sl@0: 	IMPORT_C void CopyToStreamL(RWriteStream& aStream, TInt aPos, TInt aLength, TStreamId aGlobalTextId) const;
sl@0: 	IMPORT_C void CopyToStreamL(RWriteStream& aStream, TInt aPos, TInt aLength) const;
sl@0: 	void CopyToStreamL(RWriteStream& aStream, TInt aPos, TInt aLength, TStreamId aGlobalTextId, TBool aCopyStyles) const;
sl@0: 	TInt PasteRichTextFromStoreL(const CStreamStore& aStore, const CStreamDictionary& aDictionary, TStreamId& anId, TInt aPos, CParagraphStyle::TStylePasteMode aStylePasteMode);
sl@0: 	void CompletePasteRichTextFromStoreL(const CStreamStore& aStore, TStreamId& aRichTextStreamId, TInt aPos, CParagraphStyle::TStylePasteMode aStylePasteMode);
sl@0: 	TInt PastePlainTextFromStoreL(const CStreamStore& aStore, TStreamId& anId, TInt aPos);
sl@0: 	//
sl@0: 	// Append
sl@0: 	void PrepareAppendMarkupL(const CRichText& aSource);
sl@0: 	void DoAppendTakingSolePictureOwnershipL(const CRichText& aSource);
sl@0: public:
sl@0: 	IMPORT_C static void ActivateParserL(MParser* aParser);		// Switch on a particular parser
sl@0: 	IMPORT_C static void DeactivateParser(MParser* aParser);	// Switch off a particular parser
sl@0: 	IMPORT_C static void ActivateDefaultParserL(MParser* aParser);	// Switch on a default parser
sl@0: 	IMPORT_C static void DeactivateParserDefaults();				// Switch off default set (if any)
sl@0: 																// and delete EText TLS
sl@0: 
sl@0: 	IMPORT_C void SetEditObserver(MEditObserver* aEditObserver);
sl@0: 	IMPORT_C TBool ParseText(TInt& aStartOfTags, TInt& aLength, TBool aForceScanAllText);
sl@0: 	IMPORT_C TBool CursorOverTag(TInt aPos, MParser*& aParser, TInt& aTagStart, TInt& aLength) const;
sl@0: 	// Next tag (forwards), any or specific parser
sl@0: 	IMPORT_C TInt PositionOfNextTag(TInt aPos) const;
sl@0: 	IMPORT_C TInt PositionOfNextTag(TInt aPos, const MParser* aParser) const;
sl@0: 	// Prev tag (backwards), any or specific parser
sl@0: 	IMPORT_C TInt PositionOfPrevTag(TInt aPos) const;
sl@0: 	IMPORT_C TInt PositionOfPrevTag(TInt aPos, const MParser* aParser) const;
sl@0: 
sl@0: private:
sl@0: 	static void CreateParserETextTLSL();
sl@0: 	TBool DoCursorOverTag(TInt aPos, MParser*& aParser, TInt& aTagStart, TInt& aLength) const;
sl@0: 	void OverrideFormatForParsersIfApplicable(TPtrC& aText, TCharFormatX& aFormat, TInt aStartPos) const;
sl@0: 	void CallEditObserver(TInt aStart, TInt aExtent) const;
sl@0: 
sl@0: protected:
sl@0: 	enum {EDelimiterCharacterLength = 1};
sl@0: private:
sl@0: 	TSwizzle<CStyleList> iStyleList;
sl@0: 	TSwizzle<CRichTextIndex> iIndex;
sl@0: 	TUint32 iFlags;
sl@0: 	MPictureFactory* iPictureFactory;
sl@0: 	MRichTextStoreResolver* iStoreResolver;
sl@0: 
sl@0: 	CParserData* iParserData;
sl@0: 
sl@0: 	void* iReserved_3;
sl@0: 
sl@0: 	__DECLARE_TEST;  // Index consistency check with document length.
sl@0: 	};
sl@0: 
sl@0: 
sl@0: #include <txtrich.inl>
sl@0: 
sl@0: 
sl@0: #endif
sl@0: 
sl@0: 
sl@0: