os/textandloc/textrendering/textformatting/undo/EditorUndo.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     5 * under the terms of "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description: 
    15 *
    16 */
    17 
    18 
    19 #include "EditorUndo.h"
    20 #include "EditorCommands.h"
    21 #include "UndoSystem.h"
    22 #include "AssertFileAndLine.h"
    23 
    24 using namespace UndoSystem;
    25 
    26 //
    27 //
    28 // Functions for Unique Instance Repositories
    29 //
    30 //
    31 
    32 namespace EditorUndo
    33 {
    34 TInt CompareCharFormatMasks(const TTmCharFormatMask* aL, const TTmCharFormatMask* aR)
    35 	{
    36 	TUint32 left = aL->iFlags;
    37 	TUint32 right= aR->iFlags;
    38 	if (left < right)
    39 		return -1;
    40 	if (right < left)
    41 		return 1;
    42 	return 0;
    43 	}
    44 TInt CompareParFormatMasks(const TTmParFormatMask* aL, const TTmParFormatMask* aR)
    45 	{
    46 	TUint32 left = aL->iFlags;
    47 	TUint32 right= aR->iFlags;
    48 	if (left < right)
    49 		return -1;
    50 	if (right < left)
    51 		return 1;
    52 	return 0;
    53 	}
    54 // aLeftEnd is one-past-end pointer for the memory beginning at aLeft.
    55 TInt CompareRawMem(const TUint32* aLeft, const TUint32* aRight, const TUint32* aLeftEnd)
    56 	{
    57 	while (aLeft != aLeftEnd)
    58 		{
    59 		if (*aLeft < *aRight)
    60 			return -1;
    61 		if (*aRight < *aLeft)
    62 			return 1;
    63 		++aLeft;
    64 		++aRight;
    65 		}
    66 	return 0;
    67 	}
    68 // void* for convenience, const TUint32* would be better
    69 // aLeftEnd is one-past-end pointer for the memory beginning at aLeft.
    70 TInt CompareMemByUint32(const void* aLeft, const void* aRight, const void* aLeftEnd)
    71 	{
    72 	ASSERT((reinterpret_cast<TUint32>(aLeft) & 3) == 0);
    73 	ASSERT((reinterpret_cast<TUint32>(aRight) & 3) == 0);
    74 	ASSERT((reinterpret_cast<TUint32>(aLeftEnd) & 3) == 0);
    75 	return CompareRawMem(
    76 		reinterpret_cast<const TUint32*>(aLeft),
    77 		reinterpret_cast<const TUint32*>(aRight),
    78 		reinterpret_cast<const TUint32*>(aLeftEnd));
    79 	}
    80 TInt CompareOpenFontSpec(const TOpenFontSpec* aL, const TOpenFontSpec* aR)
    81 	{
    82 	// We can almost compare TOpenFontSpecs bitwise, except for the fact that
    83 	// there is a literal name of the font at the start. We must compare these
    84 	// names, and skip over them for the full compare.
    85 	TInt nameComp = aL->Name().Compare(aR->Name());
    86 	if (nameComp)
    87 		return nameComp;
    88 	const TText* lText = reinterpret_cast<const TText*>(aL) + TOpenFontFaceAttribBase::ENameLength;
    89 	const TText* rText = reinterpret_cast<const TText*>(aR) + TOpenFontFaceAttribBase::ENameLength;
    90 	return CompareMemByUint32(lText, rText, aL + 1);
    91 	}
    92 TInt CompareCharFormats(const TTmCharFormat* aL, const TTmCharFormat* aR)
    93 	{
    94 	TInt fontSpecCompare = CompareOpenFontSpec(&aL->iFontSpec, &aR->iFontSpec);
    95 	if (fontSpecCompare != 0)
    96 		return fontSpecCompare;
    97 	return CompareMemByUint32(&aL->iTextColor, &aR->iTextColor, aL + 1);
    98 	}
    99 TBool operator<(const TTmTab& aL, const TTmTab& aR)
   100 	{
   101 	if (aL.iPosition != aR.iPosition)
   102 		return aL.iPosition < aR.iPosition;
   103 	return aL.iType < aR.iType;
   104 	}
   105 TBool operator<(const TTmParBorder& aL, const TTmParBorder& aR)
   106 	{
   107 	if (aL.iAutoColor != aR.iAutoColor)
   108 		return aR.iAutoColor;
   109 	if (aL.iColor.Value() != aR.iColor.Value())
   110 		return aL.iColor.Value() < aR.iColor.Value();
   111 	if (aL.iStyle != aR.iStyle)
   112 		return aL.iStyle < aR.iStyle;
   113 	return aL.iWeight < aR.iWeight;
   114 	}
   115 TInt CompareParFormats(const RTmParFormat* left, const RTmParFormat* right)
   116 	{
   117 	const TLogicalRgb* leftBodyEnd = &left->iBackgroundColor;
   118 	TInt bodyCompare = CompareMemByUint32(left, right, leftBodyEnd + 1);
   119 	if (bodyCompare != 0)
   120 		return bodyCompare;
   121 	TInt tabs = left->Tabs();
   122 	if (right->Tabs() < tabs)
   123 		tabs = right->Tabs();
   124 		{
   125 		for(TInt i = 0; i != tabs; ++i)
   126 			{
   127 			if (left->Tab(i) != right->Tab(i))
   128 				return left->Tab(i) < right->Tab(i)? -1 : 1;
   129 			}
   130 		}
   131 	if (left->Tabs() != right->Tabs())
   132 		return left->Tabs() < right->Tabs()? -1 : 1;
   133 		{
   134 		const TTmBullet* leftBullet = left->Bullet();
   135 		const TTmBullet* rightBullet = right->Bullet();
   136 		if (leftBullet != rightBullet)
   137 			{
   138 			if (!leftBullet)
   139 				return -1;
   140 			if (!rightBullet)
   141 				return 1;
   142 			if (leftBullet->iCharacterCode < rightBullet->iCharacterCode)
   143 				return -1;
   144 			if (rightBullet->iCharacterCode < leftBullet->iCharacterCode)
   145 				return 1;
   146 			TInt fontSpecCompare = CompareOpenFontSpec(&leftBullet->iFontSpec,
   147 				&rightBullet->iFontSpec);
   148 			if (fontSpecCompare != 0)
   149 				return fontSpecCompare;
   150 
   151 			return CompareMemByUint32(&leftBullet->iHangingIndent, &rightBullet->iHangingIndent,
   152 				leftBullet + 1);
   153 			}
   154 		}
   155 		{
   156 		for (TInt i = 0; i != 4; ++i)
   157 			{
   158 			const TTmParBorder* lb =
   159 				left->Border(static_cast<RTmParFormat::TBorderIndex>(i));
   160 			const TTmParBorder* rb =
   161 				right->Border(static_cast<RTmParFormat::TBorderIndex>(i));
   162 			if (!lb && rb)
   163 				return -1;
   164 			if (lb && !rb)
   165 				return 1;
   166 			if (lb)
   167 				{
   168 				if (*lb < *rb)
   169 					return -1;
   170 				if (*rb < *lb)
   171 					return 1;
   172 				}
   173 			}
   174 		}
   175 	return 0;
   176 	}
   177 void DeleteParFormat(RTmParFormat* a)
   178 	{
   179 	a->Close();
   180 	delete a;
   181 	}
   182 RTmParFormat* CopyParFormatL(const RTmParFormat* a, TInt)
   183 	{
   184 	RTmParFormat* r = new(ELeave) RTmParFormat;
   185 	CleanupStack::PushL(r);
   186 	r->CopyL(*a);
   187 	CleanupStack::Pop(r);
   188 	return r;
   189 	}
   190 }
   191 using namespace EditorUndo;
   192 
   193 /**
   194  * Command factory. Used for obtaining 'command' versions of API calls to MUnifiedEditor.
   195  *
   196  * @internalComponent
   197  * @since App-frameworks6.1
   198  */
   199 NONSHARABLE_CLASS(CEditorCommandFactory) : public CBase
   200 	{
   201 public:
   202 	~CEditorCommandFactory();
   203 	static CEditorCommandFactory* NewL(MUnifiedEditor& aTarget);
   204 
   205 	// these commands set up the prototypes and then pass them back
   206 	const CEditorCommandCreateStyleProto*
   207 		GetCreateStyleProto(const RTmStyle&);
   208 	const CEditorCommandChangeStyleProto*
   209 		GetChangeStyleProto(const RTmStyle&);
   210 	const CEditorCommandSetStyleProto*
   211 		GetSetStyleProto(TInt aPos,
   212 						   TInt aLength,
   213 						   const TDesC& aName);
   214 	const CEditorCommandDeleteStyleProto*
   215 		GetDeleteStyleProto(const TDesC& aName);
   216 	const CEditorCommandDeleteCharFormatProto*
   217 		GetDeleteCharFormatProto(TInt aPos,
   218 								 TInt aLength);
   219 	const CEditorCommandDeleteParFormatProto*
   220 		GetDeleteParFormatProto(TInt aPos,
   221 								TInt aLength);
   222 	const CEditorCommandSetCharFormatProto*
   223 		GetSetCharFormatProto(TInt aPos,
   224 							  TInt aLength,
   225 							  const TTmCharFormatLayer& aFormat);
   226 	const CEditorCommandSetParFormatProto*
   227 		GetSetParFormatProto(TInt aPos,
   228 							 TInt aLength,
   229 							 const RTmParFormatLayer& aFormat);
   230 	const CEditorCommandInsertProto*
   231 		GetInsertProto(TInt aPos,
   232 					   const TDesC& aText,
   233 					   const TDesC* aStyle,
   234 					   const TTmCharFormatLayer* aCharFormat,
   235 					   const RTmParFormatLayer* aParFormat);
   236 	const CEditorCommandDeletePictureProto*
   237 		GetDeletePictureProto(TInt aPos);
   238 	// this is only safe if there are no pictures to delete.
   239 	// If there are, multiple commands must be issued.
   240 	const CEditorCommandDeleteProto*
   241 		GetDeleteProto(TInt aPos, TInt aLength);
   242 	const CEditorCommandInsertPictureProto*
   243 		GetInsertPictureProto(TInt aPos, const TPictureHeader& aPicture);
   244 	const CEditorCommandDestroyPictureProto*
   245 		GetDestroyPictureProto(TInt aPos);
   246 	const CEditorCommandRenameStyleProto*
   247 		GetRenameStyleProto(const TDesC& aOldName, const TDesC& aNewName);
   248 	const CEditorCommandSetBaseFormatProto*
   249 		GetSetBaseFormatProto(const TTmCharFormat* aCharFormat,
   250 			const RTmParFormat* aParFormat);
   251 	const CEditorCommandPasteProto*
   252 		GetPasteProto(const CStreamStore& aStore,
   253 			const CStreamDictionary& aStreamDictionary,	TInt aPos);
   254 
   255 private:
   256 	CEditorCommandFactory(MUnifiedEditor& aTarget);
   257 	void ConstructL();
   258 
   259 	TRepositories						iReps;
   260 	MUnifiedEditor&							iTarget;
   261 	// like Design Pattern prototypes, but not quite, because rather than
   262 	// being clonable, they create inverses of themselves
   263 	CEditorCommandCreateStyleProto		iCreateStyleProto;
   264 	CEditorCommandChangeStyleProto		iChangeStyleProto;
   265 	CEditorCommandSetStyleProto			iSetStyleProto;
   266 	CEditorCommandDeleteStyleProto		iDeleteStyleProto;
   267 	CEditorCommandSetCharFormatProto	iSetCharFormatProto;
   268 	CEditorCommandSetParFormatProto		iSetParFormatProto;
   269 	CEditorCommandInsertProto			iInsertProto;
   270 	CEditorCommandDeleteProto			iDeleteProto;
   271 	CEditorCommandDeleteCharFormatProto	iDeleteCharFormatProto;
   272 	CEditorCommandDeleteParFormatProto	iDeleteParFormatProto;
   273 	CEditorCommandDeletePictureProto	iDeletePictureProto;
   274 	CEditorCommandInsertPictureProto	iInsertPictureProto;
   275 	CEditorCommandDestroyPictureProto	iDestroyPictureProto;
   276 	CEditorCommandRenameStyleProto		iRenameStyleProto;
   277 	CEditorCommandSetBaseFormatProto	iSetBaseFormatProto;
   278 	CEditorCommandPasteProto			iPasteProto;
   279 	};
   280 
   281 //
   282 //
   283 // CEditorWithUndo
   284 //
   285 //
   286 
   287 CEditorWithUndo::CEditorWithUndo() {}
   288 
   289 CEditorWithUndo::~CEditorWithUndo()
   290 	{
   291 	if (iCommandManager)
   292 		iCommandManager->Release();
   293 	delete iFactory;
   294 	}
   295 
   296 void CEditorWithUndo::ConstructL(MUnifiedEditor& aEditorBasedOn, CCommandManager* aUndoSys)
   297 	{
   298 	iBaseEditor = &aEditorBasedOn;
   299 	iFactory = CEditorCommandFactory::NewL(aEditorBasedOn);
   300 	if (!aUndoSys)
   301 		iCommandManager = CCommandManager::NewL();
   302 	else
   303 		{
   304 		iCommandManager = aUndoSys;
   305 		iCommandManager->NewReference();
   306 		}
   307 	}
   308 
   309 EXPORT_C CEditorWithUndo* CEditorWithUndo::NewL(MUnifiedEditor& aEditor,
   310 												CCommandManager* aUndoSys)
   311 	{
   312 	CEditorWithUndo *r = new(ELeave) CEditorWithUndo;
   313 	CleanupStack::PushL(r);
   314 	r->ConstructL(aEditor, aUndoSys);
   315 	CleanupStack::Pop(r);
   316 	return r;
   317 	}
   318 
   319 EXPORT_C CEditorWithUndo* CEditorWithUndo::NewL(MUnifiedEditor& aEditor)
   320 	{
   321 	return NewL(aEditor, 0);
   322 	}
   323 
   324 EXPORT_C MNotUndoableGatekeeper*
   325 	CEditorWithUndo::SetGatekeeper(MNotUndoableGatekeeper* a)
   326 	{
   327 	return iCommandManager->SetGatekeeper(a);
   328 	}
   329 
   330 MTmOptionalInterface* CEditorWithUndo::Interface(TUint aId)
   331 	{
   332 	if (!iBaseEditor->Interface(aId))
   333 		return 0;
   334 	if (aId == KUidMUnifiedEditorStyleSupport)
   335 		return static_cast<MUnifiedEditor::MStyleSupport*>(this);
   336 	if (aId == KUidMUnifiedEditorPictureSupport)
   337 		return static_cast<MUnifiedEditor::MPictureSupport*>(this);
   338 	if (aId == KUidMUnifiedEditorClipboardSupport)
   339 		return static_cast<MUnifiedEditor::MClipboardSupport*>(this);
   340 	return 0;
   341 	}
   342 
   343 //
   344 // history control methods
   345 //
   346 
   347 EXPORT_C void CEditorWithUndo::UndoL()
   348 	{
   349 	iCommandManager->UndoL();
   350 	}
   351 
   352 EXPORT_C void CEditorWithUndo::RedoL()
   353 	{
   354 	iCommandManager->RedoL();
   355 	}
   356 
   357 EXPORT_C TBool CEditorWithUndo::CanUndo() const
   358 	{
   359 	return iCommandManager->CanUndo();
   360 	}
   361 
   362 EXPORT_C TBool CEditorWithUndo::CanRedo() const
   363 	{
   364 	return iCommandManager->CanRedo();
   365 	}
   366 
   367 EXPORT_C void CEditorWithUndo::ResetUndo()
   368 	{
   369 	iCommandManager->ResetUndo();
   370 	}
   371 
   372 EXPORT_C void CEditorWithUndo::SetMaxItems(TInt aMaxItems)
   373 	{
   374 	iCommandManager->SetMaxItems(aMaxItems);
   375 	}
   376 
   377 //
   378 // purely delegated editor methods
   379 //
   380 TInt CEditorWithUndo::DocumentLength() const
   381 	{
   382 	ASSERT(iBaseEditor);
   383 	return iBaseEditor->DocumentLength();
   384 	}
   385 
   386 TInt CEditorWithUndo::StyleCount() const
   387 	{
   388 	ASSERT(iBaseEditor);
   389 	MUnifiedEditor::MStyleSupport* si = iBaseEditor->StyleSupport();
   390 	return si? si->StyleCount() : 0;
   391 	}
   392 
   393 void CEditorWithUndo::GetStyle(TInt aPos,
   394 										TPtrC& aName, TInt& aRunLength) const
   395 	{
   396 	ASSERT(iBaseEditor);
   397 	MUnifiedEditor::MStyleSupport* si = iBaseEditor->StyleSupport();
   398 	ASSERT(si);
   399 	si->GetStyle(aPos, aName, aRunLength);
   400 	}
   401 
   402 TInt CEditorWithUndo::GetStyleByNameL(const TDesC& aName,
   403 											   RTmStyle& aStyle) const
   404 	{
   405 	ASSERT(iBaseEditor);
   406 	MUnifiedEditor::MStyleSupport* si = iBaseEditor->StyleSupport();
   407 	ASSERT(si);
   408 	return si->GetStyleByNameL(aName, aStyle);
   409 	}
   410 
   411 TInt CEditorWithUndo::GetStyleByIndexL(TInt aIndex,
   412 												RTmStyle& aStyle) const
   413 	{
   414 	ASSERT(iBaseEditor);
   415 	MUnifiedEditor::MStyleSupport* si = iBaseEditor->StyleSupport();
   416 	ASSERT(si);
   417 	return si->GetStyleByIndexL(aIndex, aStyle);
   418 	}
   419 
   420 void CEditorWithUndo::GetText(TInt aPos,TPtrC& aText) const
   421 	{
   422 	ASSERT(iBaseEditor);
   423 	iBaseEditor->GetText(aPos, aText);
   424 	}
   425 
   426 void CEditorWithUndo::GetCharFormat(TInt aPos,
   427 											 TFormatLevel aLevel,
   428 											 TTmCharFormatLayer& aFormat,
   429 											 TInt& aRunLength) const
   430 	{
   431 	ASSERT(iBaseEditor);
   432 	iBaseEditor->GetCharFormat(aPos, aLevel, aFormat, aRunLength);
   433 	}
   434 
   435 void CEditorWithUndo::GetParFormatL(TInt aPos,
   436 											 TFormatLevel aLevel,
   437 											 RTmParFormatLayer& aFormat,
   438 											 TInt& aRunLength) const
   439 	{
   440 	ASSERT(iBaseEditor);
   441 	iBaseEditor->GetParFormatL(aPos, aLevel, aFormat, aRunLength);
   442 	}
   443 
   444 void CEditorWithUndo::GetBaseFormatL(TTmCharFormat& aCharFormat,
   445 							 RTmParFormat& aParFormat) const
   446 	{
   447 	ASSERT(iBaseEditor);
   448 	iBaseEditor->GetBaseFormatL(aCharFormat, aParFormat);
   449 	}
   450 
   451 void CEditorWithUndo::CopyToStoreL(CStreamStore& aStore,
   452 											CStreamDictionary& aDictionary,
   453 											TInt aPos,
   454 											TInt aLength) const
   455 	{
   456 	ASSERT(iBaseEditor);
   457 	MUnifiedEditor::MClipboardSupport* ci = iBaseEditor->ClipboardSupport();
   458 	ASSERT(ci);
   459 	ci->CopyToStoreL(aStore, aDictionary, aPos, aLength);
   460 	}
   461 
   462 //
   463 // methods for altering styles
   464 //
   465 TInt CEditorWithUndo::CreateStyleL(const RTmStyle& aStyle)
   466 	{
   467 	ASSERT(iFactory);
   468 	const CSingleCommand* proto =
   469 		iFactory->GetCreateStyleProto(aStyle);
   470 	ASSERT(proto);
   471 	return iCommandManager->ExecuteL(*proto);
   472 	}
   473 
   474 TInt CEditorWithUndo::ChangeStyleL(const RTmStyle& aStyle)
   475 	{
   476 	ASSERT(iFactory);
   477 	const CSingleCommand* proto =
   478 		iFactory->GetChangeStyleProto(aStyle);
   479 	ASSERT(proto);
   480 	return iCommandManager->ExecuteL(*proto);
   481 	}
   482 
   483 TInt CEditorWithUndo::SetStyleL(TInt aPos,
   484 											 TInt aLength,
   485 											 const TDesC& aName)
   486 	{
   487 	ASSERT(iFactory);
   488 	const CSingleCommand* proto =
   489 		iFactory->GetSetStyleProto(aPos, aLength, aName);
   490 	ASSERT(proto);
   491 	return iCommandManager->ExecuteL(*proto);
   492 	}
   493 
   494 TInt CEditorWithUndo::DeleteStyleL(const TDesC& aName)
   495 	{
   496 	ASSERT(iFactory);
   497 	const CSingleCommand* proto =
   498 		iFactory->GetDeleteStyleProto(aName);
   499 	ASSERT(proto);
   500 	return iCommandManager->ExecuteL(*proto);
   501 	}
   502 
   503 void CEditorWithUndo::SetBaseFormatL(const TTmCharFormat& aChar,
   504 											  const RTmParFormat& aPar)
   505 	{
   506 	ASSERT(iFactory);
   507 	const CSingleCommand* proto =
   508 		iFactory->GetSetBaseFormatProto(&aChar, &aPar);
   509 	ASSERT(proto);
   510 	iCommandManager->ExecuteL(*proto);
   511 	}
   512 
   513 TInt CEditorWithUndo::RenameStyleL(const TDesC& aOldName,
   514 											const TDesC& aNewName)
   515 	{
   516 	ASSERT(iFactory);
   517 	const CSingleCommand* proto =
   518 		iFactory->GetRenameStyleProto(aOldName, aNewName);
   519 	ASSERT(proto);
   520 	return iCommandManager->ExecuteL(*proto);
   521 	}
   522 
   523 //
   524 // methods for altering format
   525 //
   526 void CEditorWithUndo::DeleteCharFormatL(TInt aPos,
   527 												 TInt aLength)
   528 	{
   529 	ASSERT(iFactory);
   530 	const CSingleCommand* proto =
   531 		iFactory->GetDeleteCharFormatProto(aPos, aLength);
   532 	ASSERT(proto);
   533 	iCommandManager->ExecuteL(*proto);
   534 	}
   535 
   536 void CEditorWithUndo::DeleteParFormatL(TInt aPos,
   537 												TInt aLength)
   538 	{
   539 	ASSERT(iFactory);
   540 	const CSingleCommand* proto =
   541 		iFactory->GetDeleteParFormatProto(aPos, aLength);
   542 	ASSERT(proto);
   543 	iCommandManager->ExecuteL(*proto);
   544 	}
   545 
   546 void CEditorWithUndo::SetCharFormatL(TInt aPos,
   547 											  TInt aLength,
   548 											  const TTmCharFormatLayer& aFormat)
   549 	{
   550 	ASSERT(iFactory);
   551 	const CSingleCommand* proto =
   552 		iFactory->GetSetCharFormatProto(aPos, aLength, aFormat);
   553 	ASSERT(proto);
   554 	iCommandManager->ExecuteL(*proto);
   555 	}
   556 
   557 void CEditorWithUndo::SetParFormatL(TInt aPos,
   558 											 TInt aLength,
   559 											 const RTmParFormatLayer& aFormat)
   560 	{
   561 	ASSERT(iFactory);
   562 	const CSingleCommand* proto =
   563 		iFactory->GetSetParFormatProto(aPos, aLength, aFormat);
   564 	ASSERT(proto);
   565 	iCommandManager->ExecuteL(*proto);
   566 	}
   567 
   568 //
   569 // methods for altering text
   570 //
   571 void CEditorWithUndo::InsertTextL(TInt aPos,
   572 									 const TDesC& aText,
   573 									 const TDesC* aStyle,
   574 									 const TTmCharFormatLayer* aCharFormat,
   575 									 const RTmParFormatLayer* aParFormat)
   576 	{
   577 	ASSERT(iFactory);
   578 	const CSingleCommand* proto =
   579 		iFactory->GetInsertProto(aPos, aText, aStyle, aCharFormat, aParFormat);
   580 	ASSERT(proto);
   581 	iCommandManager->ExecuteL(*proto);
   582 	}
   583 
   584 void CEditorWithUndo::DeleteTextL(TInt aPos, TInt aLength)
   585 	{
   586 	ASSERT(iFactory);
   587 	ASSERT(iBaseEditor)
   588 	TInt picPos = UndoSystem::FindPicture(*iBaseEditor, aPos, aLength);
   589 	if (picPos < 0)
   590 		{
   591 		const CSingleCommand* proto =
   592 			iFactory->GetDeleteProto(aPos, aLength);
   593 		ASSERT(proto);
   594 		iCommandManager->ExecuteL(*proto);
   595 		return;
   596 		}
   597 
   598 	iCommandManager->BeginBatchLC();
   599 	while (0 < aLength)
   600 		{
   601 		picPos = UndoSystem::FindPicture(*iBaseEditor, aPos, aLength);
   602 		const CSingleCommand* proto = 0;
   603 		if (picPos == aPos)
   604 			{
   605 			proto = iFactory->GetDestroyPictureProto(aPos);
   606 			--aLength;
   607 			}
   608 		else
   609 			{
   610 			TInt segLength = 0 <= picPos? picPos - aPos : aLength;
   611 			proto = iFactory->GetDeleteProto(aPos, segLength);
   612 			aLength -= segLength;
   613 			}
   614 		ASSERT(proto);
   615 		iCommandManager->ExecuteL(*proto);
   616 		ASSERT(0 <= aLength);
   617 		}
   618 	CleanupStack::PopAndDestroy();		// command manager's batch
   619 	}
   620 
   621 //
   622 // methods for pictures
   623 //
   624 void CEditorWithUndo::Picture(TInt aPos, TPictureHeader& aPictureOut) const
   625 	{
   626 	ASSERT(iBaseEditor);
   627 	MUnifiedEditor::MPictureSupport* pi = iBaseEditor->PictureSupport();
   628 	if (!pi)
   629 		{
   630 		aPictureOut.iPicture = 0;
   631 		aPictureOut.iPictureType = KNullUid;
   632 		return;
   633 		}
   634 	pi->Picture(aPos, aPictureOut);
   635 	}
   636 
   637 void CEditorWithUndo::InsertPictureL(TInt aPos,
   638 											  const TPictureHeader& aPicture)
   639 	{
   640 	ASSERT(iFactory);
   641 	const CSingleCommand* proto =
   642 		iFactory->GetInsertPictureProto(aPos, aPicture);
   643 	ASSERT(proto);
   644 	iCommandManager->ExecuteL(*proto);
   645 	}
   646 
   647 void CEditorWithUndo::DropPictureL(TInt aPos)
   648 	{
   649 	ASSERT(iFactory);
   650 	const CSingleCommand* proto =
   651 		iFactory->GetDeletePictureProto(aPos);
   652 	ASSERT(proto);
   653 	iCommandManager->ExecuteL(*proto);
   654 	}
   655 
   656 //
   657 // paste
   658 //
   659 
   660 void CEditorWithUndo::PasteFromStoreL(const CStreamStore& aStore,
   661 											   const CStreamDictionary& aDictionary,
   662 											   TInt aPos)
   663 	{
   664 	ASSERT(iFactory);
   665 	const CSingleCommand* proto =
   666 		iFactory->GetPasteProto(aStore, aDictionary, aPos);
   667 	ASSERT(proto);
   668 	iCommandManager->ExecuteL(*proto);
   669 	}
   670 
   671 //
   672 //
   673 // CEditorCommandFactory
   674 //
   675 //
   676 
   677 CEditorCommandFactory::CEditorCommandFactory(MUnifiedEditor& aTarget) :
   678 	iTarget(aTarget),
   679 	iCreateStyleProto(iReps, aTarget),
   680 	iChangeStyleProto(iReps, aTarget),
   681 	iSetStyleProto(iReps, aTarget),
   682 	iDeleteStyleProto(iReps, aTarget),
   683 	iSetCharFormatProto(iReps, aTarget),
   684 	iSetParFormatProto(iReps, aTarget),
   685 	iInsertProto(iReps, aTarget),
   686 	iDeleteProto(iReps, aTarget),
   687 	iDeleteCharFormatProto(iReps, aTarget),
   688 	iDeleteParFormatProto(iReps, aTarget),
   689 	iDeletePictureProto(iReps, aTarget),
   690 	iInsertPictureProto(iReps, aTarget),
   691 	iDestroyPictureProto(iReps, aTarget),
   692 	iRenameStyleProto(iReps, aTarget),
   693 	iSetBaseFormatProto(iReps, aTarget),
   694 	iPasteProto(iReps, aTarget)
   695 	{
   696 	}
   697 
   698 void CEditorCommandFactory::ConstructL()
   699 	{
   700 	iReps.iChar	= CUniqueInstanceRepository<TTmCharFormat>
   701 		::NewL(CompareCharFormats);
   702 	iReps.iPar	= CUniqueInstanceRepository<RTmParFormat>
   703 		::NewL(CompareParFormats, DeleteParFormat, CopyParFormatL);
   704 	iReps.iDes	= CUniqueInstanceRepository<TDes>::NewL();
   705 	}
   706 
   707 CEditorCommandFactory::~CEditorCommandFactory()
   708 	{
   709 	delete iReps.iChar;
   710 	delete iReps.iPar;
   711 	delete iReps.iDes;
   712 	}
   713 
   714 CEditorCommandFactory* CEditorCommandFactory::NewL(MUnifiedEditor& aTarget)
   715 	{
   716 	CEditorCommandFactory* r = new(ELeave) CEditorCommandFactory(aTarget);
   717 	CleanupStack::PushL(r);
   718 	r->ConstructL();
   719 	CleanupStack::Pop(r);
   720 	return r;
   721 	}
   722 
   723 const CEditorCommandChangeStyleProto*
   724 	CEditorCommandFactory::GetChangeStyleProto(const RTmStyle& aStyle)
   725 	{
   726 	iChangeStyleProto.Set(aStyle);
   727 	return &iChangeStyleProto;
   728 	}
   729 
   730 const CEditorCommandCreateStyleProto*
   731 	CEditorCommandFactory::GetCreateStyleProto(const RTmStyle& aStyle)
   732 	{
   733 	iCreateStyleProto.Set(aStyle);
   734 	return &iCreateStyleProto;
   735 	}
   736 
   737 const CEditorCommandSetStyleProto*
   738 	CEditorCommandFactory::GetSetStyleProto(TInt aPos,
   739 					   TInt aLength,
   740 					   const TDesC& aName)
   741 	{
   742 	iSetStyleProto.Set(aPos, aLength, aName);
   743 	return &iSetStyleProto;
   744 	}
   745 
   746 const CEditorCommandDeleteStyleProto*
   747 	CEditorCommandFactory::GetDeleteStyleProto(const TDesC& aName)
   748 	{
   749 	iDeleteStyleProto.Set(aName);
   750 	return &iDeleteStyleProto;
   751 	}
   752 
   753 const CEditorCommandDeleteCharFormatProto*
   754 	CEditorCommandFactory::GetDeleteCharFormatProto(TInt aPos, TInt aLength)
   755 	{
   756 	iDeleteCharFormatProto.Set(aPos, aLength);
   757 	return &iDeleteCharFormatProto;
   758 	}
   759 
   760 const CEditorCommandDeleteParFormatProto*
   761 	CEditorCommandFactory::GetDeleteParFormatProto(TInt aPos, TInt aLength)
   762 	{
   763 	iDeleteParFormatProto.Set(aPos, aLength);
   764 	return &iDeleteParFormatProto;
   765 	}
   766 
   767 const CEditorCommandSetCharFormatProto*
   768 	CEditorCommandFactory::GetSetCharFormatProto(TInt aPos,
   769 						  TInt aLength,
   770 						  const TTmCharFormatLayer& aFormat)
   771 	{
   772 	iSetCharFormatProto.Set(aPos, aLength, aFormat);
   773 	return &iSetCharFormatProto;
   774 	}
   775 
   776 const CEditorCommandSetParFormatProto*
   777 	CEditorCommandFactory::GetSetParFormatProto(TInt aPos,
   778 						 TInt aLength,
   779 						 const RTmParFormatLayer& aFormat)
   780 	{
   781 	iSetParFormatProto.Set(aPos, aLength, aFormat);
   782 	return &iSetParFormatProto;
   783 	}
   784 
   785 const CEditorCommandInsertProto*
   786 	CEditorCommandFactory::GetInsertProto(TInt aPos,
   787 				   const TDesC& aText,
   788 				   const TDesC* aStyle,
   789 				   const TTmCharFormatLayer* aCharFormat,
   790 				   const RTmParFormatLayer* aParFormat)
   791 	{
   792 	iInsertProto.Set(aPos, aText, aStyle, aCharFormat, aParFormat);
   793 	return &iInsertProto;
   794 	}
   795 
   796 const CEditorCommandDeleteProto*
   797 	CEditorCommandFactory::GetDeleteProto(TInt aPos, TInt aLength)
   798 	{
   799 	iDeleteProto.Set(aPos, aLength);
   800 	return &iDeleteProto;
   801 	}
   802 
   803 const CEditorCommandDeletePictureProto*
   804 	CEditorCommandFactory::GetDeletePictureProto(TInt aPos)
   805 	{
   806 	iDeletePictureProto.Set(aPos);
   807 	return &iDeletePictureProto;
   808 	}
   809 
   810 const CEditorCommandInsertPictureProto*
   811 	CEditorCommandFactory::GetInsertPictureProto(TInt aPos,
   812 												 const TPictureHeader& aPicture)
   813 	{
   814 	iInsertPictureProto.Set(aPos, aPicture);
   815 	return &iInsertPictureProto;
   816 	}
   817 
   818 const CEditorCommandDestroyPictureProto*
   819 	CEditorCommandFactory::GetDestroyPictureProto(TInt aPos)
   820 	{
   821 	iDestroyPictureProto.Set(aPos);
   822 	return &iDestroyPictureProto;
   823 	}
   824 
   825 const CEditorCommandRenameStyleProto*
   826 	CEditorCommandFactory::GetRenameStyleProto(const TDesC& aOldName,
   827 										  const TDesC& aNewName)
   828 	{
   829 	iRenameStyleProto.Set(aOldName, aNewName);
   830 	return &iRenameStyleProto;
   831 	}
   832 
   833 const CEditorCommandSetBaseFormatProto*
   834 	CEditorCommandFactory::GetSetBaseFormatProto(const TTmCharFormat* aCharFormat,
   835 												 const RTmParFormat* aParFormat)
   836 	{
   837 	iSetBaseFormatProto.Set(aCharFormat, aParFormat);
   838 	return &iSetBaseFormatProto;
   839 	}
   840 
   841 const CEditorCommandPasteProto*
   842 	CEditorCommandFactory::GetPasteProto(const CStreamStore& aStore,
   843 		const CStreamDictionary& aStreamDictionary,	TInt aPos)
   844 	{
   845 	iPasteProto.Set(aStore, aStreamDictionary, aPos);
   846 	return &iPasteProto;
   847 	}