First public contribution.
2 * Copyright (c) 2000-2010 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
15 * TUndo.cpp test file for UndoSystem classes
22 #include "UndoSystem.h"
23 #include "UndoSystemImpl.h"
24 #include "EditorUndo.h"
25 #include "EditorPlainTextUndo.h"
30 #include "TGraphicsContext.h"
31 #include "form_and_etext_editor.h"
33 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
34 #include <txtclipboard.h>
35 #include "txtfmlyr_internal.h"
40 #define UNUSED_VAR(a) a = a
42 using namespace UndoSystem;
46 CTUndoStep* TestStep = NULL;
47 #define TESTPOINT(p) TestStep->testpoint(p,(TText8*)__FILE__,__LINE__)
48 #define TESTPRINT(p) TestStep->print(p,(TText8*)__FILE__,__LINE__)
57 class CLogger : public CBase
60 virtual void Output(const TDesC& aText) = 0;
63 TBuf<16> num(_L("<"));
72 CLogger& operator<<(CLogger& aLog, const TDesC& aText)
77 CLogger& operator<<(CLogger& aLog, TInt aVal)
84 class CCheckingLogger : public CLogger
90 void SetCheckString(const TDesC& aCheck) { iCheck = &aCheck; iPos = 0; iFailed = EFalse; }
91 TBool Failed() { return iFailed; }
92 TBool Passed() { return !iFailed && iCheck && iCheck->Length() == iPos; }
93 void Output(const TDesC& aText)
95 if (!iCheck || iFailed)
97 TInt length = aText.Length();
98 TInt maxLength = iCheck->Length() - iPos;
99 TPtrC mid = iCheck->Mid(iPos, length < maxLength? length : maxLength);
100 if (aText.Compare(mid) != 0)
103 iPos += aText.Length();
107 class CStoringLogger : public CLogger
112 ~CStoringLogger() { delete iStore; }
113 HBufC* GetStore() { HBufC* r = iStore; iStore = 0; iMaxLength = 0; return r; }
114 void Output(const TDesC& aText)
118 iStore = HBufC::NewL(50);
121 while (iMaxLength < aText.Length() + iStore->Length())
124 iStore = iStore->ReAllocL(iMaxLength);
126 iStore->Des().Append(aText);
137 class CCommandOffset;
138 class CCommandToggle;
139 class CTestCommand : public CSingleCommand
142 TUid FamilyUid() const
144 return TUid::Uid(12345);
146 virtual CCommandOffset* CastToCCommandOffset() { return 0; }
147 virtual CCommandToggle* CastToCCommandToggle() { return 0; }
151 class CCommandOffset : public CTestCommand
158 static CCommandOffset* NewL(TInt aOffset, TInt* aTarget, CLogger* aLogger = 0)
160 CCommandOffset* r = new(ELeave) CCommandOffset;
161 r->iOffset = aOffset;
162 r->iTarget = aTarget;
163 r->iLogger = aLogger;
166 void SetLogger(CLogger* aLogger) { iLogger = aLogger; }
167 TInt ExecuteL() const
170 (*iLogger) << _L("offset") << iOffset;
174 CCommand* CreateInverseL() const
176 return NewL(-iOffset, iTarget, iLogger);
178 void Add(TInt aOffset) { iOffset += aOffset; }
179 CCommandOffset* CastToCCommandOffset() { return this; }
182 // Negate (only if iTog is ETrue!)
183 class CCommandToggle : public CTestCommand
190 static CCommandToggle* NewL(TBool aTog, TInt* aTarget, CLogger* aLogger = 0)
192 CCommandToggle* r = new(ELeave) CCommandToggle;
194 r->iTarget = aTarget;
195 r->iLogger = aLogger;
198 void SetLogger(CLogger* aLogger) { iLogger = aLogger; }
199 TInt ExecuteL() const
203 (*iLogger) << _L("negate") << (iTog? 1:0);
206 *iTarget = -*iTarget;
209 CCommand* CreateInverseL() const
211 return NewL(iTog, iTarget, iLogger);
218 CCommandToggle* CastToCCommandToggle() { return this; }
221 // command prototypes
222 class CCommandIncProto : public CTestCommand
226 CCommandIncProto() {}
228 static CCommandIncProto* NewL(TInt* aTarget, CLogger* aLogger = 0)
230 CCommandIncProto* r = new(ELeave) CCommandIncProto;
231 r->iTarget = aTarget;
232 r->iLogger = aLogger;
235 TInt ExecuteL() const
238 (*iLogger) << _L("inc<>");
242 CCommand* CreateInverseL() const
244 return CCommandOffset::NewL(-1, iTarget, iLogger);
246 TBool PrepareToAddInverseToLastL(CSingleCommand& aLastCommand) const
248 if (aLastCommand.FamilyUid() != TUid::Uid(12345))
250 return !!static_cast<CTestCommand&>(aLastCommand).CastToCCommandOffset();
252 void AddInverseToLast(CSingleCommand& aLastCommand) const
255 static_cast<CTestCommand&>(aLastCommand).CastToCCommandOffset();
261 class CCommandDecProto : public CTestCommand
265 CCommandDecProto() {}
267 static CCommandDecProto* NewL(TInt* aTarget, CLogger* aLogger = 0)
269 CCommandDecProto* r = new(ELeave) CCommandDecProto;
270 r->iTarget = aTarget;
271 r->iLogger = aLogger;
274 TInt ExecuteL() const
277 (*iLogger) << _L("dec<>");
281 CCommand* CreateInverseL() const
283 return CCommandOffset::NewL(1, iTarget, iLogger);
285 TBool PrepareToAddInverseToLastL(CSingleCommand& aLastCommand) const
287 if (aLastCommand.FamilyUid() != TUid::Uid(12345))
289 return !!static_cast<CTestCommand&>(aLastCommand).CastToCCommandOffset();
291 void AddInverseToLast(CSingleCommand& aLastCommand) const
294 static_cast<CTestCommand&>(aLastCommand).CastToCCommandOffset();
300 class CCommandNegProto : public CTestCommand
304 CCommandNegProto() {}
306 static CCommandNegProto* NewL(TInt* aTarget, CLogger* aLogger = 0)
308 CCommandNegProto* r = new(ELeave) CCommandNegProto;
309 r->iTarget = aTarget;
310 r->iLogger = aLogger;
313 TInt ExecuteL() const
316 (*iLogger) << _L("neg<>");
317 *iTarget = -*iTarget;
320 CCommand* CreateInverseL() const
322 return CCommandToggle::NewL(ETrue, iTarget, iLogger);
324 TBool PrepareToAddInverseToLastL(CSingleCommand& aLastCommand) const
326 if (aLastCommand.FamilyUid() != TUid::Uid(12345))
328 return !!static_cast<CTestCommand&>(aLastCommand).CastToCCommandToggle();
330 void AddInverseToLast(CSingleCommand& aLastCommand) const
333 static_cast<CTestCommand&>(aLastCommand).CastToCCommandToggle();
339 // command whose inverse is a batch command
340 class CCommandDecThenNegProto : public CTestCommand
344 CCommandDecThenNegProto() {}
346 static CCommandDecThenNegProto* NewL(TInt* aTarget, CLogger* aLogger = 0)
348 CCommandDecThenNegProto* r = new(ELeave) CCommandDecThenNegProto;
349 r->iTarget = aTarget;
350 r->iLogger = aLogger;
353 TInt ExecuteL() const
356 (*iLogger) << _L("decneg<>");
357 *iTarget = -(*iTarget - 1);
360 CCommand* CreateInverseL() const
362 CBatchCommand* batch = CBatchCommand::NewLC();
363 batch->PushL(CCommandOffset::NewL(1, iTarget, iLogger));
364 batch->PushL(CCommandToggle::NewL(ETrue, iTarget, iLogger));
365 CleanupStack::Pop(batch);
370 class CCommandCannotDo : public CTestCommand
374 static CCommandCannotDo* NewL(CLogger* aLogger)
376 CCommandCannotDo* r = new(ELeave) CCommandCannotDo;
377 r->iLogger = aLogger;
380 TInt ExecuteL() const
383 (*iLogger) << _L("nodo<>");
384 return KErrNotSupported;
386 CCommand* CreateInverseL() const
392 class CCommandCannotInvert : public CTestCommand
396 static CCommandCannotInvert* NewL(CLogger* aLogger)
398 CCommandCannotInvert* r = new(ELeave) CCommandCannotInvert;
399 r->iLogger = aLogger;
402 TInt ExecuteL() const
405 (*iLogger) << _L("noinv<>");
408 CCommand* CreateInverseL() const
411 (*iLogger) << _L("noinvfail.");
412 User::Leave(KErrNotSupported);
417 class CCommandLeavesInvert : public CTestCommand
422 static CCommandLeavesInvert* NewL(CLogger* aLogger)
424 CCommandLeavesInvert* r = new(ELeave) CCommandLeavesInvert;
425 r->iLogger = aLogger;
429 TInt ExecuteL() const
432 (*iLogger) << _L("leaveinv<>");
435 CCommand* CreateInverseL() const
441 (*iLogger) << _L("noinvfail.");
442 User::Leave(KErrNotFound);
448 class CCommandNoMemory : public CTestCommand
453 TBool iFailAddToLast;
455 mutable TBool iLogExecuteFailed;
457 static CCommandNoMemory* NewL(CLogger* aLogger)
459 CCommandNoMemory* r = new(ELeave) CCommandNoMemory;
460 r->iLogger = aLogger;
461 r->iFailInvert = ETrue;
462 r->iFailAddToLast = ETrue;
463 r->iFailExecute = ETrue;
464 r->iLogExecuteFailed= ETrue;
467 TInt ExecuteL() const
471 if (iLogger && iLogExecuteFailed)
472 (*iLogger) << _L("nomemfailexe.");
473 iLogExecuteFailed = EFalse;
474 User::Leave(KErrNoMemory);
477 (*iLogger) << _L("nomem<>");
480 CCommand* CreateInverseL() const
485 (*iLogger) << _L("nomemfailinv.");
486 User::Leave(KErrNoMemory);
490 TBool PrepareToAddInverseToLastL(CSingleCommand&) const
495 (*iLogger) << _L("nomemfailadd.");
496 User::Leave(KErrNoMemory);
502 // this gatekeeper refuses non-undoable requests
503 class CRefuserGatekeeper : public CBase, public MNotUndoableGatekeeper
506 TBool RetryOutOfMemoryL(TInt)
510 TBool AllowNotUndoableL(TInt)
516 // this gatekeeper permits all non-undoable requests
517 // (not just KErrNotSupported and KErrNoMemory)
518 class CPermitterGatekeeper : public CBase, public MNotUndoableGatekeeper
521 TBool RetryOutOfMemoryL(TInt)
525 TBool AllowNotUndoableL(TInt)
531 // this gatekeeper makes the CCommandNoMemory fail less the more times it is called
532 class CMemoryReclaimGatekeeper : public CRefuserGatekeeper
535 CCommandNoMemory* iTarget;
536 CMemoryReclaimGatekeeper(CCommandNoMemory* aTarget = 0) : iTarget(aTarget) {}
537 TBool RetryOutOfMemoryL(TInt aNumRetries)
539 if (aNumRetries == 0)
541 iTarget->iFailAddToLast = EFalse;
544 if (aNumRetries == 1)
546 iTarget->iFailInvert = EFalse;
549 if (aNumRetries == 2)
551 iTarget->iFailExecute = EFalse;
565 // a cut-down set of attributes for testing purposes
566 class CUndoTestPicture : public CPicture
570 CUndoTestPicture(TInt aChar) : iDesc(1) { iDesc[0] = static_cast<TText>(aChar); }
571 void Draw(CGraphicsContext&, const TPoint&, const TRect&, MGraphicsDeviceMap*) const {}
572 void ExternalizeL(RWriteStream&) const {}
573 void GetOriginalSizeInTwips(TSize&) const {}
574 TPtrC Description() const { return iDesc; }
577 struct TTestAttributes
582 TTestAttributes() : iCharFlags(0), iParFlags(0), iStyle(-1) {}
583 TBool operator==(TTestAttributes& a)
585 return iCharFlags == a.iCharFlags && iParFlags == a.iParFlags && iStyle == a.iStyle;
588 CLogger& operator<<(CLogger& log, TTestAttributes& at)
590 TBuf<3> buf(_L("Aa0"));
591 buf[0] = (TText)(buf[0] + (at.iCharFlags & 15));
592 buf[1] = (TText)(buf[1] + (at.iParFlags & 15));
593 buf[2] = (TText)(buf[2] + at.iStyle);
596 // Test editor, badly behaved if something leaves.
597 // The only formats supported are bold, italic, keep together and keep with next.
598 class CTestEditor : public CBase, public MUnifiedEditor,
599 public MUnifiedEditor::MStyleSupport,
600 public MUnifiedEditor::MPictureSupport,
601 public MUnifiedEditor::MClipboardSupport
603 TTestAttributes iBase;
604 TTestAttributes iStyles[10];
605 TBuf<KMaxParagraphStyleName> iStyleNames[10];
607 CArrayFix<TTestAttributes>* iAttrs;
609 CArrayFix<CUndoTestPicture*>* iPics;
611 CTestEditor* ConstructL()
613 iText = CBufSeg::NewL(5 * sizeof(TText));
614 iAttrs = new(ELeave) CArrayFixFlat<TTestAttributes>(5);
615 iPics = new(ELeave) CArrayFixFlat<CUndoTestPicture*>(5);
618 TInt Style(const TDesC& aName) const
620 for (int i = 0; i != iNumStyles; ++i)
621 if (aName == iStyleNames[i])
625 TInt InsertStylePos(const TDesC& aName) const
628 for (i = 0; i != iNumStyles; ++i)
629 if (aName.Compare(iStyleNames[i]) <= 0)
633 void ReassignStyles(TInt aFrom, TInt aTo)
635 ASSERT(-1 <= aTo && aTo < iNumStyles);
636 ASSERT(0 <= aFrom && aFrom < iNumStyles);
641 aTo = iNumStyles - 1;
651 TInt len = DocumentLength();
654 for (i = 0; i != len; ++i)
656 TTestAttributes* attr = &iAttrs->At(i);
657 if (aFrom == attr->iStyle)
658 attr->iStyle = static_cast<TInt8>(setTo);
659 else if (low <= attr->iStyle && attr->iStyle <= high)
660 attr->iStyle = static_cast<TInt8>(attr->iStyle + delta);
662 for (i = aFrom; i != aTo; i -= delta)
664 iStyles[i] = iStyles[i - delta];
665 iStyleNames[i] = iStyleNames[i - delta];
668 void DoDeleteStyle(TInt aForDeletion)
670 ASSERT(aForDeletion < iNumStyles);
671 ReassignStyles(aForDeletion, -1);
674 void DoAddStyle(const TDesC& aNewName, const TTestAttributes& aAttr)
676 ASSERT(iNumStyles < 10);
677 TInt pos = InsertStylePos(aNewName);
679 ReassignStyles(iNumStyles - 1, pos);
680 iStyles[pos] = aAttr;
681 iStyleNames[pos] = aNewName;
683 static void BoldToAttr(TTestAttributes& aAttr, const TTmCharFormat& aCFormat)
685 if (aCFormat.iFontSpec.IsBold())
686 aAttr.iCharFlags |= 1;
688 aAttr.iCharFlags &= ~1;
690 static void ItalicToAttr(TTestAttributes& aAttr, const TTmCharFormat& aCFormat)
692 if (aCFormat.iFontSpec.IsItalic())
693 aAttr.iCharFlags |= 2;
695 aAttr.iCharFlags &= ~2;
697 static void CharFormatToAttr(TTestAttributes& aAttr, const TTmCharFormat& aCFormat)
699 aAttr.iCharFlags = 0;
700 BoldToAttr(aAttr, aCFormat);
701 ItalicToAttr(aAttr, aCFormat);
703 static void CharLayerToAttr(TTestAttributes& aAttr, const TTmCharFormatLayer& aCLayer)
705 if (aCLayer.iMask.iFlags & TTmCharFormatMask::EBold)
707 aAttr.iCharFlags |= 4;
708 BoldToAttr(aAttr, aCLayer.iFormat);
710 if (aCLayer.iMask.iFlags & TTmCharFormatMask::EItalic)
712 aAttr.iCharFlags |= 8;
713 ItalicToAttr(aAttr, aCLayer.iFormat);
716 static void KeepTogetherToAttr(TTestAttributes& aAttr, const RTmParFormat& aPFormat)
718 if (aPFormat.iFlags & RTmParFormat::EKeepTogether)
719 aAttr.iParFlags |= 1;
721 aAttr.iParFlags &= ~1;
723 static void KeepWithNextToAttr(TTestAttributes& aAttr, const RTmParFormat& aPFormat)
725 if (aPFormat.iFlags & RTmParFormat::EKeepWithNext)
726 aAttr.iParFlags |= 2;
728 aAttr.iParFlags &= ~2;
730 static void ParFormatToAttr(TTestAttributes& aAttr, const RTmParFormat& aPFormat)
733 KeepTogetherToAttr(aAttr, aPFormat);
734 KeepWithNextToAttr(aAttr, aPFormat);
736 static void ParLayerToAttr(TTestAttributes& aAttr, const RTmParFormatLayer& aPLayer)
738 if (aPLayer.iMask.iFlags & TTmParFormatMask::EKeepTogether)
740 aAttr.iParFlags |= 4;
741 KeepTogetherToAttr(aAttr, aPLayer.iFormat);
743 if (aPLayer.iMask.iFlags & TTmParFormatMask::EKeepWithNext)
745 aAttr.iParFlags |= 8;
746 KeepWithNextToAttr(aAttr, aPLayer.iFormat);
749 static void BoldAttrToCharFormat(TTmCharFormat& aCFormat, const TTestAttributes& aAttr)
751 if (aAttr.iCharFlags & 1)
752 aCFormat.iFontSpec.SetBold(ETrue);
754 static void ItalicAttrToCharFormat(TTmCharFormat& aCFormat, const TTestAttributes& aAttr)
756 if (aAttr.iCharFlags & 2)
757 aCFormat.iFontSpec.SetItalic(ETrue);
759 static void ResetCharFormat(TTmCharFormat& aCFormat)
764 static void AttrToCharFormat(TTmCharFormat& aCFormat, const TTestAttributes& aAttr)
766 ResetCharFormat(aCFormat);
767 BoldAttrToCharFormat(aCFormat, aAttr);
768 ItalicAttrToCharFormat(aCFormat, aAttr);
770 static void MergeAttrToCharLayer(TTmCharFormatLayer& aCLayer, const TTestAttributes& aAttr)
772 if (aAttr.iCharFlags & 4)
774 aCLayer.iMask.iFlags |= TTmCharFormatMask::EBold;
775 BoldAttrToCharFormat(aCLayer.iFormat, aAttr);
777 if (aAttr.iCharFlags & 8)
779 aCLayer.iMask.iFlags |= TTmCharFormatMask::EItalic;
780 ItalicAttrToCharFormat(aCLayer.iFormat, aAttr);
783 static void AttrToCharLayer(TTmCharFormatLayer& aCLayer, const TTestAttributes& aAttr)
785 ResetCharFormat(aCLayer.iFormat);
786 aCLayer.iMask.iFlags = 0;
787 MergeAttrToCharLayer(aCLayer, aAttr);
789 static void ResetParFormat(RTmParFormat& aPFormat)
792 CleanupClosePushL(p);
794 CleanupStack::PopAndDestroy();
796 static void KeepTogetherAttrToParFormat(RTmParFormat& aPFormat, const TTestAttributes& aAttr)
798 if (aAttr.iParFlags & 1)
799 aPFormat.iFlags |= RTmParFormat::EKeepTogether;
801 static void KeepWithNextAttrToParFormat(RTmParFormat& aPFormat, const TTestAttributes& aAttr)
803 if (aAttr.iParFlags & 2)
804 aPFormat.iFlags |= RTmParFormat::EKeepWithNext;
806 static void AttrToParFormat(RTmParFormat& aPFormat, const TTestAttributes& aAttr)
808 ResetParFormat(aPFormat);
809 KeepTogetherAttrToParFormat(aPFormat, aAttr);
810 KeepWithNextAttrToParFormat(aPFormat, aAttr);
812 static void MergeAttrToParLayer(RTmParFormatLayer& aPLayer, const TTestAttributes& aAttr)
814 if (aAttr.iParFlags & 4)
816 aPLayer.iMask.iFlags |= TTmParFormatMask::EKeepTogether;
817 KeepTogetherAttrToParFormat(aPLayer.iFormat, aAttr);
819 if (aAttr.iParFlags & 8)
821 aPLayer.iMask.iFlags |= TTmParFormatMask::EKeepWithNext;
822 KeepWithNextAttrToParFormat(aPLayer.iFormat, aAttr);
825 static void AttrToParLayer(RTmParFormatLayer& aPLayer, const TTestAttributes& aAttr)
827 ResetParFormat(aPLayer.iFormat);
828 aPLayer.iMask.iFlags = 0;
829 MergeAttrToParLayer(aPLayer, aAttr);
835 // workaround for CBufSeg bug
836 if (0 < iText->Size())
837 iText->Delete(iText->Size() - 1, 1);
841 static CTestEditor* NewL() { return (new(ELeave) CTestEditor)->ConstructL(); }
849 void AlterGranularityL(TInt aNewGranularity)
851 CBufSeg* newIText = CBufSeg::NewL(aNewGranularity * sizeof(TText));
852 CleanupStack::PushL(newIText);
855 while (pos < iText->Size())
857 TInt length = transfer.MaxLength();
858 if (iText->Size() - pos < length)
859 length = iText->Size() - pos;
860 iText->Read(pos, transfer, length);
861 newIText->InsertL(pos, transfer, length);
862 pos += transfer.Length();
864 CleanupStack::Pop(newIText);
865 // workaround for CBufSeg bug
866 if (0 < iText->Size())
867 iText->Delete(iText->Size() - 1, 1);
871 void Print(CLogger& log)
873 TInt length = DocumentLength();
876 for (i = 0; i < length;)
880 TInt picPos = seg.Locate(CEditableText::EPictureCharacter);
883 // shorten seg to just before the picture character
884 TPtrC temp(seg.Ptr(), picPos);
889 CUndoTestPicture* pic = iPics->At(i);
891 log << _L("{pic:") << pic->Description() << _L("}");
893 log << _L("{nopic}");
902 log << _L("} styles{");
903 for(i = 0; i != iNumStyles; ++i)
907 log << iStyleNames[i] << _L(":") << iStyles[i];
909 log << _L("} attr{");
910 for (i = 0; i != length; ++i)
911 log << iAttrs->At(i);
914 MTmOptionalInterface* Interface(TUint aId)
916 if (aId == KUidMUnifiedEditorStyleSupport)
917 return static_cast<MUnifiedEditor::MStyleSupport*>(this);
918 if (aId == KUidMUnifiedEditorPictureSupport)
919 return static_cast<MUnifiedEditor::MPictureSupport*>(this);
920 if (aId == KUidMUnifiedEditorClipboardSupport)
921 return static_cast<MUnifiedEditor::MClipboardSupport*>(this);
925 void InsertTextL(TInt aPos, const TDesC& aText,
927 const TTmCharFormatLayer* aCharFormat,
928 const RTmParFormatLayer* aParFormat)
930 TTestAttributes attr;
931 attr.iStyle = aStyle? (TInt8)Style(*aStyle) : (TInt8)-1;
933 CharLayerToAttr(attr, *aCharFormat);
935 ParLayerToAttr(attr, *aParFormat);
936 iText->InsertL(aPos * sizeof(TText), aText.Ptr(), aText.Length() * sizeof(TText));
937 iAttrs->InsertL(aPos, attr, aText.Length());
938 CUndoTestPicture* nullPic = 0;
939 iPics->InsertL(aPos, nullPic, aText.Length());
941 void DeleteTextL(TInt aPos, TInt aLength)
943 iText->Delete(aPos * sizeof(TText), aLength * sizeof(TText));
944 iAttrs->Delete(aPos, aLength);
945 for (int i = aPos; i != aPos + aLength; ++i)
947 iPics->Delete(aPos, aLength);
949 void SetBaseFormatL(const TTmCharFormat& aCharFormat,const RTmParFormat& aParFormat)
951 CharFormatToAttr(iBase, aCharFormat);
952 ParFormatToAttr(iBase, aParFormat);
954 void SetCharFormatL(TInt aPos,TInt aLength,const TTmCharFormatLayer& aFormat)
956 TInt end = aPos + aLength;
957 if (DocumentLength() < end)
958 end = DocumentLength();
959 for (; aPos < end; ++aPos)
960 CharLayerToAttr(iAttrs->At(aPos), aFormat);
962 void SetParFormatL(TInt aPos,TInt aLength,const RTmParFormatLayer& aFormat)
964 TInt end = aPos + aLength;
965 if (DocumentLength() < end)
966 end = DocumentLength();
967 for (; aPos < end; ++aPos)
968 ParLayerToAttr(iAttrs->At(aPos), aFormat);
970 void DeleteCharFormatL(TInt aPos,TInt aLength)
972 TInt end = aPos + aLength;
973 if (DocumentLength() < end)
974 end = DocumentLength();
975 for (; aPos < end; ++aPos)
976 iAttrs->At(aPos).iCharFlags = 0;
978 void DeleteParFormatL(TInt aPos,TInt aLength)
980 TInt end = aPos + aLength;
981 if (DocumentLength() < end)
982 end = DocumentLength();
983 for (; aPos < end; ++aPos)
984 iAttrs->At(aPos).iParFlags = 0;
986 TInt CreateStyleL(const RTmStyle& aStyle)
988 TInt styleNo = Style(aStyle.iName);
990 return KErrAlreadyExists;
991 TTestAttributes newAttr;
992 CharLayerToAttr(newAttr, aStyle.iCharFormat);
993 ParLayerToAttr(newAttr, aStyle.iParFormat);
994 DoAddStyle(aStyle.iName, newAttr);
997 TInt ChangeStyleL(const RTmStyle& aStyle)
999 TInt styleNo = Style(aStyle.iName);
1001 return KErrNotFound;
1002 iStyles[styleNo] = TTestAttributes();
1003 CharLayerToAttr(iStyles[styleNo], aStyle.iCharFormat);
1004 ParLayerToAttr(iStyles[styleNo], aStyle.iParFormat);
1007 TInt SetStyleL(TInt aPos, TInt aLength, const TDesC& aName)
1012 styleNo = Style(aName);
1014 return KErrNotFound;
1016 TInt end = aPos + aLength;
1017 for (; aPos < end; ++aPos)
1018 iAttrs->At(aPos).iStyle = (TInt8)styleNo;
1021 TInt RenameStyleL(const TDesC& aOldName, const TDesC& aNewName)
1023 TInt oldNo = Style(aOldName);
1025 return KErrNotFound;
1026 TTestAttributes temp = iStyles[oldNo];
1027 TInt newNo = InsertStylePos(aNewName);
1030 ReassignStyles(oldNo, newNo);
1031 iStyles[newNo] = temp;
1032 iStyleNames[newNo] = aNewName;
1035 TInt DeleteStyleL(const TDesC& aName)
1037 TInt n = Style(aName);
1039 return KErrNotFound;
1043 void InsertPictureL(TInt aPos, const TPictureHeader& aPictureIn)
1046 picChar[0] = CEditableText::EPictureCharacter;
1047 InsertTextL(aPos, picChar, 0, 0, 0);
1048 iPics->At(aPos) = static_cast<CUndoTestPicture*>(aPictureIn.iPicture.AsPtr());
1050 void DropPictureL(TInt aPos)
1054 if (ptr[0] == CEditableText::EPictureCharacter)
1056 iPics->At(aPos) = 0;
1057 DeleteTextL(aPos, 1);
1060 void Picture(TInt aPos, TPictureHeader& aPictureOut) const
1062 CPicture* pic = iPics->At(aPos);
1063 aPictureOut.iPictureType = KUidXzePictureType;
1064 aPictureOut.iPicture = pic;
1066 TInt DocumentLength() const
1068 return iText->Size() / sizeof(TText);
1070 void GetText(TInt aPos, TPtrC& aText) const
1073 if (DocumentLength() <= aPos)
1074 aPos = DocumentLength();
1075 TPtr8 ptr = iText->Ptr(aPos * sizeof(TText));
1076 aText.Set((TText*)ptr.Ptr(), ptr.Length()/sizeof(TText));
1078 void GetBaseFormatL(TTmCharFormat& aCharFormat, RTmParFormat& aParFormat) const
1080 AttrToCharFormat(aCharFormat, iBase);
1081 AttrToParFormat(aParFormat, iBase);
1083 void GetCharFormat(TInt aPos, TFormatLevel aLevel,
1084 TTmCharFormatLayer& aFormat, TInt& aRunLength) const
1086 TInt length = DocumentLength();
1092 TTestAttributes attr = iAttrs->At(aPos);
1093 if (aLevel == ESpecific)
1095 AttrToCharLayer(aFormat, attr);
1099 AttrToCharLayer(aFormat, iBase);
1100 MergeAttrToCharLayer(aFormat, attr);
1102 TInt pos = aPos + 1;
1103 while (pos < length && attr == iAttrs->At(pos))
1105 aRunLength = pos - aPos;
1107 void GetParFormatL(TInt aPos, TFormatLevel aLevel,
1108 RTmParFormatLayer& aFormat, TInt& aRunLength) const
1110 TInt length = DocumentLength();
1116 TTestAttributes attr = iAttrs->At(aPos);
1117 if (aLevel == ESpecific)
1119 AttrToParLayer(aFormat, attr);
1123 AttrToParLayer(aFormat, iBase);
1124 MergeAttrToParLayer(aFormat, attr);
1126 TInt pos = aPos + 1;
1127 while (pos < length && attr == iAttrs->At(pos))
1129 aRunLength = pos - aPos;
1131 TInt StyleCount() const { return iNumStyles; }
1132 void GetStyle(TInt aPos, TPtrC& aName, TInt& aRunLength) const
1134 TInt length = DocumentLength();
1135 if (aPos < 0 || length <= aPos)
1137 aName.Set(iStyleNames[0].Ptr(), 0);
1141 TInt styleNo = iAttrs->At(aPos).iStyle;
1143 aName.Set(iStyleNames[0].Ptr(), 0);
1145 aName.Set(iStyleNames[styleNo]);
1146 TInt pos = aPos + 1;
1147 while (pos < length && iAttrs->At(pos).iStyle == styleNo)
1149 aRunLength = pos - aPos;
1152 TInt GetStyleByNameL(const TDesC& aName, RTmStyle& aStyle) const
1154 return GetStyleByIndexL(Style(aName), aStyle);
1156 TInt GetStyleByIndexL(TInt aIndex, RTmStyle& aStyle) const
1158 if (aIndex < 0 || iNumStyles <= aIndex)
1159 return KErrNotFound;
1160 aStyle.iName = iStyleNames[aIndex];
1161 AttrToParLayer(aStyle.iParFormat, iStyles[aIndex]);
1162 AttrToCharLayer(aStyle.iCharFormat, iStyles[aIndex]);
1165 void CopyToStoreL(CStreamStore& aStore, CStreamDictionary& aDictionary,
1166 TInt aPos, TInt aLength) const
1168 ASSERT(aPos + aLength <= DocumentLength());
1171 RStoreWriteStream stream;
1172 TStreamId id = stream.CreateLC(aStore);
1173 stream.WriteInt32L(aLength);
1174 RBufReadStream input_stream(*iText, aPos * sizeof(TText));
1175 TMemoryStreamUnicodeSource source(input_stream);
1176 TUnicodeCompressor c;
1177 c.CompressL(stream, source, KMaxTInt, aLength);
1178 input_stream.Close();
1180 aDictionary.AssignL(KClipboardUidTypePlainText, id);
1181 CleanupStack::PopAndDestroy(); // close stream
1183 // now write out formatting in our own bizarre format
1185 // in actual fact this probably wouldn't test that much, so I won't
1186 // bother right now.
1188 void PasteFromStoreL(const CStreamStore& aStore,
1189 const CStreamDictionary& aDictionary, TInt aPos)
1191 ASSERT(aPos <= DocumentLength());
1192 TStreamId id = aDictionary.At(KClipboardUidTypePlainText);
1193 RStoreReadStream stream;
1194 stream.OpenLC(aStore, id);
1195 TInt length = stream.ReadInt32L();
1196 RBufWriteStream bufferStream;
1197 bufferStream.Insert(*iText, aPos * sizeof(TText));
1198 TMemoryStreamUnicodeSink sink(bufferStream);
1200 e.ExpandL(sink, stream, length);
1201 bufferStream.CommitL();
1202 bufferStream.Close();
1203 CleanupStack::PopAndDestroy(); // close stream
1205 // and if we get round to adding some formatting to the copy method,
1206 // then we should deal with it here also
1208 // but not today. Just add the appropriate spaces into all the structures.
1209 TTestAttributes attr;
1210 iAttrs->InsertL(aPos, attr, length);
1211 CUndoTestPicture* nullPic = 0;
1212 iPics->InsertL(aPos, nullPic, length);
1216 CLogger& operator<<(CLogger& log, CTestEditor& ed) { ed.Print(log); return log; }
1218 // 1 - CCommandStack test
1219 TInt ExecuteStackL(CCommandStack& a)
1223 CSingleCommand* single = a.Top()->Single();
1226 TESTPRINT(_L("CCommandStack : stack unexpectedly contained batches"));
1236 TInt CheckLog(CCheckingLogger& a)
1240 TESTPRINT(_L("CCommandStack... : log failed"));
1243 TInt CheckTop(CCommandStack& aStack, CCommand* aTop)
1245 if (aStack.Top() != aTop)
1247 TESTPRINT(_L("CCommandStack : unexpected item at top of stack"));
1252 TInt CheckCount(CCommandStack& aStack, TInt aExpectedCount)
1254 if (aStack.Count() != aExpectedCount)
1256 TESTPRINT(_L("CCommandStack : stack an unexpected size"));
1261 TInt CheckPop(CCommandStack& aStack)
1263 CCommand* check = aStack.Top();
1264 if (aStack.Pop() != check)
1266 TESTPRINT(_L("CCommandStack : Pop() does not match Top()"));
1271 void AddStuffL(CCommandStack& aStack, TInt* aTarget, CLogger* aLog)
1273 TInt startCount = aStack.Count();
1274 CheckTop(aStack, 0);
1275 aStack.PrepareToPushL(1);
1276 CheckCount(aStack, startCount);
1277 CheckTop(aStack, 0);
1278 CheckCount(aStack, startCount);
1279 CCommand* temp = CCommandIncProto::NewL(aTarget, aLog);
1281 CheckCount(aStack, startCount + 1);
1282 CheckTop(aStack, temp);
1283 aStack.PrepareToPushL(2);
1284 CheckCount(aStack, startCount + 1);
1285 CheckTop(aStack, temp);
1286 CheckCount(aStack, startCount + 1);
1287 CheckTop(aStack, temp);
1288 aStack.PrepareToPushL(1);
1289 aStack.PrepareToPushL(3);
1290 CheckCount(aStack, startCount + 1);
1291 CheckTop(aStack, temp);
1292 temp = CCommandDecProto::NewL(aTarget, aLog);
1293 CheckCount(aStack, startCount + 1);
1295 CheckCount(aStack, startCount + 2);
1296 CheckTop(aStack, temp);
1297 CheckTop(aStack, temp);
1298 CheckCount(aStack, startCount + 2);
1299 CheckTop(aStack, temp);
1300 temp = CCommandIncProto::NewL(aTarget, aLog);
1302 CheckTop(aStack, temp);
1303 CheckCount(aStack, startCount + 3);
1304 aStack.PrepareToPushL(1);
1305 CheckTop(aStack, temp);
1306 aStack.PrepareToPushL(2);
1307 CheckTop(aStack, temp);
1308 temp = CCommandNegProto::NewL(aTarget, aLog);
1309 CheckCount(aStack, startCount + 3);
1311 CheckCount(aStack, startCount + 4);
1312 CheckTop(aStack, temp);
1313 CheckCount(aStack, startCount + 4);
1314 CheckTop(aStack, temp);
1315 temp = CCommandIncProto::NewL(aTarget, aLog);
1316 CheckCount(aStack, startCount + 4);
1318 CheckTop(aStack, temp);
1319 CheckCount(aStack, startCount + 5);
1321 void TestCCommandStackL()
1325 CCheckingLogger* log = new(ELeave) CCheckingLogger;
1327 CCommandStack* stack = CCommandStack::NewL();
1329 AddStuffL(*stack, &target, log);
1331 log->SetCheckString(_L("inc<>neg<>inc<>dec<>inc<>"));
1332 ExecuteStackL(*stack);
1335 CheckCount(*stack, 0);
1336 CCommand* temp = CCommandIncProto::NewL(&target, log);
1337 CheckTop(*stack, 0);
1338 stack->PrepareToPushL(1);
1339 CheckCount(*stack, 0);
1340 CheckTop(*stack, 0);
1341 CheckCount(*stack, 0);
1343 CheckCount(*stack, 1);
1344 stack->PrepareToPushL(1);
1345 CheckCount(*stack, 1);
1346 CCommand* next = CCommandDecProto::NewL(&target, log);
1348 CheckCount(*stack, 2);
1349 stack->PrepareToPushL(1);
1351 stack->PrepareToPushL(1);
1352 CheckCount(*stack, 1);
1353 CheckTop(*stack, temp);
1354 CheckCount(*stack, 1);
1356 stack->PrepareToPushL(1);
1357 CheckCount(*stack, 2);
1358 CheckCount(*stack, 2);
1360 CheckCount(*stack, 1);
1361 CheckTop(*stack, temp);
1365 CheckCount(*stack, 0);
1367 AddStuffL(*stack, &target, log);
1369 CheckCount(*stack, 3);
1370 log->SetCheckString(_L("inc<>neg<>inc<>"));
1371 ExecuteStackL(*stack);
1374 AddStuffL(*stack, &target, log);
1375 stack->PrepareToPushL(1);
1376 CheckCount(*stack, 5);
1378 CheckCount(*stack, 2);
1379 log->SetCheckString(_L("inc<>neg<>"));
1380 ExecuteStackL(*stack);
1386 __UHEAP_MARKENDC(0);
1389 // 2 - CBatchCommand test
1390 void ExecuteBatchL(CBatchCommand& a)
1394 CSingleCommand* single = a.Top();
1396 if (a.Pop() != single)
1398 TESTPRINT(_L("CBatchCommand : Pop() didn't match Top()"));
1405 void CheckTop(CBatchCommand& aBatch, CCommand* aTop)
1407 if (aBatch.Top() != aTop)
1409 TESTPRINT(_L("CCommandBatch : unexpected item at top of stack"));
1414 void TestCBatchCommandL()
1418 CCheckingLogger* log = new(ELeave) CCheckingLogger;
1420 CBatchCommand* batch = CBatchCommand::NewL();
1422 CBatchCommand* b1 = CBatchCommand::NewL();
1423 CBatchCommand* b2 = CBatchCommand::NewL();
1424 CBatchCommand* b3 = CBatchCommand::NewL();
1426 CCommand* s1 = CCommandIncProto::NewL(&target, log);
1427 CCommand* s2 = CCommandDecProto::NewL(&target, log);
1428 CCommand* s3 = CCommandNegProto::NewL(&target, log);
1429 CCommand* s4 = CCommandIncProto::NewL(&target, log);
1430 CCommand* s5 = CCommandDecProto::NewL(&target, log);
1431 CCommand* s6 = CCommandNegProto::NewL(&target, log);
1432 CCommand* s7 = CCommandIncProto::NewL(&target, log);
1433 CCommand* s8 = CCommandDecProto::NewL(&target, log);
1434 CCommand* s9 = CCommandNegProto::NewL(&target, log);
1436 b2->PrepareToPushL(s4);
1438 b2->PrepareToPushL(s8);
1440 b2->PrepareToPushL(s2);
1441 b2->PrepareToPushL(s2);
1444 b3->PrepareToPushL(s3);
1445 b3->PrepareToPushL(s9);
1447 b3->PrepareToPushL(s3);
1449 b3->PrepareToPushL(s7);
1452 b1->PrepareToPushL(s6);
1454 b1->PrepareToPushL(s5);
1456 b1->PrepareToPushL(b3);
1458 b1->PrepareToPushL(b1);
1459 b1->PrepareToPushL(s1);
1460 b1->PrepareToPushL(s1);
1461 b1->PrepareToPushL(b2);
1463 batch->PrepareToPushL(b2);
1465 batch->PrepareToPushL(s1);
1466 batch->PrepareToPushL(s1);
1467 batch->PrepareToPushL(b1);
1469 batch->PrepareToPushL(s1);
1472 CheckTop(*batch, s1);
1474 CheckTop(*batch, s7);
1475 batch->PrepareToPushL(s1);
1476 CheckTop(*batch, s7);
1478 CheckTop(*batch, s1);
1479 batch->PrepareToPushL(s1);
1480 CheckTop(*batch, s1);
1482 CheckTop(*batch, s7);
1484 CheckTop(*batch, s3);
1486 CheckTop(*batch, s9);
1488 CheckTop(*batch, s5);
1490 CheckTop(*batch, s6);
1491 batch->PrepareToPushL(s5);
1492 CheckTop(*batch, s6);
1494 CheckTop(*batch, s5);
1495 b3 = CBatchCommand::NewL();
1496 b3->PrepareToPushL(s9);
1500 b3->PrepareToPushL(s3);
1504 b3->PrepareToPushL(s7);
1508 batch->PrepareToPushL(b3);
1509 CheckTop(*batch, s5);
1511 CheckTop(*batch, s7);
1512 batch->PrepareToPushL(s1);
1515 log->SetCheckString(_L("inc<>inc<>neg<>neg<>dec<>neg<>dec<>dec<>inc<>"));
1516 ExecuteBatchL(*batch);
1522 __UHEAP_MARKENDC(0);
1525 // 3 - CCommandHistory test
1526 void ExecuteHistoryL(CCommandHistory& aHistory, CLogger& aLog)
1528 while (aHistory.Top())
1530 if (aHistory.Top()->Single())
1532 aHistory.Top()->Single()->ExecuteL();
1536 CBatchCommand* batch = aHistory.Top()->Batch();
1537 TESTPOINT(batch != 0);
1538 aLog << _L("batch{");
1539 ExecuteBatchL(*batch);
1542 delete aHistory.Pop();
1545 void TestCCommandHistoryL()
1549 CCommandHistory* history = CCommandHistory::NewL();
1550 CCheckingLogger* log = new(ELeave) CCheckingLogger;
1554 history->SetMaxItems(5);
1555 p = CCommandDecProto::NewL(&target, log);
1556 history->PrepareToAddCommandL(p);
1557 history->AddCommand(p);
1558 p = CCommandIncProto::NewL(&target, log);
1559 history->PrepareToAddCommandL(p);
1560 history->AddCommand(p);
1561 p = CCommandDecProto::NewL(&target, log);
1562 history->PrepareToAddCommandL(p);
1563 history->AddCommand(p);
1564 p = CCommandNegProto::NewL(&target, log);
1565 history->PrepareToAddCommandL(p);
1566 history->AddCommand(p);
1567 history->BeginBatchLC();
1568 p = CCommandIncProto::NewL(&target, log);
1569 history->PrepareToAddCommandL(p);
1570 history->AddCommand(p);
1571 p = CCommandDecProto::NewL(&target, log);
1572 history->PrepareToAddCommandL(p);
1573 history->AddCommand(p);
1574 p = CCommandNegProto::NewL(&target, log);
1575 history->PrepareToAddCommandL(p);
1576 history->AddCommand(p);
1577 CleanupStack::PopAndDestroy();
1578 p = CCommandDecProto::NewL(&target, log);
1579 history->PrepareToAddCommandL(p);
1580 history->AddCommand(p);
1581 CBatchCommand* batch = CBatchCommand::NewL();
1582 p = CCommandDecProto::NewL(&target, log);
1583 batch->PrepareToPushL(p);
1585 p = CCommandNegProto::NewL(&target, log);
1586 batch->PrepareToPushL(p);
1588 p = CCommandIncProto::NewL(&target, log);
1589 batch->PrepareToPushL(p);
1591 history->PrepareToAddCommandL(batch);
1592 history->AddCommand(batch);
1593 p = CCommandNegProto::NewL(&target, log);
1594 history->PrepareToAddCommandL(p);
1595 history->AddCommand(p);
1597 log->SetCheckString(_L("neg<>batch{inc<>neg<>dec<>}dec<>batch{neg<>dec<>inc<>}neg<>"));
1598 ExecuteHistoryL(*history, *log);
1604 __UHEAP_MARKENDC(0);
1607 // 4 - CCommandManager test
1608 void TestCanUndo(const CCommandManager& aMan)
1615 TESTPRINT(_L("CCommandManager : unexpectedly could not undo"));
1618 void TestCanRedo(const CCommandManager& aMan)
1625 TESTPRINT(_L("CCommandManager : unexpectedly could not redo"));
1628 void TestCannotUndo(const CCommandManager& aMan)
1630 if (!aMan.CanUndo())
1635 TESTPRINT(_L("CCommandManager : unexpectedly could undo"));
1638 void TestCannotRedo(const CCommandManager& aMan)
1640 if (!aMan.CanRedo())
1645 TESTPRINT(_L("CCommandManager : unexpectedly could undo"));
1648 void SetUpTestL(CCommandManager& aMan, CSingleCommand& aCommand, TInt* aTarget, CLogger* aLogger)
1650 CCommandIncProto* inc = CCommandIncProto::NewL(aTarget, aLogger);
1651 CleanupStack::PushL(inc);
1652 CCommandNegProto* neg = CCommandNegProto::NewL(aTarget, aLogger);
1653 CleanupStack::PushL(neg);
1654 CCommandDecProto* dec = CCommandDecProto::NewL(aTarget, aLogger);
1655 CleanupStack::PushL(dec);
1657 aMan.ExecuteL(*inc);
1658 aMan.BeginBatchLC();
1659 aMan.ExecuteL(*neg);
1660 aMan.ExecuteL(aCommand);
1661 aMan.ExecuteL(*dec);
1662 CleanupStack::PopAndDestroy(); // close batch
1663 aMan.ExecuteL(*neg);
1666 CleanupStack::PopAndDestroy(dec);
1667 CleanupStack::PopAndDestroy(neg);
1668 CleanupStack::PopAndDestroy(inc);
1670 TInt CheckErrorCode(TInt aErr, TInt aExpected)
1672 if (aErr == aExpected)
1674 if (aErr == KErrNone)
1675 TESTPRINT(_L("CCommandManager : no leave where one was expected"));
1677 TESTPRINT(_L("CCommandManager : unexpected leave code"));
1680 void TestCCommandManagerL()
1684 CCommandManager* manager = CCommandManager::NewL();
1685 CCheckingLogger* log = new(ELeave) CCheckingLogger;
1687 CRefuserGatekeeper* refuser = new(ELeave) CRefuserGatekeeper;
1688 CPermitterGatekeeper* permitter = new(ELeave) CPermitterGatekeeper;
1689 CMemoryReclaimGatekeeper* reclaimer = new(ELeave) CMemoryReclaimGatekeeper;
1691 TestCannotUndo(*manager);
1692 TestCannotRedo(*manager);
1694 CCommandIncProto* inc = CCommandIncProto::NewL(&target, log);
1695 CCommandDecProto* dec = CCommandDecProto::NewL(&target, log);
1696 CCommandNegProto* neg = CCommandNegProto::NewL(&target, log);
1698 log->SetCheckString(_L("inc<>neg<>inc<>dec<>neg<>negate<1>"));
1699 SetUpTestL(*manager, *inc, &target, log);
1701 TestCanUndo(*manager);
1702 TestCanRedo(*manager);
1703 log->SetCheckString(_L("offset<0>negate<1>"));
1706 TestCanUndo(*manager);
1707 TestCanRedo(*manager);
1708 log->SetCheckString(_L("offset<-1>"));
1711 TestCannotUndo(*manager);
1712 TestCanRedo(*manager);
1713 log->SetCheckString(_L("offset<1>"));
1716 TestCanUndo(*manager);
1717 TestCanRedo(*manager);
1718 log->SetCheckString(_L("negate<1>offset<0>"));
1721 TestCanUndo(*manager);
1722 TestCanRedo(*manager);
1723 log->SetCheckString(_L("negate<1>"));
1726 TestCanUndo(*manager);
1727 TestCannotRedo(*manager);
1728 log->SetCheckString(_L("negate<1>"));
1731 TestCanUndo(*manager);
1732 TestCanRedo(*manager);
1733 log->SetCheckString(_L("inc<>"));
1734 manager->ExecuteL(*inc);
1736 TestCanUndo(*manager);
1737 TestCannotRedo(*manager);
1738 log->SetCheckString(_L("offset<-1>negate<1>"));
1741 TestCanUndo(*manager);
1742 TestCanRedo(*manager);
1743 log->SetCheckString(_L("negate<1>offset<1>"));
1746 TestCanUndo(*manager);
1747 TestCannotRedo(*manager);
1749 manager->ResetUndo();
1750 TestCannotUndo(*manager);
1751 TestCannotRedo(*manager);
1755 log->SetCheckString(_L("inc<>inc<>inc<>inc<>inc<>inc<>"));
1757 manager->ExecuteL(*inc);
1758 manager->ExecuteL(*inc);
1759 manager->BeginBatchLC();
1760 manager->ExecuteL(*inc);
1761 manager->ExecuteL(*inc);
1762 CleanupStack::PopAndDestroy(); // close batch
1763 manager->ExecuteL(*inc);
1764 manager->ExecuteL(*inc);
1767 log->SetCheckString(_L("offset<-4>offset<-2>"));
1772 log->SetCheckString(_L("offset<2>offset<4>"));
1775 TestCannotRedo(*manager);
1778 manager->ResetUndo();
1779 TestCannotUndo(*manager);
1780 TestCannotRedo(*manager);
1782 // test command with batch inverse
1783 log->SetCheckString(_L("inc<>decneg<>inc<>"));
1784 CCommandDecThenNegProto* dnp = CCommandDecThenNegProto::NewL(&target, log);
1785 manager->ExecuteL(*inc);
1786 manager->ExecuteL(*dnp);
1787 manager->ExecuteL(*inc);
1790 log->SetCheckString(_L("offset<-1>"));
1793 log->SetCheckString(_L("negate<1>offset<1>"));
1796 log->SetCheckString(_L("offset<-1>"));
1799 manager->ResetUndo();
1801 // Test case when undo is not supported
1802 // 1. execution is permitted
1803 log->SetCheckString(_L("inc<>neg<>noinvfail.noinv<>dec<>neg<>negate<1>"));
1804 CCommandCannotInvert* noInv = CCommandCannotInvert::NewL(log);
1805 SetUpTestL(*manager, *noInv, &target, log);
1807 TestCannotUndo(*manager);
1808 log->SetCheckString(_L("negate<1>"));
1811 TestCannotRedo(*manager);
1812 manager->ResetUndo();
1814 //2. execution is supressed
1815 manager->SetGatekeeper(refuser);
1816 log->SetCheckString(_L("inc<>neg<>noinvfail.dec<>neg<>negate<1>"));
1817 SetUpTestL(*manager, *noInv, &target, log);
1820 log->SetCheckString(_L("offset<1>negate<1>"));
1823 log->SetCheckString(_L("offset<-1>"));
1826 TestCannotUndo(*manager);
1827 manager->ResetUndo();
1828 manager->SetGatekeeper(0);
1830 // Test case when execution fails (with returned error code)
1831 CCommandCannotDo* noDo = CCommandCannotDo::NewL(log);
1832 log->SetCheckString(_L("inc<>neg<>nodo<>dec<>neg<>negate<1>"));
1833 SetUpTestL(*manager, *noDo, &target, log);
1835 log->SetCheckString(_L("offset<1>negate<1>"));
1838 log->SetCheckString(_L("offset<-1>"));
1841 TestCannotUndo(*manager);
1842 manager->ResetUndo();
1844 // Test case when inversion fails (not inversion is reported as impossible)
1845 // 1. when execution is permitted
1846 manager->SetGatekeeper(permitter);
1847 log->SetCheckString(_L("inc<>neg<>noinvfail.leaveinv<>dec<>neg<>negate<1>"));
1848 CCommandLeavesInvert* leaveInv = CCommandLeavesInvert::NewL(log);
1849 SetUpTestL(*manager, *leaveInv, &target, log);
1851 TestCannotUndo(*manager);
1852 log->SetCheckString(_L("negate<1>"));
1855 TestCannotRedo(*manager);
1856 manager->ResetUndo();
1858 // 2. when execution is supressed
1859 manager->SetGatekeeper(refuser);
1860 log->SetCheckString(_L("inc<>neg<>noinvfail.dec<>neg<>negate<1>"));
1861 leaveInv->iFail = ETrue;
1862 TRAPD(err, SetUpTestL(*manager, *leaveInv, &target, log));
1863 CheckErrorCode(err, KErrNone);
1865 log->SetCheckString(_L("offset<1>negate<1>"));
1868 log->SetCheckString(_L("offset<-1>"));
1871 TestCannotUndo(*manager);
1872 manager->ResetUndo();
1874 // 3. when execution is terminated by leaving
1875 manager->SetGatekeeper(0);
1876 log->SetCheckString(_L("inc<>neg<>noinvfail."));
1877 leaveInv->iFail = ETrue;
1878 TRAP(err, SetUpTestL(*manager, *leaveInv, &target, log));
1879 CheckErrorCode(err, KErrNotFound);
1882 log->SetCheckString(_L("negate<1>"));
1885 log->SetCheckString(_L("offset<-1>"));
1888 TestCannotUndo(*manager);
1889 manager->ResetUndo();
1891 // Test case when inversion runs out of memory
1892 // 1. when execution is permitted with no undo
1893 manager->SetGatekeeper(permitter);
1894 log->SetCheckString(_L("inc<>neg<>nomemfailadd.nomem<>dec<>neg<>negate<1>"));
1895 CCommandNoMemory* noMem = CCommandNoMemory::NewL(log);
1896 noMem->iFailExecute = EFalse;
1897 SetUpTestL(*manager, *noMem, &target, log);
1899 TestCannotUndo(*manager);
1900 log->SetCheckString(_L("negate<1>"));
1903 TestCannotRedo(*manager);
1904 manager->ResetUndo();
1906 // 2. when execution is supressed
1907 manager->SetGatekeeper(refuser);
1908 log->SetCheckString(_L("inc<>neg<>nomemfailadd.dec<>neg<>negate<1>"));
1909 TRAP(err, SetUpTestL(*manager, *noMem, &target, log));
1910 CheckErrorCode(err, KErrNone);
1912 log->SetCheckString(_L("offset<1>negate<1>"));
1915 log->SetCheckString(_L("offset<-1>"));
1918 TestCannotUndo(*manager);
1919 manager->ResetUndo();
1920 manager->SetGatekeeper(0);
1922 // 3. when memory is reclaimed
1923 reclaimer->iTarget = noMem;
1924 manager->SetGatekeeper(reclaimer);
1925 log->SetCheckString(_L("inc<>neg<>nomemfailadd.nomemfailinv.nomem<>dec<>neg<>negate<1>"));
1926 TRAP(err, SetUpTestL(*manager, *noMem, &target, log));
1927 CheckErrorCode(err, KErrNone);
1929 log->SetCheckString(_L("offset<1>negate<1>"));
1932 log->SetCheckString(_L("offset<-1>"));
1935 TestCannotUndo(*manager);
1936 manager->ResetUndo();
1937 manager->SetGatekeeper(0);
1939 // Test when execution runs out of memory
1940 // 1. with no reclaimation
1941 noMem->iFailAddToLast = EFalse;
1942 noMem->iFailInvert = EFalse;
1943 noMem->iFailExecute = ETrue;
1944 noMem->iLogExecuteFailed= ETrue;
1945 log->SetCheckString(_L("inc<>neg<>nomemfailexe."));
1946 TRAP(err, SetUpTestL(*manager, *noMem, &target, log));
1947 CheckErrorCode(err, KErrNoMemory);
1949 TestCannotRedo(*manager);
1950 log->SetCheckString(_L("negate<1>"));
1953 log->SetCheckString(_L("offset<-1>"));
1956 TestCannotUndo(*manager);
1957 manager->ResetUndo();
1958 // 2. with reclaimation
1959 noMem->iFailAddToLast = EFalse;
1960 noMem->iFailInvert = EFalse;
1961 noMem->iFailExecute = ETrue;
1962 noMem->iLogExecuteFailed= ETrue;
1963 reclaimer->iTarget = noMem;
1964 manager->SetGatekeeper(reclaimer);
1965 log->SetCheckString(_L("inc<>neg<>nomemfailexe.nomem<>dec<>neg<>negate<1>"));
1966 TRAP(err, SetUpTestL(*manager, *noMem, &target, log));
1967 CheckErrorCode(err, KErrNone);
1969 log->SetCheckString(_L("offset<1>negate<1>"));
1972 log->SetCheckString(_L("offset<-1>"));
1975 TestCannotUndo(*manager);
1976 manager->ResetUndo();
1977 manager->SetGatekeeper(0);
1989 __UHEAP_MARKENDC(0);
1994 // Tests involving CTestEditor
1998 void CheckEditorLog(CCheckingLogger& a)
2005 TESTPRINT(_L("EditorUndo : log failed"));
2009 void TestPlainText(CTestEditor& aTestEditor, MUnifiedEditor& aUndoEditor,
2010 CCommandManager& aCommandManager)
2012 CCheckingLogger* check = new(ELeave) CCheckingLogger;
2013 CStoringLogger* log = new(ELeave) CStoringLogger;
2016 // general inserting and deleting text
2018 aUndoEditor.InsertTextL(0, _L("Hello world!"), 0, 0, 0);
2020 aCommandManager.ResetUndo();
2022 aTestEditor.Print(*log);
2023 HBufC* helloWorldLog = log->GetStore();
2025 check->SetCheckString(*helloWorldLog);
2026 aTestEditor.Print(*check);
2027 CheckEditorLog(*check);
2028 aUndoEditor.InsertTextL(5, _L(" lovely"), 0, 0, 0);
2029 aTestEditor.Print(*log);
2030 HBufC* helloLovelyWorldLog = log->GetStore();
2031 aUndoEditor.DeleteTextL(10, 8);
2032 aTestEditor.Print(*log);
2033 HBufC* helloLoveLog = log->GetStore();
2034 aCommandManager.UndoL();
2035 check->SetCheckString(*helloLovelyWorldLog);
2036 aTestEditor.Print(*check);
2037 CheckEditorLog(*check);
2038 aCommandManager.UndoL();
2039 check->SetCheckString(*helloWorldLog);
2040 aTestEditor.Print(*check);
2041 CheckEditorLog(*check);
2042 aCommandManager.RedoL();
2043 check->SetCheckString(*helloLovelyWorldLog);
2044 aTestEditor.Print(*check);
2045 CheckEditorLog(*check);
2046 aCommandManager.RedoL();
2047 check->SetCheckString(*helloLoveLog);
2048 aTestEditor.Print(*check);
2049 CheckEditorLog(*check);
2050 aCommandManager.UndoL();
2051 check->SetCheckString(*helloLovelyWorldLog);
2052 aTestEditor.Print(*check);
2053 CheckEditorLog(*check);
2054 aCommandManager.UndoL();
2055 check->SetCheckString(*helloWorldLog);
2056 aTestEditor.Print(*check);
2057 CheckEditorLog(*check);
2059 aUndoEditor.InsertTextL(6, _L("w"), 0, 0, 0);
2060 aUndoEditor.InsertTextL(7, _L("h"), 0, 0, 0);
2061 aUndoEditor.InsertTextL(8, _L("at's"), 0, 0, 0);
2062 aUndoEditor.InsertTextL(12, _L(" "), 0, 0, 0);
2063 aUndoEditor.InsertTextL(13, _L("w"), 0, 0, 0);
2064 aUndoEditor.InsertTextL(14, _L("i"), 0, 0, 0);
2065 aUndoEditor.InsertTextL(6, _L("there "), 0, 0, 0);
2066 aUndoEditor.InsertTextL(21, _L("t"), 0, 0, 0);
2067 aUndoEditor.InsertTextL(22, _L("h"), 0, 0, 0);
2068 aUndoEditor.InsertTextL(23, _L(" "), 0, 0, 0);
2069 aTestEditor.Print(*log);
2070 HBufC* textLog0 = log->GetStore();
2071 aUndoEditor.InsertTextL(24, _L("the"), 0, 0, 0); // first of next
2072 aUndoEditor.InsertTextL(27, _L(" "), 0, 0, 0);
2073 aUndoEditor.InsertTextL(28, _L("d "), 0, 0, 0);
2074 aUndoEditor.InsertTextL(28, _L("ol"), 0, 0, 0);
2075 aTestEditor.Print(*log);
2076 HBufC* textLog1 = log->GetStore();
2078 aCommandManager.UndoL();
2079 check->SetCheckString(*textLog0);
2080 aTestEditor.Print(*check);
2081 CheckEditorLog(*check);
2083 aCommandManager.UndoL();
2084 check->SetCheckString(*helloWorldLog);
2085 aTestEditor.Print(*check);
2086 CheckEditorLog(*check);
2088 aCommandManager.RedoL();
2089 check->SetCheckString(*textLog0);
2090 aTestEditor.Print(*check);
2091 CheckEditorLog(*check);
2093 aCommandManager.RedoL();
2094 check->SetCheckString(*textLog1);
2095 aTestEditor.Print(*check);
2096 CheckEditorLog(*check);
2098 // check coalescence of insertions
2099 aTestEditor.AlterGranularityL(5);
2100 aUndoEditor.DeleteTextL(22, 1);
2101 aUndoEditor.DeleteTextL(21, 1);
2102 aUndoEditor.DeleteTextL(20, 1);
2103 aUndoEditor.DeleteTextL(19, 1);
2104 aUndoEditor.DeleteTextL(18, 1);
2105 aUndoEditor.DeleteTextL(18, 1);
2106 aUndoEditor.DeleteTextL(15, 3); // this will coalesce
2107 aUndoEditor.DeleteTextL(6, 9); // this won't, as it does not fit in one command
2108 aTestEditor.Print(*log);
2109 HBufC* delLog0 = log->GetStore();
2110 aUndoEditor.DeleteTextL(4, 1);
2111 aTestEditor.Print(*log);
2112 HBufC* delLog1 = log->GetStore();
2113 aUndoEditor.DeleteTextL(8, 2);
2114 aUndoEditor.DeleteTextL(8, 1); // should coalesce
2115 aUndoEditor.DeleteTextL(8, 1); // should coalesce
2116 aTestEditor.Print(*log);
2117 HBufC* delLog3 = log->GetStore();
2119 aCommandManager.UndoL();
2120 check->SetCheckString(*delLog1);
2121 aTestEditor.Print(*check);
2122 CheckEditorLog(*check);
2124 aCommandManager.UndoL();
2125 check->SetCheckString(*delLog0);
2126 aTestEditor.Print(*check);
2127 CheckEditorLog(*check);
2129 aCommandManager.UndoL();
2130 aCommandManager.UndoL();
2131 check->SetCheckString(*textLog1);
2132 aTestEditor.Print(*check);
2133 CheckEditorLog(*check);
2135 aCommandManager.RedoL();
2136 aCommandManager.RedoL();
2137 check->SetCheckString(*delLog0);
2138 aTestEditor.Print(*check);
2139 CheckEditorLog(*check);
2141 aCommandManager.RedoL();
2142 check->SetCheckString(*delLog1);
2143 aTestEditor.Print(*check);
2144 CheckEditorLog(*check);
2146 aCommandManager.RedoL();
2147 check->SetCheckString(*delLog3);
2148 aTestEditor.Print(*check);
2149 CheckEditorLog(*check);
2151 aCommandManager.UndoL();
2152 check->SetCheckString(*delLog1);
2153 aTestEditor.Print(*check);
2154 CheckEditorLog(*check);
2156 aCommandManager.UndoL();
2157 check->SetCheckString(*delLog0);
2158 aTestEditor.Print(*check);
2159 CheckEditorLog(*check);
2161 aCommandManager.UndoL();
2162 aCommandManager.UndoL();
2163 check->SetCheckString(*textLog1);
2164 aTestEditor.Print(*check);
2165 CheckEditorLog(*check);
2167 aCommandManager.UndoL();
2168 aCommandManager.UndoL();
2169 check->SetCheckString(*helloWorldLog);
2170 aTestEditor.Print(*check);
2171 CheckEditorLog(*check);
2173 aCommandManager.ResetUndo();
2178 // Check adding large amounts of text
2179 aTestEditor.AlterGranularityL(32);
2180 aUndoEditor.InsertTextL(0, _L("123456789"), 0, 0, 0);
2181 aUndoEditor.InsertTextL(0, _L("223456789"), 0, 0, 0);
2182 aTestEditor.Print(*log);
2183 HBufC* largeLog0 = log->GetStore();
2184 aUndoEditor.InsertTextL(0, _L("3234567890"), 0, 0, 0);
2185 aUndoEditor.InsertTextL(0, _L("4234567890"), 0, 0, 0);
2186 aTestEditor.Print(*log);
2187 HBufC* largeLog1 = log->GetStore();
2188 aUndoEditor.InsertTextL(0, _L("523456789"), 0, 0, 0);
2189 aTestEditor.Print(*log);
2190 HBufC* largeLog2 = log->GetStore();
2192 aCommandManager.UndoL();
2193 check->SetCheckString(*largeLog1);
2194 aTestEditor.Print(*check);
2195 CheckEditorLog(*check);
2197 aCommandManager.UndoL();
2198 check->SetCheckString(*largeLog0);
2199 aTestEditor.Print(*check);
2200 CheckEditorLog(*check);
2202 aCommandManager.UndoL();
2203 check->SetCheckString(*helloWorldLog);
2204 aTestEditor.Print(*check);
2205 CheckEditorLog(*check);
2207 aCommandManager.RedoL();
2208 check->SetCheckString(*largeLog0);
2209 aTestEditor.Print(*check);
2210 CheckEditorLog(*check);
2212 aCommandManager.RedoL();
2213 check->SetCheckString(*largeLog1);
2214 aTestEditor.Print(*check);
2215 CheckEditorLog(*check);
2217 aCommandManager.RedoL();
2218 check->SetCheckString(*largeLog2);
2219 aTestEditor.Print(*check);
2220 CheckEditorLog(*check);
2222 aCommandManager.UndoL();
2223 check->SetCheckString(*largeLog1);
2224 aTestEditor.Print(*check);
2225 CheckEditorLog(*check);
2227 aCommandManager.UndoL();
2228 check->SetCheckString(*largeLog0);
2229 aTestEditor.Print(*check);
2230 CheckEditorLog(*check);
2232 aCommandManager.UndoL();
2233 check->SetCheckString(*helloWorldLog);
2234 aTestEditor.Print(*check);
2235 CheckEditorLog(*check);
2237 aCommandManager.RedoL();
2238 aCommandManager.RedoL();
2239 aCommandManager.RedoL();
2241 // test copy and paste
2242 MUnifiedEditor::MClipboardSupport* ci = aUndoEditor.ClipboardSupport();
2245 CBufStore* clipboardBuffer = CBufStore::NewL(100);
2246 CStreamDictionary* clipboardDictionary = CStreamDictionary::NewL();
2248 ci->CopyToStoreL(*clipboardBuffer, *clipboardDictionary, 5, 40);
2249 aTestEditor.Print(*log);
2250 HBufC* clipLog0 = log->GetStore();
2251 ci->PasteFromStoreL(*clipboardBuffer, *clipboardDictionary, 2);
2252 aTestEditor.Print(*log);
2253 HBufC* clipLog1 = log->GetStore();
2254 ci->PasteFromStoreL(*clipboardBuffer, *clipboardDictionary, 55);
2255 aTestEditor.Print(*log);
2256 HBufC* clipLog2 = log->GetStore();
2257 ci->PasteFromStoreL(*clipboardBuffer, *clipboardDictionary, 23);
2258 aTestEditor.Print(*log);
2259 HBufC* clipLog3 = log->GetStore();
2261 aCommandManager.UndoL();
2262 check->SetCheckString(*clipLog2);
2263 aTestEditor.Print(*check);
2264 CheckEditorLog(*check);
2266 aCommandManager.UndoL();
2267 check->SetCheckString(*clipLog1);
2268 aTestEditor.Print(*check);
2269 CheckEditorLog(*check);
2271 aCommandManager.UndoL();
2272 check->SetCheckString(*clipLog0);
2273 aTestEditor.Print(*check);
2274 CheckEditorLog(*check);
2276 aCommandManager.RedoL();
2277 check->SetCheckString(*clipLog1);
2278 aTestEditor.Print(*check);
2279 CheckEditorLog(*check);
2281 aCommandManager.RedoL();
2282 check->SetCheckString(*clipLog2);
2283 aTestEditor.Print(*check);
2284 CheckEditorLog(*check);
2286 aCommandManager.RedoL();
2287 check->SetCheckString(*clipLog3);
2288 aTestEditor.Print(*check);
2289 CheckEditorLog(*check);
2291 aCommandManager.UndoL();
2292 check->SetCheckString(*clipLog2);
2293 aTestEditor.Print(*check);
2294 CheckEditorLog(*check);
2296 aCommandManager.UndoL();
2297 check->SetCheckString(*clipLog1);
2298 aTestEditor.Print(*check);
2299 CheckEditorLog(*check);
2301 aCommandManager.UndoL();
2302 check->SetCheckString(*clipLog0);
2303 aTestEditor.Print(*check);
2304 CheckEditorLog(*check);
2310 delete clipboardDictionary;
2311 delete clipboardBuffer;
2320 delete helloWorldLog;
2321 delete helloLovelyWorldLog;
2322 delete helloLoveLog;
2327 // This class merely splits the test function into little functions
2328 // to help out the MW compiler
2329 class TestEditorUndo
2331 CCheckingLogger* check;
2332 CStoringLogger* log;
2333 CTestEditor* testEd;
2334 CCommandManager* manager;
2335 CEditorPlainTextWithUndo* plainEd;
2336 CEditorWithUndo* ed;
2337 TTmCharFormatMask charBMask;
2338 TTmCharFormatMask charIMask;
2339 TTmCharFormatMask charBIMask;
2340 TOpenFontFaceAttribBase attrib;
2341 TTmCharFormat charB;
2342 TTmCharFormat charIB;
2343 TTmCharFormat charI;
2344 TTmParFormatMask parTMask;
2345 TTmParFormatMask parNMask;
2346 TTmParFormatMask parTNMask;
2351 TTmCharFormatLayer charLayer;
2352 RTmParFormatLayer parLayer;
2390 HBufC* bookMarkLog0;
2391 HBufC* bookMarkLog1;
2392 HBufC* bookMarkLog2;
2393 HBufC* bookMarkLog3;
2394 HBufC* bookMarkLog4;
2395 HBufC* bookMarkLog5;
2407 void TestEditorUndo::Test1L()
2409 check = new(ELeave) CCheckingLogger;
2410 log = new(ELeave) CStoringLogger;
2411 testEd = CTestEditor::NewL();
2412 manager = CCommandManager::NewL();
2413 plainEd = CEditorPlainTextWithUndo::NewL(*testEd, manager);
2415 TestPlainText(*testEd, *plainEd, *manager);
2416 ed = CEditorWithUndo::NewL(*testEd, manager);
2417 testEd->DeleteTextL(0, testEd->DocumentLength());
2418 manager->ResetUndo();
2423 TestPlainText(*testEd, *ed, *manager);
2427 void TestEditorUndo::Test2L()
2429 // char and par formats
2430 charBMask.iFlags = TTmCharFormatMask::EBold;
2431 charIMask.iFlags = TTmCharFormatMask::EItalic;
2432 charBIMask.iFlags = TTmCharFormatMask::EItalic | TTmCharFormatMask::EBold;
2433 attrib.SetBold(ETrue);
2434 charB.iFontSpec.SetAttrib(attrib);
2435 attrib.SetItalic(ETrue);
2436 charIB.iFontSpec.SetAttrib(attrib);
2437 attrib.SetBold(EFalse);
2438 charI.iFontSpec.SetAttrib(attrib);
2440 parTMask.iFlags = TTmParFormatMask::EKeepTogether;
2441 parNMask.iFlags = TTmParFormatMask::EKeepWithNext;
2442 parTNMask.iFlags = TTmParFormatMask::EKeepTogether | TTmParFormatMask::EKeepWithNext;
2443 parT.iFlags = RTmParFormat::EKeepTogether;
2444 parN.iFlags = RTmParFormat::EKeepWithNext;
2445 parTN.iFlags = RTmParFormat::EKeepWithNext | RTmParFormat::EKeepTogether;
2447 charLayer.iFormat = charB;
2448 charLayer.iMask = charBMask;
2449 ed->SetCharFormatL(0, 5, charLayer);
2450 testEd->Print(*log);
2451 charLog0 = log->GetStore();
2453 charLayer.iFormat = charI;
2454 charLayer.iMask = charIMask;
2455 ed->SetCharFormatL(3, 9, charLayer);
2456 testEd->Print(*log);
2457 charLog1 = log->GetStore();
2459 charLayer.iFormat = charB;
2460 charLayer.iMask = charBIMask;
2461 ed->SetCharFormatL(2, 5, charLayer);
2462 testEd->Print(*log);
2463 charLog2 = log->GetStore();
2465 ed->DeleteCharFormatL(1, 10);
2466 testEd->Print(*log);
2467 charLog3 = log->GetStore();
2470 check->SetCheckString(*charLog2);
2471 testEd->Print(*check);
2472 CheckEditorLog(*check);
2475 check->SetCheckString(*charLog1);
2476 testEd->Print(*check);
2477 CheckEditorLog(*check);
2480 check->SetCheckString(*charLog0);
2481 testEd->Print(*check);
2482 CheckEditorLog(*check);
2485 check->SetCheckString(*charLog1);
2486 testEd->Print(*check);
2487 CheckEditorLog(*check);
2490 check->SetCheckString(*charLog2);
2491 testEd->Print(*check);
2492 CheckEditorLog(*check);
2495 check->SetCheckString(*charLog3);
2496 testEd->Print(*check);
2497 CheckEditorLog(*check);
2499 parLayer.iMask = parTMask;
2500 parLayer.iFormat.CopyL(parT);
2501 ed->SetParFormatL(5, 7, parLayer);
2502 testEd->Print(*log);
2503 parLog0 = log->GetStore();
2505 parLayer.iMask = parTNMask;
2506 parLayer.iFormat.CopyL(parN);
2507 ed->SetParFormatL(0, 7, parLayer);
2508 testEd->Print(*log);
2509 parLog1 = log->GetStore();
2511 ed->DeleteParFormatL(4, 4);
2512 testEd->Print(*log);
2513 parLog2 = log->GetStore();
2515 parLayer.iMask = parNMask;
2516 parLayer.iFormat.CopyL(parN);
2517 ed->SetParFormatL(3, 6, parLayer);
2518 testEd->Print(*log);
2519 parLog3 = log->GetStore();
2522 check->SetCheckString(*parLog2);
2523 testEd->Print(*check);
2524 CheckEditorLog(*check);
2527 check->SetCheckString(*parLog1);
2528 testEd->Print(*check);
2529 CheckEditorLog(*check);
2532 check->SetCheckString(*parLog0);
2533 testEd->Print(*check);
2534 CheckEditorLog(*check);
2537 check->SetCheckString(*charLog3);
2538 testEd->Print(*check);
2539 CheckEditorLog(*check);
2542 check->SetCheckString(*parLog0);
2543 testEd->Print(*check);
2544 CheckEditorLog(*check);
2547 check->SetCheckString(*parLog1);
2548 testEd->Print(*check);
2549 CheckEditorLog(*check);
2552 check->SetCheckString(*parLog2);
2553 testEd->Print(*check);
2554 CheckEditorLog(*check);
2557 check->SetCheckString(*parLog3);
2558 testEd->Print(*check);
2559 CheckEditorLog(*check);
2562 void TestEditorUndo::Test3L()
2564 // check coalescence of deletions
2565 charLayer.iMask = charIMask;
2566 charLayer.iFormat = charI;
2567 parLayer.iMask = parNMask;
2568 parLayer.iFormat.CopyL(parN);
2569 ed->InsertTextL(6, _L("w"), 0, &charLayer, &parLayer);
2570 ed->InsertTextL(7, _L("h"), 0, &charLayer, &parLayer);
2571 ed->InsertTextL(8, _L("at's"), 0, &charLayer, &parLayer);
2572 ed->InsertTextL(12, _L(" "), 0, &charLayer, &parLayer);
2573 ed->InsertTextL(13, _L("w"), 0, &charLayer, &parLayer);
2574 ed->InsertTextL(14, _L("i"), 0, &charLayer, &parLayer);
2575 ed->InsertTextL(6, _L("there "), 0, &charLayer, &parLayer);
2576 ed->InsertTextL(21, _L("t"), 0, &charLayer, &parLayer);
2577 ed->InsertTextL(22, _L("h"), 0, &charLayer, &parLayer);
2578 ed->InsertTextL(23, _L(" "), 0, &charLayer, &parLayer);
2579 testEd->Print(*log);
2580 textLog0 = log->GetStore();
2581 ed->InsertTextL(24, _L("the"), 0, &charLayer, &parLayer); // first of next?
2582 ed->InsertTextL(27, _L(" "), 0, &charLayer, &parLayer);
2583 testEd->Print(*log);
2584 textLog1 = log->GetStore();
2585 charLayer.iMask = charBIMask;
2586 ed->InsertTextL(28, _L("ol"), 0, &charLayer, &parLayer);
2587 testEd->Print(*log);
2588 textLog2 = log->GetStore();
2589 parLayer.iMask = parTNMask;
2590 ed->InsertTextL(30, _L("d "), 0, &charLayer, &parLayer);
2591 testEd->Print(*log);
2592 textLog3 = log->GetStore();
2595 check->SetCheckString(*textLog0);
2596 testEd->Print(*check);
2597 CheckEditorLog(*check);
2600 check->SetCheckString(*parLog3);
2601 testEd->Print(*check);
2602 CheckEditorLog(*check);
2605 check->SetCheckString(*textLog0);
2606 testEd->Print(*check);
2607 CheckEditorLog(*check);
2610 check->SetCheckString(*textLog3);
2611 testEd->Print(*check);
2612 CheckEditorLog(*check);
2616 void TestEditorUndo::Test4L()
2618 // check coalescence of insertions
2619 testEd->AlterGranularityL(5);
2620 ed->DeleteTextL(22, 1);
2621 ed->DeleteTextL(21, 1);
2622 ed->DeleteTextL(20, 1);
2623 ed->DeleteTextL(19, 1);
2624 ed->DeleteTextL(18, 1);
2625 ed->DeleteTextL(18, 1);
2626 ed->DeleteTextL(15, 3); // this will coalesce
2627 ed->DeleteTextL(6, 9); // this won't, as it does not fit in one command
2628 testEd->Print(*log);
2629 delLog0 = log->GetStore();
2630 ed->DeleteTextL(4, 1);
2631 testEd->Print(*log);
2632 delLog1 = log->GetStore();
2633 ed->DeleteTextL(8, 2);
2634 ed->DeleteTextL(8, 1); // should coalesce
2635 testEd->Print(*log);
2636 delLog2 = log->GetStore();
2637 ed->DeleteTextL(8, 1); // should fail to coalesce
2638 testEd->Print(*log);
2639 delLog3 = log->GetStore();
2642 check->SetCheckString(*delLog2);
2643 testEd->Print(*check);
2644 CheckEditorLog(*check);
2647 check->SetCheckString(*delLog1);
2648 testEd->Print(*check);
2649 CheckEditorLog(*check);
2652 check->SetCheckString(*delLog0);
2653 testEd->Print(*check);
2654 CheckEditorLog(*check);
2658 check->SetCheckString(*textLog3);
2659 testEd->Print(*check);
2660 CheckEditorLog(*check);
2664 check->SetCheckString(*delLog0);
2665 testEd->Print(*check);
2666 CheckEditorLog(*check);
2669 check->SetCheckString(*delLog1);
2670 testEd->Print(*check);
2671 CheckEditorLog(*check);
2674 check->SetCheckString(*delLog2);
2675 testEd->Print(*check);
2676 CheckEditorLog(*check);
2679 check->SetCheckString(*delLog3);
2680 testEd->Print(*check);
2681 CheckEditorLog(*check);
2684 check->SetCheckString(*delLog2);
2685 testEd->Print(*check);
2686 CheckEditorLog(*check);
2689 check->SetCheckString(*delLog1);
2690 testEd->Print(*check);
2691 CheckEditorLog(*check);
2694 check->SetCheckString(*delLog0);
2695 testEd->Print(*check);
2696 CheckEditorLog(*check);
2700 check->SetCheckString(*textLog3);
2701 testEd->Print(*check);
2702 CheckEditorLog(*check);
2710 void TestEditorUndo::Test5L()
2712 // Check adding large amounts of text
2713 testEd->AlterGranularityL(32);
2714 ed->InsertTextL(0, _L("123456789"), 0, 0, 0);
2715 ed->InsertTextL(0, _L("223456789"), 0, 0, 0);
2716 testEd->Print(*log);
2718 textLog0 = log->GetStore();
2719 ed->InsertTextL(0, _L("3234567890"), 0, 0, 0);
2720 ed->InsertTextL(0, _L("4234567890"), 0, 0, 0);
2721 testEd->Print(*log);
2723 textLog1 = log->GetStore();
2724 ed->InsertTextL(0, _L("523456789"), 0, 0, 0);
2725 testEd->Print(*log);
2727 textLog2 = log->GetStore();
2730 check->SetCheckString(*textLog1);
2731 testEd->Print(*check);
2732 CheckEditorLog(*check);
2735 check->SetCheckString(*textLog0);
2736 testEd->Print(*check);
2737 CheckEditorLog(*check);
2740 check->SetCheckString(*textLog3);
2741 testEd->Print(*check);
2742 CheckEditorLog(*check);
2745 check->SetCheckString(*textLog0);
2746 testEd->Print(*check);
2747 CheckEditorLog(*check);
2750 check->SetCheckString(*textLog1);
2751 testEd->Print(*check);
2752 CheckEditorLog(*check);
2755 check->SetCheckString(*textLog2);
2756 testEd->Print(*check);
2757 CheckEditorLog(*check);
2760 check->SetCheckString(*textLog1);
2761 testEd->Print(*check);
2762 CheckEditorLog(*check);
2765 check->SetCheckString(*textLog0);
2766 testEd->Print(*check);
2767 CheckEditorLog(*check);
2770 check->SetCheckString(*textLog3);
2771 testEd->Print(*check);
2772 CheckEditorLog(*check);
2775 void TestEditorUndo::Test6L()
2777 // test style manipulation
2778 style1.iName = _L("author");
2779 style2.iName = _L("title");
2780 style2.iNextStyleName = _L("author");
2781 style1.iCharFormat.iFormat = charI;
2782 style1.iCharFormat.iMask = charIMask;
2783 style1.iParFormat.iFormat.CopyL(parT);
2784 style1.iParFormat.iMask = parTNMask;
2785 style2.iCharFormat.iFormat = charB;
2786 style2.iCharFormat.iMask = charBIMask;
2787 style2.iParFormat.iFormat.CopyL(parN);
2788 style2.iParFormat.iMask = parNMask;
2790 ed->StyleSupport()->CreateStyleL(style1);
2791 testEd->Print(*log);
2792 styleLog1 = log->GetStore();
2793 TInt retval = ed->StyleSupport()->SetStyleL(1, 3, _L("author"));
2794 testEd->Print(*log);
2795 styleLog2 = log->GetStore();
2796 if (retval != KErrNone)
2798 TESTPRINT(_L("EditorUndo : apply style failed"));
2801 TPtrC testStyleName;
2802 TInt testStyleRunLength;
2803 ed->StyleSupport()->GetStyle(1, testStyleName, testStyleRunLength);
2804 if (testStyleRunLength != 3 || testStyleName != style1.iName)
2806 TESTPRINT(_L("EditorUndo : apply style failed"));
2809 ed->InsertTextL(5, _L(","), &style1.iName, 0, 0);
2810 testEd->Print(*log);
2811 styleLog3 = log->GetStore();
2812 ed->StyleSupport()->CreateStyleL(style2);
2813 testEd->Print(*log);
2814 styleLog4 = log->GetStore();
2815 ed->StyleSupport()->SetStyleL(2, 7, _L("title"));
2816 testEd->Print(*log);
2817 styleLog5 = log->GetStore();
2818 ed->StyleSupport()->SetStyleL(10, 4, _L("title"));
2819 testEd->Print(*log);
2820 styleLog6 = log->GetStore();
2821 ed->StyleSupport()->SetStyleL(8, 4, _L("author"));
2822 testEd->Print(*log);
2823 styleLog7 = log->GetStore();
2824 style1.iCharFormat.iFormat = charB;
2825 style1.iCharFormat.iMask = charBMask;
2826 ed->StyleSupport()->ChangeStyleL(style1);
2827 testEd->Print(*log);
2828 styleLog8 = log->GetStore();
2829 ed->StyleSupport()->RenameStyleL(_L("author"), _L("version"));
2830 style1.iName = _L("version");
2831 testEd->Print(*log);
2832 styleLog9 = log->GetStore();
2833 retval = ed->StyleSupport()->SetStyleL(10, 1, _L("version"));
2834 testEd->Print(*log);
2835 styleLog10 = log->GetStore();
2836 if (retval != KErrNone)
2838 TESTPRINT(_L("EditorUndo : rename style failed"));
2841 ed->StyleSupport()->GetStyle(1, testStyleName, testStyleRunLength);
2842 if (testStyleRunLength != 1 || testStyleName != style1.iName)
2844 TESTPRINT(_L("EditorUndo : rename or apply style failed"));
2847 ed->StyleSupport()->RenameStyleL(_L("title"), _L("zip"));
2848 style2.iName = _L("zip");
2849 testEd->Print(*log);
2850 styleLog11 = log->GetStore();
2851 ed->StyleSupport()->SetStyleL(0, 6, _L("zip"));
2852 testEd->Print(*log);
2853 styleLog12 = log->GetStore();
2854 ed->StyleSupport()->DeleteStyleL(_L("zip"));
2855 testEd->Print(*log);
2856 styleLog13 = log->GetStore();
2857 ed->InsertTextL(0, _L("Well "), &style1.iName, 0, 0);
2860 check->SetCheckString(*styleLog13);
2861 testEd->Print(*check);
2862 CheckEditorLog(*check);
2865 check->SetCheckString(*styleLog12);
2866 testEd->Print(*check);
2867 CheckEditorLog(*check);
2870 check->SetCheckString(*styleLog11);
2871 testEd->Print(*check);
2872 CheckEditorLog(*check);
2875 check->SetCheckString(*styleLog10);
2876 testEd->Print(*check);
2877 CheckEditorLog(*check);
2880 check->SetCheckString(*styleLog9);
2881 testEd->Print(*check);
2882 CheckEditorLog(*check);
2885 check->SetCheckString(*styleLog8);
2886 testEd->Print(*check);
2887 CheckEditorLog(*check);
2890 check->SetCheckString(*styleLog7);
2891 testEd->Print(*check);
2892 CheckEditorLog(*check);
2895 check->SetCheckString(*styleLog6);
2896 testEd->Print(*check);
2897 CheckEditorLog(*check);
2900 check->SetCheckString(*styleLog5);
2901 testEd->Print(*check);
2902 CheckEditorLog(*check);
2905 check->SetCheckString(*styleLog4);
2906 testEd->Print(*check);
2907 CheckEditorLog(*check);
2910 check->SetCheckString(*styleLog3);
2911 testEd->Print(*check);
2912 CheckEditorLog(*check);
2915 check->SetCheckString(*styleLog2);
2916 testEd->Print(*check);
2917 CheckEditorLog(*check);
2920 check->SetCheckString(*styleLog1);
2921 testEd->Print(*check);
2922 CheckEditorLog(*check);
2925 check->SetCheckString(*textLog3);
2926 testEd->Print(*check);
2927 CheckEditorLog(*check);
2930 check->SetCheckString(*styleLog1);
2931 testEd->Print(*check);
2932 CheckEditorLog(*check);
2935 check->SetCheckString(*styleLog2);
2936 testEd->Print(*check);
2937 CheckEditorLog(*check);
2940 check->SetCheckString(*styleLog3);
2941 testEd->Print(*check);
2942 CheckEditorLog(*check);
2945 check->SetCheckString(*styleLog4);
2946 testEd->Print(*check);
2947 CheckEditorLog(*check);
2950 check->SetCheckString(*styleLog5);
2951 testEd->Print(*check);
2952 CheckEditorLog(*check);
2955 check->SetCheckString(*styleLog6);
2956 testEd->Print(*check);
2957 CheckEditorLog(*check);
2960 check->SetCheckString(*styleLog7);
2961 testEd->Print(*check);
2962 CheckEditorLog(*check);
2965 check->SetCheckString(*styleLog8);
2966 testEd->Print(*check);
2967 CheckEditorLog(*check);
2970 check->SetCheckString(*styleLog9);
2971 testEd->Print(*check);
2972 CheckEditorLog(*check);
2975 check->SetCheckString(*styleLog10);
2976 testEd->Print(*check);
2977 CheckEditorLog(*check);
2980 check->SetCheckString(*styleLog11);
2981 testEd->Print(*check);
2982 CheckEditorLog(*check);
2985 check->SetCheckString(*styleLog12);
2986 testEd->Print(*check);
2987 CheckEditorLog(*check);
2990 check->SetCheckString(*styleLog13);
2991 testEd->Print(*check);
2992 CheckEditorLog(*check);
2994 // probably need some more style tests that test the full range of
2995 // attributes that a style may have.
3026 void TestEditorUndo::Test7L()
3028 // test picture manipulation
3030 pic.iPictureType = KUidXzePictureType;
3031 testEd->Print(*log);
3032 picLog0 = log->GetStore();
3033 pic.iPicture = new (ELeave) CUndoTestPicture('A');
3034 ed->PictureSupport()->InsertPictureL(5, pic);
3035 testEd->Print(*log);
3036 picLog1 = log->GetStore();
3037 pic.iPicture = new (ELeave) CUndoTestPicture('B');
3038 ed->PictureSupport()->InsertPictureL(8, pic);
3039 testEd->Print(*log);
3040 picLog2 = log->GetStore();
3041 pic.iPicture = new (ELeave) CUndoTestPicture('C');
3042 ed->PictureSupport()->InsertPictureL(9, pic);
3043 testEd->Print(*log);
3044 picLog3 = log->GetStore();
3045 pic.iPicture = new (ELeave) CUndoTestPicture('D');
3046 ed->PictureSupport()->InsertPictureL(12, pic);
3047 ed->StyleSupport()->SetStyleL(6, 2, style1.iName);
3048 ed->SetCharFormatL(8, 3, charLayer);
3049 ed->SetParFormatL(7, 7, parLayer);
3050 testEd->Print(*log);
3051 picLog4 = log->GetStore();
3052 ed->DeleteTextL(5, 8);
3053 testEd->Print(*log);
3054 picLog5 = log->GetStore();
3057 check->SetCheckString(*picLog4);
3058 testEd->Print(*check);
3059 CheckEditorLog(*check);
3065 check->SetCheckString(*picLog3);
3066 testEd->Print(*check);
3067 CheckEditorLog(*check);
3070 check->SetCheckString(*picLog2);
3071 testEd->Print(*check);
3072 CheckEditorLog(*check);
3075 check->SetCheckString(*picLog1);
3076 testEd->Print(*check);
3077 CheckEditorLog(*check);
3080 check->SetCheckString(*picLog0);
3081 testEd->Print(*check);
3082 CheckEditorLog(*check);
3085 check->SetCheckString(*picLog1);
3086 testEd->Print(*check);
3087 CheckEditorLog(*check);
3090 check->SetCheckString(*picLog2);
3091 testEd->Print(*check);
3092 CheckEditorLog(*check);
3095 check->SetCheckString(*picLog3);
3096 testEd->Print(*check);
3097 CheckEditorLog(*check);
3103 check->SetCheckString(*picLog4);
3104 testEd->Print(*check);
3105 CheckEditorLog(*check);
3108 check->SetCheckString(*picLog5);
3109 testEd->Print(*check);
3110 CheckEditorLog(*check);
3127 void TestEditorUndo::Test8L()
3130 for (TInt i = 0; i != 7; ++i)
3135 manager->SetBookmark();
3136 testEd->Print(*log);
3137 bookMarkLog0 = log->GetStore();
3138 ed->InsertTextL(0, _L("Hallo"), 0, 0, 0); // hallo
3140 manager->SetBookmark();
3141 testEd->Print(*log);
3142 bookMarkLog1 = log->GetStore();
3143 ed->DeleteTextL(2, 1); // halo
3145 manager->SetBookmark();
3146 testEd->Print(*log);
3147 bookMarkLog2 = log->GetStore();
3148 manager->BeginBatchLC();
3149 ed->DeleteTextL(3, 1); // hal
3150 ed->InsertTextL(3, _L("t, who goes there?"), 0, 0, 0); // halt, who goes there?
3152 manager->SetBookmark(); // should not get set
3153 ed->DeleteTextL(9, 5); // halt, who there?
3154 CleanupStack::PopAndDestroy();
3156 manager->SetBookmark();
3157 testEd->Print(*log);
3158 bookMarkLog3 = log->GetStore();
3159 ed->InsertTextL(0, _L("Oi"), 0, 0, 0);
3161 manager->SetBookmark();
3162 testEd->Print(*log);
3163 bookMarkLog4 = log->GetStore();
3164 ed->InsertTextL(2, _L("! "), 0, 0, 0);
3165 testEd->Print(*log);
3166 bookMarkLog5 = log->GetStore();
3168 manager->SetBookmark();
3171 // coalescence should have happenned unless there is a bookmark
3175 TESTPOINT(manager->IsAtBookmark());
3176 check->SetCheckString(*bookMarkLog4);
3177 testEd->Print(*check);
3178 CheckEditorLog(*check);
3182 TESTPOINT(manager->IsAtBookmark());
3184 TESTPOINT(!manager->IsAtBookmark());
3185 check->SetCheckString(*bookMarkLog3);
3186 testEd->Print(*check);
3187 CheckEditorLog(*check);
3190 TESTPOINT(manager->IsAtBookmark());
3192 TESTPOINT(!manager->IsAtBookmark());
3193 check->SetCheckString(*bookMarkLog2);
3194 testEd->Print(*check);
3195 CheckEditorLog(*check);
3198 TESTPOINT(manager->IsAtBookmark());
3200 TESTPOINT(!manager->IsAtBookmark());
3201 check->SetCheckString(*bookMarkLog1);
3202 testEd->Print(*check);
3203 CheckEditorLog(*check);
3206 TESTPOINT(manager->IsAtBookmark());
3208 TESTPOINT(!manager->IsAtBookmark());
3209 check->SetCheckString(*bookMarkLog0);
3210 testEd->Print(*check);
3211 CheckEditorLog(*check);
3212 TESTPOINT(!ed->CanUndo());
3215 TESTPOINT(manager->IsAtBookmark());
3217 TESTPOINT(!manager->IsAtBookmark());
3218 check->SetCheckString(*bookMarkLog1);
3219 testEd->Print(*check);
3220 CheckEditorLog(*check);
3223 TESTPOINT(manager->IsAtBookmark());
3225 TESTPOINT(!manager->IsAtBookmark());
3226 check->SetCheckString(*bookMarkLog2);
3227 testEd->Print(*check);
3228 CheckEditorLog(*check);
3231 TESTPOINT(manager->IsAtBookmark());
3233 TESTPOINT(!manager->IsAtBookmark());
3234 check->SetCheckString(*bookMarkLog3);
3235 testEd->Print(*check);
3236 CheckEditorLog(*check);
3240 TESTPOINT(manager->IsAtBookmark());
3241 check->SetCheckString(*bookMarkLog4);
3242 testEd->Print(*check);
3243 CheckEditorLog(*check);
3246 TESTPOINT(!ed->CanRedo());
3248 TESTPOINT(manager->IsAtBookmark());
3250 TESTPOINT(!manager->IsAtBookmark());
3252 delete bookMarkLog0;
3253 delete bookMarkLog1;
3254 delete bookMarkLog2;
3255 delete bookMarkLog3;
3256 delete bookMarkLog4;
3257 delete bookMarkLog5;
3266 void TestEditorUndoL()
3280 __UHEAP_MARKENDC(0);
3282 // integration of command manager with multiple editors
3283 void TestMultipleEditorsL()
3287 CCheckingLogger* check = new(ELeave) CCheckingLogger;
3288 CStoringLogger* log = new(ELeave) CStoringLogger;
3290 CTestEditor* testEd0 = CTestEditor::NewL();
3291 CTestEditor* testEd1 = CTestEditor::NewL();
3292 CTestEditor* testEd2 = CTestEditor::NewL();
3293 CTestEditor* testEd3 = CTestEditor::NewL();
3294 CCommandManager* manager = CCommandManager::NewL();
3296 CEditorPlainTextWithUndo* ed0 =
3297 CEditorPlainTextWithUndo::NewL(*testEd0, manager);
3298 CEditorWithUndo* ed1 = CEditorWithUndo::NewL(*testEd1, manager);
3299 CEditorPlainTextWithUndo* ed2 =
3300 CEditorPlainTextWithUndo::NewL(*testEd2, manager);
3301 CEditorWithUndo* ed3 = CEditorWithUndo::NewL(*testEd3, manager);
3304 // Testing the API's of CEditorPlainTextWithUndo
3305 TTmCharFormatMask charBIMask;
3306 charBIMask.iFlags = TTmCharFormatMask::EItalic | TTmCharFormatMask::EBold;
3307 TOpenFontFaceAttribBase attrib;
3308 TTmCharFormat charB;
3309 attrib.SetBold(ETrue);
3310 charB.iFontSpec.SetAttrib(attrib);
3311 TTmCharFormatLayer charLayer;
3312 charLayer.iFormat = charB;
3313 charLayer.iMask = charBIMask;
3314 TTmParFormatMask parTMask;
3315 parTMask.iFlags = TTmParFormatMask::EKeepTogether;
3317 parT.iFlags = RTmParFormat::EKeepTogether;
3318 RTmParFormatLayer parLayer;
3319 parLayer.iMask = parTMask;
3321 //Setting the base, character and paragraph format and then inserting the text
3322 ed0->SetBaseFormatL(charB,parT);
3323 ed0->SetCharFormatL(0, 1, charLayer);
3324 ed0->SetParFormatL(0, 1, parLayer);
3326 // The main thing to check is that no commands coalesce that have
3327 // different targets which would if their targets matched. The
3328 // commands that can coalesce are Delete Text, Delete Plain Text,
3329 // Insert Text, Insert Plain Text, Delete Character Format, Delete
3330 // Paragraph Format.
3331 ed0->InsertTextL(0, _L("ab"), 0, 0, 0);
3332 testEd0->Print(*log);
3333 HBufC* log00 = log->GetStore();
3334 ed2->InsertTextL(0, _L("cd"), 0, 0, 0);
3335 testEd2->Print(*log);
3336 HBufC* log20 = log->GetStore();
3337 ed1->InsertTextL(0, _L("ef"), 0, 0, 0);
3338 testEd1->Print(*log);
3339 HBufC* log10 = log->GetStore();
3340 ed3->InsertTextL(0, _L("gh"), 0, 0, 0);
3341 testEd3->Print(*log);
3342 HBufC* log30 = log->GetStore();
3345 check->SetCheckString(*log10);
3346 testEd1->Print(*check);
3347 CheckEditorLog(*check);
3350 check->SetCheckString(*log20);
3351 testEd2->Print(*check);
3352 CheckEditorLog(*check);
3355 check->SetCheckString(*log00);
3356 testEd0->Print(*check);
3357 CheckEditorLog(*check);
3360 TestCannotUndo(*manager);
3363 check->SetCheckString(*log00);
3364 testEd0->Print(*check);
3365 CheckEditorLog(*check);
3368 check->SetCheckString(*log20);
3369 testEd2->Print(*check);
3370 CheckEditorLog(*check);
3373 check->SetCheckString(*log10);
3374 testEd1->Print(*check);
3375 CheckEditorLog(*check);
3378 check->SetCheckString(*log30);
3379 testEd3->Print(*check);
3380 CheckEditorLog(*check);
3381 TestCannotRedo(*manager);
3383 ed0->DeleteTextL(1, 1);
3384 testEd0->Print(*log);
3385 HBufC* log01 = log->GetStore();
3386 ed2->DeleteTextL(0, 1);
3387 testEd2->Print(*log);
3388 HBufC* log21 = log->GetStore();
3389 ed3->DeleteTextL(0, 1);
3390 testEd3->Print(*log);
3391 HBufC* log31 = log->GetStore();
3392 ed1->DeleteTextL(0, 1);
3393 testEd1->Print(*log);
3394 HBufC* log11 = log->GetStore();
3397 check->SetCheckString(*log31);
3398 testEd3->Print(*check);
3399 CheckEditorLog(*check);
3402 check->SetCheckString(*log21);
3403 testEd2->Print(*check);
3404 CheckEditorLog(*check);
3407 check->SetCheckString(*log01);
3408 testEd0->Print(*check);
3409 CheckEditorLog(*check);
3412 check->SetCheckString(*log30);
3413 testEd3->Print(*check);
3414 CheckEditorLog(*check);
3417 check->SetCheckString(*log01);
3418 testEd0->Print(*check);
3419 CheckEditorLog(*check);
3422 check->SetCheckString(*log21);
3423 testEd2->Print(*check);
3424 CheckEditorLog(*check);
3427 check->SetCheckString(*log31);
3428 testEd3->Print(*check);
3429 CheckEditorLog(*check);
3432 check->SetCheckString(*log11);
3433 testEd1->Print(*check);
3434 CheckEditorLog(*check);
3435 TestCannotRedo(*manager);
3437 parLayer.iFormat.CopyL(parT);
3439 //Getting the base format to check if it is set accordingly
3440 TTmCharFormat charB1;
3442 ed0->GetBaseFormatL(charB1,parT1);
3443 TESTPOINT(charB1==charB);
3444 TESTPOINT(parT1==parT);
3446 //Getting the character format
3447 TTmCharFormatLayer charLayer1;
3448 MUnifiedEditor::TFormatLevel level=MUnifiedEditor::EEffective;
3450 ed0->GetCharFormat(0,level,charLayer1,runLen);
3452 //Getting the paragraph format
3453 RTmParFormatLayer parLayer1;
3454 ed0->GetParFormatL(0,level,parLayer1,runLen);
3458 ed0->GetText(0,text);
3459 TESTPOINT(text==_L("a"));
3461 //Deleting the formating
3462 ed0->DeleteCharFormatL(0,1);
3463 ed0->DeleteParFormatL(0,1);
3465 // To test CEditorCommandSetBaseFormat class
3466 // SetBaseFormatL calls CEditorCommandSetBaseFormatProto::CreateInverseL() which in turn calls CEditorCommandSetBaseFormat::NewL().
3467 ed1->SetBaseFormatL(charB,parT);
3468 ed1->SetCharFormatL(0, 1, charLayer);
3470 testEd1->Print(*log);
3471 HBufC* log12 = log->GetStore();
3472 ed3->SetCharFormatL(0, 1 ,charLayer);
3473 testEd3->Print(*log);
3474 HBufC* log32 = log->GetStore();
3475 ed3->SetParFormatL(0, 1, parLayer);
3476 testEd3->Print(*log);
3477 HBufC* log33 = log->GetStore();
3478 ed1->SetParFormatL(0, 1, parLayer);
3479 testEd1->Print(*log);
3480 HBufC* log13 = log->GetStore();
3483 check->SetCheckString(*log33);
3484 testEd3->Print(*check);
3485 CheckEditorLog(*check);
3488 check->SetCheckString(*log32);
3489 testEd3->Print(*check);
3490 CheckEditorLog(*check);
3493 check->SetCheckString(*log12);
3494 testEd1->Print(*check);
3495 CheckEditorLog(*check);
3498 check->SetCheckString(*log32);
3499 testEd3->Print(*check);
3500 CheckEditorLog(*check);
3503 check->SetCheckString(*log33);
3504 testEd3->Print(*check);
3505 CheckEditorLog(*check);
3508 check->SetCheckString(*log13);
3509 testEd1->Print(*check);
3510 CheckEditorLog(*check);
3526 manager->ResetUndo();
3538 __UHEAP_MARKENDC(0);
3547 TVerdict CTUndoStep::doTestStepL()
3549 SetTestStepResult(EPass);
3551 TESTPRINT(_L("TUndo - Undo system"));
3554 TESTPRINT(_L("@SYMTestCaseID:SYSLIB-FORM-LEGACY-UNDO-0001 Undo System Tests: "));
3556 // test of general undo system components
3557 TestCCommandStackL();
3558 TestCBatchCommandL();
3559 TestCCommandHistoryL();
3560 TestCCommandManagerL();
3562 // test of editor undo components
3565 // test that command manager and multiple editors integrate correctly
3566 TestMultipleEditorsL();
3568 __UHEAP_MARKENDC(0);
3570 return TestStepResult();