1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/textandloc/textrendering/textformatting/test/src/TUndo.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,3572 @@
1.4 +/*
1.5 +* Copyright (c) 2000-2010 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +* TUndo.cpp test file for UndoSystem classes
1.19 +*
1.20 +*/
1.21 +
1.22 +
1.23 +#include <e32test.h>
1.24 +
1.25 +#include "UndoSystem.h"
1.26 +#include "UndoSystemImpl.h"
1.27 +#include "EditorUndo.h"
1.28 +#include "EditorPlainTextUndo.h"
1.29 +#include <txtetext.h>
1.30 +#include <conpics.h>
1.31 +#include <s32mem.h>
1.32 +#include <s32ucmp.h>
1.33 +#include "TGraphicsContext.h"
1.34 +#include "form_and_etext_editor.h"
1.35 +
1.36 +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
1.37 +#include <txtclipboard.h>
1.38 +#include "txtfmlyr_internal.h"
1.39 +#endif
1.40 +
1.41 +#include "tundo.h"
1.42 +
1.43 +#define UNUSED_VAR(a) a = a
1.44 +
1.45 +using namespace UndoSystem;
1.46 +
1.47 +namespace
1.48 +{
1.49 +CTUndoStep* TestStep = NULL;
1.50 +#define TESTPOINT(p) TestStep->testpoint(p,(TText8*)__FILE__,__LINE__)
1.51 +#define TESTPRINT(p) TestStep->print(p,(TText8*)__FILE__,__LINE__)
1.52 +}
1.53 +
1.54 +//
1.55 +//
1.56 +// logger
1.57 +//
1.58 +//
1.59 +
1.60 +class CLogger : public CBase
1.61 + {
1.62 +public:
1.63 + virtual void Output(const TDesC& aText) = 0;
1.64 + void Output(TInt a)
1.65 + {
1.66 + TBuf<16> num(_L("<"));
1.67 + num.AppendNum(a);
1.68 + num.Append(_L(">"));
1.69 + Output(num);
1.70 + }
1.71 + };
1.72 +
1.73 +namespace
1.74 +{
1.75 +CLogger& operator<<(CLogger& aLog, const TDesC& aText)
1.76 + {
1.77 + aLog.Output(aText);
1.78 + return aLog;
1.79 + }
1.80 +CLogger& operator<<(CLogger& aLog, TInt aVal)
1.81 + {
1.82 + aLog.Output(aVal);
1.83 + return aLog;
1.84 + }
1.85 +}
1.86 +
1.87 +class CCheckingLogger : public CLogger
1.88 + {
1.89 + const TDesC* iCheck;
1.90 + TInt iPos;
1.91 + TBool iFailed;
1.92 +public:
1.93 + void SetCheckString(const TDesC& aCheck) { iCheck = &aCheck; iPos = 0; iFailed = EFalse; }
1.94 + TBool Failed() { return iFailed; }
1.95 + TBool Passed() { return !iFailed && iCheck && iCheck->Length() == iPos; }
1.96 + void Output(const TDesC& aText)
1.97 + {
1.98 + if (!iCheck || iFailed)
1.99 + return;
1.100 + TInt length = aText.Length();
1.101 + TInt maxLength = iCheck->Length() - iPos;
1.102 + TPtrC mid = iCheck->Mid(iPos, length < maxLength? length : maxLength);
1.103 + if (aText.Compare(mid) != 0)
1.104 + iFailed = ETrue;
1.105 + else
1.106 + iPos += aText.Length();
1.107 + }
1.108 + };
1.109 +
1.110 +class CStoringLogger : public CLogger
1.111 + {
1.112 + HBufC* iStore;
1.113 + TInt iMaxLength;
1.114 +public:
1.115 + ~CStoringLogger() { delete iStore; }
1.116 + HBufC* GetStore() { HBufC* r = iStore; iStore = 0; iMaxLength = 0; return r; }
1.117 + void Output(const TDesC& aText)
1.118 + {
1.119 + if (!iStore)
1.120 + {
1.121 + iStore = HBufC::NewL(50);
1.122 + iMaxLength = 50;
1.123 + }
1.124 + while (iMaxLength < aText.Length() + iStore->Length())
1.125 + {
1.126 + iMaxLength *= 2;
1.127 + iStore = iStore->ReAllocL(iMaxLength);
1.128 + }
1.129 + iStore->Des().Append(aText);
1.130 + };
1.131 + };
1.132 +
1.133 +//
1.134 +//
1.135 +// commands
1.136 +//
1.137 +//
1.138 +
1.139 +// internal commands
1.140 +class CCommandOffset;
1.141 +class CCommandToggle;
1.142 +class CTestCommand : public CSingleCommand
1.143 + {
1.144 +public:
1.145 + TUid FamilyUid() const
1.146 + {
1.147 + return TUid::Uid(12345);
1.148 + }
1.149 + virtual CCommandOffset* CastToCCommandOffset() { return 0; }
1.150 + virtual CCommandToggle* CastToCCommandToggle() { return 0; }
1.151 + };
1.152 +
1.153 +// Offset
1.154 +class CCommandOffset : public CTestCommand
1.155 + {
1.156 + TInt iOffset;
1.157 + TInt* iTarget;
1.158 + CLogger* iLogger;
1.159 + CCommandOffset() {}
1.160 +public:
1.161 + static CCommandOffset* NewL(TInt aOffset, TInt* aTarget, CLogger* aLogger = 0)
1.162 + {
1.163 + CCommandOffset* r = new(ELeave) CCommandOffset;
1.164 + r->iOffset = aOffset;
1.165 + r->iTarget = aTarget;
1.166 + r->iLogger = aLogger;
1.167 + return r;
1.168 + }
1.169 + void SetLogger(CLogger* aLogger) { iLogger = aLogger; }
1.170 + TInt ExecuteL() const
1.171 + {
1.172 + if (iLogger)
1.173 + (*iLogger) << _L("offset") << iOffset;
1.174 + *iTarget += iOffset;
1.175 + return KErrNone;
1.176 + }
1.177 + CCommand* CreateInverseL() const
1.178 + {
1.179 + return NewL(-iOffset, iTarget, iLogger);
1.180 + }
1.181 + void Add(TInt aOffset) { iOffset += aOffset; }
1.182 + CCommandOffset* CastToCCommandOffset() { return this; }
1.183 + };
1.184 +
1.185 +// Negate (only if iTog is ETrue!)
1.186 +class CCommandToggle : public CTestCommand
1.187 + {
1.188 + TBool iTog;
1.189 + TInt* iTarget;
1.190 + CLogger* iLogger;
1.191 + CCommandToggle() {}
1.192 +public:
1.193 + static CCommandToggle* NewL(TBool aTog, TInt* aTarget, CLogger* aLogger = 0)
1.194 + {
1.195 + CCommandToggle* r = new(ELeave) CCommandToggle;
1.196 + r->iTog = aTog;
1.197 + r->iTarget = aTarget;
1.198 + r->iLogger = aLogger;
1.199 + return r;
1.200 + }
1.201 + void SetLogger(CLogger* aLogger) { iLogger = aLogger; }
1.202 + TInt ExecuteL() const
1.203 + {
1.204 + if (iLogger)
1.205 + {
1.206 + (*iLogger) << _L("negate") << (iTog? 1:0);
1.207 + }
1.208 + if (iTog)
1.209 + *iTarget = -*iTarget;
1.210 + return KErrNone;
1.211 + }
1.212 + CCommand* CreateInverseL() const
1.213 + {
1.214 + return NewL(iTog, iTarget, iLogger);
1.215 + }
1.216 + void Add(TBool aTog)
1.217 + {
1.218 + if (aTog)
1.219 + iTog = !iTog;
1.220 + }
1.221 + CCommandToggle* CastToCCommandToggle() { return this; }
1.222 + };
1.223 +
1.224 +// command prototypes
1.225 +class CCommandIncProto : public CTestCommand
1.226 + {
1.227 + TInt* iTarget;
1.228 + CLogger* iLogger;
1.229 + CCommandIncProto() {}
1.230 +public:
1.231 + static CCommandIncProto* NewL(TInt* aTarget, CLogger* aLogger = 0)
1.232 + {
1.233 + CCommandIncProto* r = new(ELeave) CCommandIncProto;
1.234 + r->iTarget = aTarget;
1.235 + r->iLogger = aLogger;
1.236 + return r;
1.237 + }
1.238 + TInt ExecuteL() const
1.239 + {
1.240 + if (iLogger)
1.241 + (*iLogger) << _L("inc<>");
1.242 + ++*iTarget;
1.243 + return KErrNone;
1.244 + }
1.245 + CCommand* CreateInverseL() const
1.246 + {
1.247 + return CCommandOffset::NewL(-1, iTarget, iLogger);
1.248 + }
1.249 + TBool PrepareToAddInverseToLastL(CSingleCommand& aLastCommand) const
1.250 + {
1.251 + if (aLastCommand.FamilyUid() != TUid::Uid(12345))
1.252 + return EFalse;
1.253 + return !!static_cast<CTestCommand&>(aLastCommand).CastToCCommandOffset();
1.254 + }
1.255 + void AddInverseToLast(CSingleCommand& aLastCommand) const
1.256 + {
1.257 + CCommandOffset* c =
1.258 + static_cast<CTestCommand&>(aLastCommand).CastToCCommandOffset();
1.259 + ASSERT(c);
1.260 + c->Add(-1);
1.261 + }
1.262 + };
1.263 +
1.264 +class CCommandDecProto : public CTestCommand
1.265 + {
1.266 + TInt* iTarget;
1.267 + CLogger* iLogger;
1.268 + CCommandDecProto() {}
1.269 +public:
1.270 + static CCommandDecProto* NewL(TInt* aTarget, CLogger* aLogger = 0)
1.271 + {
1.272 + CCommandDecProto* r = new(ELeave) CCommandDecProto;
1.273 + r->iTarget = aTarget;
1.274 + r->iLogger = aLogger;
1.275 + return r;
1.276 + }
1.277 + TInt ExecuteL() const
1.278 + {
1.279 + if (iLogger)
1.280 + (*iLogger) << _L("dec<>");
1.281 + --*iTarget;
1.282 + return KErrNone;
1.283 + }
1.284 + CCommand* CreateInverseL() const
1.285 + {
1.286 + return CCommandOffset::NewL(1, iTarget, iLogger);
1.287 + }
1.288 + TBool PrepareToAddInverseToLastL(CSingleCommand& aLastCommand) const
1.289 + {
1.290 + if (aLastCommand.FamilyUid() != TUid::Uid(12345))
1.291 + return EFalse;
1.292 + return !!static_cast<CTestCommand&>(aLastCommand).CastToCCommandOffset();
1.293 + }
1.294 + void AddInverseToLast(CSingleCommand& aLastCommand) const
1.295 + {
1.296 + CCommandOffset* c =
1.297 + static_cast<CTestCommand&>(aLastCommand).CastToCCommandOffset();
1.298 + ASSERT(c);
1.299 + c->Add(1);
1.300 + }
1.301 + };
1.302 +
1.303 +class CCommandNegProto : public CTestCommand
1.304 + {
1.305 + TInt* iTarget;
1.306 + CLogger* iLogger;
1.307 + CCommandNegProto() {}
1.308 +public:
1.309 + static CCommandNegProto* NewL(TInt* aTarget, CLogger* aLogger = 0)
1.310 + {
1.311 + CCommandNegProto* r = new(ELeave) CCommandNegProto;
1.312 + r->iTarget = aTarget;
1.313 + r->iLogger = aLogger;
1.314 + return r;
1.315 + }
1.316 + TInt ExecuteL() const
1.317 + {
1.318 + if (iLogger)
1.319 + (*iLogger) << _L("neg<>");
1.320 + *iTarget = -*iTarget;
1.321 + return KErrNone;
1.322 + }
1.323 + CCommand* CreateInverseL() const
1.324 + {
1.325 + return CCommandToggle::NewL(ETrue, iTarget, iLogger);
1.326 + }
1.327 + TBool PrepareToAddInverseToLastL(CSingleCommand& aLastCommand) const
1.328 + {
1.329 + if (aLastCommand.FamilyUid() != TUid::Uid(12345))
1.330 + return EFalse;
1.331 + return !!static_cast<CTestCommand&>(aLastCommand).CastToCCommandToggle();
1.332 + }
1.333 + void AddInverseToLast(CSingleCommand& aLastCommand) const
1.334 + {
1.335 + CCommandToggle* c =
1.336 + static_cast<CTestCommand&>(aLastCommand).CastToCCommandToggle();
1.337 + ASSERT(c);
1.338 + c->Add(ETrue);
1.339 + }
1.340 + };
1.341 +
1.342 +// command whose inverse is a batch command
1.343 +class CCommandDecThenNegProto : public CTestCommand
1.344 + {
1.345 + TInt* iTarget;
1.346 + CLogger* iLogger;
1.347 + CCommandDecThenNegProto() {}
1.348 +public:
1.349 + static CCommandDecThenNegProto* NewL(TInt* aTarget, CLogger* aLogger = 0)
1.350 + {
1.351 + CCommandDecThenNegProto* r = new(ELeave) CCommandDecThenNegProto;
1.352 + r->iTarget = aTarget;
1.353 + r->iLogger = aLogger;
1.354 + return r;
1.355 + }
1.356 + TInt ExecuteL() const
1.357 + {
1.358 + if (iLogger)
1.359 + (*iLogger) << _L("decneg<>");
1.360 + *iTarget = -(*iTarget - 1);
1.361 + return KErrNone;
1.362 + }
1.363 + CCommand* CreateInverseL() const
1.364 + {
1.365 + CBatchCommand* batch = CBatchCommand::NewLC();
1.366 + batch->PushL(CCommandOffset::NewL(1, iTarget, iLogger));
1.367 + batch->PushL(CCommandToggle::NewL(ETrue, iTarget, iLogger));
1.368 + CleanupStack::Pop(batch);
1.369 + return batch;
1.370 + }
1.371 + };
1.372 +
1.373 +class CCommandCannotDo : public CTestCommand
1.374 + {
1.375 + CLogger* iLogger;
1.376 +public:
1.377 + static CCommandCannotDo* NewL(CLogger* aLogger)
1.378 + {
1.379 + CCommandCannotDo* r = new(ELeave) CCommandCannotDo;
1.380 + r->iLogger = aLogger;
1.381 + return r;
1.382 + }
1.383 + TInt ExecuteL() const
1.384 + {
1.385 + if (iLogger)
1.386 + (*iLogger) << _L("nodo<>");
1.387 + return KErrNotSupported;
1.388 + }
1.389 + CCommand* CreateInverseL() const
1.390 + {
1.391 + return 0;
1.392 + }
1.393 + };
1.394 +
1.395 +class CCommandCannotInvert : public CTestCommand
1.396 + {
1.397 + CLogger* iLogger;
1.398 +public:
1.399 + static CCommandCannotInvert* NewL(CLogger* aLogger)
1.400 + {
1.401 + CCommandCannotInvert* r = new(ELeave) CCommandCannotInvert;
1.402 + r->iLogger = aLogger;
1.403 + return r;
1.404 + }
1.405 + TInt ExecuteL() const
1.406 + {
1.407 + if (iLogger)
1.408 + (*iLogger) << _L("noinv<>");
1.409 + return KErrNone;
1.410 + }
1.411 + CCommand* CreateInverseL() const
1.412 + {
1.413 + if (iLogger)
1.414 + (*iLogger) << _L("noinvfail.");
1.415 + User::Leave(KErrNotSupported);
1.416 + return 0;
1.417 + }
1.418 + };
1.419 +
1.420 +class CCommandLeavesInvert : public CTestCommand
1.421 + {
1.422 + CLogger* iLogger;
1.423 +public:
1.424 + mutable TBool iFail;
1.425 + static CCommandLeavesInvert* NewL(CLogger* aLogger)
1.426 + {
1.427 + CCommandLeavesInvert* r = new(ELeave) CCommandLeavesInvert;
1.428 + r->iLogger = aLogger;
1.429 + r->iFail = ETrue;
1.430 + return r;
1.431 + }
1.432 + TInt ExecuteL() const
1.433 + {
1.434 + if (iLogger)
1.435 + (*iLogger) << _L("leaveinv<>");
1.436 + return KErrNone;
1.437 + }
1.438 + CCommand* CreateInverseL() const
1.439 + {
1.440 + if (iFail)
1.441 + {
1.442 + iFail = EFalse;
1.443 + if (iLogger)
1.444 + (*iLogger) << _L("noinvfail.");
1.445 + User::Leave(KErrNotFound);
1.446 + }
1.447 + return 0;
1.448 + }
1.449 + };
1.450 +
1.451 +class CCommandNoMemory : public CTestCommand
1.452 + {
1.453 + CLogger* iLogger;
1.454 +public:
1.455 + TBool iFailInvert;
1.456 + TBool iFailAddToLast;
1.457 + TBool iFailExecute;
1.458 + mutable TBool iLogExecuteFailed;
1.459 +
1.460 + static CCommandNoMemory* NewL(CLogger* aLogger)
1.461 + {
1.462 + CCommandNoMemory* r = new(ELeave) CCommandNoMemory;
1.463 + r->iLogger = aLogger;
1.464 + r->iFailInvert = ETrue;
1.465 + r->iFailAddToLast = ETrue;
1.466 + r->iFailExecute = ETrue;
1.467 + r->iLogExecuteFailed= ETrue;
1.468 + return r;
1.469 + }
1.470 + TInt ExecuteL() const
1.471 + {
1.472 + if (iFailExecute)
1.473 + {
1.474 + if (iLogger && iLogExecuteFailed)
1.475 + (*iLogger) << _L("nomemfailexe.");
1.476 + iLogExecuteFailed = EFalse;
1.477 + User::Leave(KErrNoMemory);
1.478 + }
1.479 + if (iLogger)
1.480 + (*iLogger) << _L("nomem<>");
1.481 + return KErrNone;
1.482 + }
1.483 + CCommand* CreateInverseL() const
1.484 + {
1.485 + if (iFailInvert)
1.486 + {
1.487 + if (iLogger)
1.488 + (*iLogger) << _L("nomemfailinv.");
1.489 + User::Leave(KErrNoMemory);
1.490 + }
1.491 + return 0;
1.492 + }
1.493 + TBool PrepareToAddInverseToLastL(CSingleCommand&) const
1.494 + {
1.495 + if (iFailAddToLast)
1.496 + {
1.497 + if (iLogger)
1.498 + (*iLogger) << _L("nomemfailadd.");
1.499 + User::Leave(KErrNoMemory);
1.500 + }
1.501 + return EFalse;
1.502 + }
1.503 + };
1.504 +
1.505 +// this gatekeeper refuses non-undoable requests
1.506 +class CRefuserGatekeeper : public CBase, public MNotUndoableGatekeeper
1.507 + {
1.508 +public:
1.509 + TBool RetryOutOfMemoryL(TInt)
1.510 + {
1.511 + return EFalse;
1.512 + }
1.513 + TBool AllowNotUndoableL(TInt)
1.514 + {
1.515 + return EFalse;
1.516 + }
1.517 + };
1.518 +
1.519 +// this gatekeeper permits all non-undoable requests
1.520 +// (not just KErrNotSupported and KErrNoMemory)
1.521 +class CPermitterGatekeeper : public CBase, public MNotUndoableGatekeeper
1.522 + {
1.523 +public:
1.524 + TBool RetryOutOfMemoryL(TInt)
1.525 + {
1.526 + return EFalse;
1.527 + }
1.528 + TBool AllowNotUndoableL(TInt)
1.529 + {
1.530 + return ETrue;
1.531 + }
1.532 + };
1.533 +
1.534 +// this gatekeeper makes the CCommandNoMemory fail less the more times it is called
1.535 +class CMemoryReclaimGatekeeper : public CRefuserGatekeeper
1.536 + {
1.537 +public:
1.538 + CCommandNoMemory* iTarget;
1.539 + CMemoryReclaimGatekeeper(CCommandNoMemory* aTarget = 0) : iTarget(aTarget) {}
1.540 + TBool RetryOutOfMemoryL(TInt aNumRetries)
1.541 + {
1.542 + if (aNumRetries == 0)
1.543 + {
1.544 + iTarget->iFailAddToLast = EFalse;
1.545 + return ETrue;
1.546 + }
1.547 + if (aNumRetries == 1)
1.548 + {
1.549 + iTarget->iFailInvert = EFalse;
1.550 + return ETrue;
1.551 + }
1.552 + if (aNumRetries == 2)
1.553 + {
1.554 + iTarget->iFailExecute = EFalse;
1.555 + return ETrue;
1.556 + }
1.557 + return EFalse;
1.558 + }
1.559 + };
1.560 +
1.561 +
1.562 +//
1.563 +//
1.564 +// Editor
1.565 +//
1.566 +//
1.567 +
1.568 +// a cut-down set of attributes for testing purposes
1.569 +class CUndoTestPicture : public CPicture
1.570 + {
1.571 + TBuf<1> iDesc;
1.572 +public:
1.573 + CUndoTestPicture(TInt aChar) : iDesc(1) { iDesc[0] = static_cast<TText>(aChar); }
1.574 + void Draw(CGraphicsContext&, const TPoint&, const TRect&, MGraphicsDeviceMap*) const {}
1.575 + void ExternalizeL(RWriteStream&) const {}
1.576 + void GetOriginalSizeInTwips(TSize&) const {}
1.577 + TPtrC Description() const { return iDesc; }
1.578 + };
1.579 +
1.580 +struct TTestAttributes
1.581 + {
1.582 + TInt8 iCharFlags;
1.583 + TInt8 iParFlags;
1.584 + TInt8 iStyle;
1.585 + TTestAttributes() : iCharFlags(0), iParFlags(0), iStyle(-1) {}
1.586 + TBool operator==(TTestAttributes& a)
1.587 + {
1.588 + return iCharFlags == a.iCharFlags && iParFlags == a.iParFlags && iStyle == a.iStyle;
1.589 + }
1.590 + };
1.591 +CLogger& operator<<(CLogger& log, TTestAttributes& at)
1.592 + {
1.593 + TBuf<3> buf(_L("Aa0"));
1.594 + buf[0] = (TText)(buf[0] + (at.iCharFlags & 15));
1.595 + buf[1] = (TText)(buf[1] + (at.iParFlags & 15));
1.596 + buf[2] = (TText)(buf[2] + at.iStyle);
1.597 + return log << buf;
1.598 + }
1.599 +// Test editor, badly behaved if something leaves.
1.600 +// The only formats supported are bold, italic, keep together and keep with next.
1.601 +class CTestEditor : public CBase, public MUnifiedEditor,
1.602 + public MUnifiedEditor::MStyleSupport,
1.603 + public MUnifiedEditor::MPictureSupport,
1.604 + public MUnifiedEditor::MClipboardSupport
1.605 + {
1.606 + TTestAttributes iBase;
1.607 + TTestAttributes iStyles[10];
1.608 + TBuf<KMaxParagraphStyleName> iStyleNames[10];
1.609 + TInt iNumStyles;
1.610 + CArrayFix<TTestAttributes>* iAttrs;
1.611 + CBufSeg* iText;
1.612 + CArrayFix<CUndoTestPicture*>* iPics;
1.613 +
1.614 + CTestEditor* ConstructL()
1.615 + {
1.616 + iText = CBufSeg::NewL(5 * sizeof(TText));
1.617 + iAttrs = new(ELeave) CArrayFixFlat<TTestAttributes>(5);
1.618 + iPics = new(ELeave) CArrayFixFlat<CUndoTestPicture*>(5);
1.619 + return this;
1.620 + }
1.621 + TInt Style(const TDesC& aName) const
1.622 + {
1.623 + for (int i = 0; i != iNumStyles; ++i)
1.624 + if (aName == iStyleNames[i])
1.625 + return i;
1.626 + return -1;
1.627 + }
1.628 + TInt InsertStylePos(const TDesC& aName) const
1.629 + {
1.630 + int i;
1.631 + for (i = 0; i != iNumStyles; ++i)
1.632 + if (aName.Compare(iStyleNames[i]) <= 0)
1.633 + return i;
1.634 + return i;
1.635 + }
1.636 + void ReassignStyles(TInt aFrom, TInt aTo)
1.637 + {
1.638 + ASSERT(-1 <= aTo && aTo < iNumStyles);
1.639 + ASSERT(0 <= aFrom && aFrom < iNumStyles);
1.640 + if (aTo == aFrom)
1.641 + return;
1.642 + TInt setTo = aTo;
1.643 + if (aTo == -1)
1.644 + aTo = iNumStyles - 1;
1.645 + TInt low = aFrom;
1.646 + TInt high = aTo;
1.647 + TInt delta = -1;
1.648 + if (aTo < aFrom)
1.649 + {
1.650 + low = aTo;
1.651 + high = aFrom;
1.652 + delta = 1;
1.653 + }
1.654 + TInt len = DocumentLength();
1.655 +
1.656 + int i;
1.657 + for (i = 0; i != len; ++i)
1.658 + {
1.659 + TTestAttributes* attr = &iAttrs->At(i);
1.660 + if (aFrom == attr->iStyle)
1.661 + attr->iStyle = static_cast<TInt8>(setTo);
1.662 + else if (low <= attr->iStyle && attr->iStyle <= high)
1.663 + attr->iStyle = static_cast<TInt8>(attr->iStyle + delta);
1.664 + }
1.665 + for (i = aFrom; i != aTo; i -= delta)
1.666 + {
1.667 + iStyles[i] = iStyles[i - delta];
1.668 + iStyleNames[i] = iStyleNames[i - delta];
1.669 + }
1.670 + }
1.671 + void DoDeleteStyle(TInt aForDeletion)
1.672 + {
1.673 + ASSERT(aForDeletion < iNumStyles);
1.674 + ReassignStyles(aForDeletion, -1);
1.675 + --iNumStyles;
1.676 + }
1.677 + void DoAddStyle(const TDesC& aNewName, const TTestAttributes& aAttr)
1.678 + {
1.679 + ASSERT(iNumStyles < 10);
1.680 + TInt pos = InsertStylePos(aNewName);
1.681 + ++iNumStyles;
1.682 + ReassignStyles(iNumStyles - 1, pos);
1.683 + iStyles[pos] = aAttr;
1.684 + iStyleNames[pos] = aNewName;
1.685 + }
1.686 + static void BoldToAttr(TTestAttributes& aAttr, const TTmCharFormat& aCFormat)
1.687 + {
1.688 + if (aCFormat.iFontSpec.IsBold())
1.689 + aAttr.iCharFlags |= 1;
1.690 + else
1.691 + aAttr.iCharFlags &= ~1;
1.692 + }
1.693 + static void ItalicToAttr(TTestAttributes& aAttr, const TTmCharFormat& aCFormat)
1.694 + {
1.695 + if (aCFormat.iFontSpec.IsItalic())
1.696 + aAttr.iCharFlags |= 2;
1.697 + else
1.698 + aAttr.iCharFlags &= ~2;
1.699 + }
1.700 + static void CharFormatToAttr(TTestAttributes& aAttr, const TTmCharFormat& aCFormat)
1.701 + {
1.702 + aAttr.iCharFlags = 0;
1.703 + BoldToAttr(aAttr, aCFormat);
1.704 + ItalicToAttr(aAttr, aCFormat);
1.705 + }
1.706 + static void CharLayerToAttr(TTestAttributes& aAttr, const TTmCharFormatLayer& aCLayer)
1.707 + {
1.708 + if (aCLayer.iMask.iFlags & TTmCharFormatMask::EBold)
1.709 + {
1.710 + aAttr.iCharFlags |= 4;
1.711 + BoldToAttr(aAttr, aCLayer.iFormat);
1.712 + }
1.713 + if (aCLayer.iMask.iFlags & TTmCharFormatMask::EItalic)
1.714 + {
1.715 + aAttr.iCharFlags |= 8;
1.716 + ItalicToAttr(aAttr, aCLayer.iFormat);
1.717 + }
1.718 + }
1.719 + static void KeepTogetherToAttr(TTestAttributes& aAttr, const RTmParFormat& aPFormat)
1.720 + {
1.721 + if (aPFormat.iFlags & RTmParFormat::EKeepTogether)
1.722 + aAttr.iParFlags |= 1;
1.723 + else
1.724 + aAttr.iParFlags &= ~1;
1.725 + }
1.726 + static void KeepWithNextToAttr(TTestAttributes& aAttr, const RTmParFormat& aPFormat)
1.727 + {
1.728 + if (aPFormat.iFlags & RTmParFormat::EKeepWithNext)
1.729 + aAttr.iParFlags |= 2;
1.730 + else
1.731 + aAttr.iParFlags &= ~2;
1.732 + }
1.733 + static void ParFormatToAttr(TTestAttributes& aAttr, const RTmParFormat& aPFormat)
1.734 + {
1.735 + aAttr.iParFlags = 0;
1.736 + KeepTogetherToAttr(aAttr, aPFormat);
1.737 + KeepWithNextToAttr(aAttr, aPFormat);
1.738 + }
1.739 + static void ParLayerToAttr(TTestAttributes& aAttr, const RTmParFormatLayer& aPLayer)
1.740 + {
1.741 + if (aPLayer.iMask.iFlags & TTmParFormatMask::EKeepTogether)
1.742 + {
1.743 + aAttr.iParFlags |= 4;
1.744 + KeepTogetherToAttr(aAttr, aPLayer.iFormat);
1.745 + }
1.746 + if (aPLayer.iMask.iFlags & TTmParFormatMask::EKeepWithNext)
1.747 + {
1.748 + aAttr.iParFlags |= 8;
1.749 + KeepWithNextToAttr(aAttr, aPLayer.iFormat);
1.750 + }
1.751 + }
1.752 + static void BoldAttrToCharFormat(TTmCharFormat& aCFormat, const TTestAttributes& aAttr)
1.753 + {
1.754 + if (aAttr.iCharFlags & 1)
1.755 + aCFormat.iFontSpec.SetBold(ETrue);
1.756 + }
1.757 + static void ItalicAttrToCharFormat(TTmCharFormat& aCFormat, const TTestAttributes& aAttr)
1.758 + {
1.759 + if (aAttr.iCharFlags & 2)
1.760 + aCFormat.iFontSpec.SetItalic(ETrue);
1.761 + }
1.762 + static void ResetCharFormat(TTmCharFormat& aCFormat)
1.763 + {
1.764 + TTmCharFormat c;
1.765 + aCFormat = c;
1.766 + }
1.767 + static void AttrToCharFormat(TTmCharFormat& aCFormat, const TTestAttributes& aAttr)
1.768 + {
1.769 + ResetCharFormat(aCFormat);
1.770 + BoldAttrToCharFormat(aCFormat, aAttr);
1.771 + ItalicAttrToCharFormat(aCFormat, aAttr);
1.772 + }
1.773 + static void MergeAttrToCharLayer(TTmCharFormatLayer& aCLayer, const TTestAttributes& aAttr)
1.774 + {
1.775 + if (aAttr.iCharFlags & 4)
1.776 + {
1.777 + aCLayer.iMask.iFlags |= TTmCharFormatMask::EBold;
1.778 + BoldAttrToCharFormat(aCLayer.iFormat, aAttr);
1.779 + }
1.780 + if (aAttr.iCharFlags & 8)
1.781 + {
1.782 + aCLayer.iMask.iFlags |= TTmCharFormatMask::EItalic;
1.783 + ItalicAttrToCharFormat(aCLayer.iFormat, aAttr);
1.784 + }
1.785 + }
1.786 + static void AttrToCharLayer(TTmCharFormatLayer& aCLayer, const TTestAttributes& aAttr)
1.787 + {
1.788 + ResetCharFormat(aCLayer.iFormat);
1.789 + aCLayer.iMask.iFlags = 0;
1.790 + MergeAttrToCharLayer(aCLayer, aAttr);
1.791 + }
1.792 + static void ResetParFormat(RTmParFormat& aPFormat)
1.793 + {
1.794 + RTmParFormat p;
1.795 + CleanupClosePushL(p);
1.796 + aPFormat.CopyL(p);
1.797 + CleanupStack::PopAndDestroy();
1.798 + }
1.799 + static void KeepTogetherAttrToParFormat(RTmParFormat& aPFormat, const TTestAttributes& aAttr)
1.800 + {
1.801 + if (aAttr.iParFlags & 1)
1.802 + aPFormat.iFlags |= RTmParFormat::EKeepTogether;
1.803 + }
1.804 + static void KeepWithNextAttrToParFormat(RTmParFormat& aPFormat, const TTestAttributes& aAttr)
1.805 + {
1.806 + if (aAttr.iParFlags & 2)
1.807 + aPFormat.iFlags |= RTmParFormat::EKeepWithNext;
1.808 + }
1.809 + static void AttrToParFormat(RTmParFormat& aPFormat, const TTestAttributes& aAttr)
1.810 + {
1.811 + ResetParFormat(aPFormat);
1.812 + KeepTogetherAttrToParFormat(aPFormat, aAttr);
1.813 + KeepWithNextAttrToParFormat(aPFormat, aAttr);
1.814 + }
1.815 + static void MergeAttrToParLayer(RTmParFormatLayer& aPLayer, const TTestAttributes& aAttr)
1.816 + {
1.817 + if (aAttr.iParFlags & 4)
1.818 + {
1.819 + aPLayer.iMask.iFlags |= TTmParFormatMask::EKeepTogether;
1.820 + KeepTogetherAttrToParFormat(aPLayer.iFormat, aAttr);
1.821 + }
1.822 + if (aAttr.iParFlags & 8)
1.823 + {
1.824 + aPLayer.iMask.iFlags |= TTmParFormatMask::EKeepWithNext;
1.825 + KeepWithNextAttrToParFormat(aPLayer.iFormat, aAttr);
1.826 + }
1.827 + }
1.828 + static void AttrToParLayer(RTmParFormatLayer& aPLayer, const TTestAttributes& aAttr)
1.829 + {
1.830 + ResetParFormat(aPLayer.iFormat);
1.831 + aPLayer.iMask.iFlags = 0;
1.832 + MergeAttrToParLayer(aPLayer, aAttr);
1.833 + }
1.834 +public:
1.835 + ~CTestEditor()
1.836 + {
1.837 + delete iAttrs;
1.838 + // workaround for CBufSeg bug
1.839 + if (0 < iText->Size())
1.840 + iText->Delete(iText->Size() - 1, 1);
1.841 + delete iText;
1.842 + delete iPics;
1.843 + }
1.844 + static CTestEditor* NewL() { return (new(ELeave) CTestEditor)->ConstructL(); }
1.845 + void Reset()
1.846 + {
1.847 + iAttrs->Reset();
1.848 + iText->Reset();
1.849 + iPics->Reset();
1.850 + iNumStyles = 0;
1.851 + }
1.852 + void AlterGranularityL(TInt aNewGranularity)
1.853 + {
1.854 + CBufSeg* newIText = CBufSeg::NewL(aNewGranularity * sizeof(TText));
1.855 + CleanupStack::PushL(newIText);
1.856 + TBuf8<32> transfer;
1.857 + TInt pos = 0;
1.858 + while (pos < iText->Size())
1.859 + {
1.860 + TInt length = transfer.MaxLength();
1.861 + if (iText->Size() - pos < length)
1.862 + length = iText->Size() - pos;
1.863 + iText->Read(pos, transfer, length);
1.864 + newIText->InsertL(pos, transfer, length);
1.865 + pos += transfer.Length();
1.866 + }
1.867 + CleanupStack::Pop(newIText);
1.868 + // workaround for CBufSeg bug
1.869 + if (0 < iText->Size())
1.870 + iText->Delete(iText->Size() - 1, 1);
1.871 + delete iText;
1.872 + iText = newIText;
1.873 + }
1.874 + void Print(CLogger& log)
1.875 + {
1.876 + TInt length = DocumentLength();
1.877 + int i;
1.878 + log << _L("text{");
1.879 + for (i = 0; i < length;)
1.880 + {
1.881 + TPtrC seg;
1.882 + GetText(i, seg);
1.883 + TInt picPos = seg.Locate(CEditableText::EPictureCharacter);
1.884 + if (0 < picPos)
1.885 + {
1.886 + // shorten seg to just before the picture character
1.887 + TPtrC temp(seg.Ptr(), picPos);
1.888 + seg.Set(temp);
1.889 + }
1.890 + if (0 == picPos)
1.891 + {
1.892 + CUndoTestPicture* pic = iPics->At(i);
1.893 + if (pic)
1.894 + log << _L("{pic:") << pic->Description() << _L("}");
1.895 + else
1.896 + log << _L("{nopic}");
1.897 + ++i;
1.898 + }
1.899 + else
1.900 + {
1.901 + log << seg;
1.902 + i += seg.Length();
1.903 + }
1.904 + }
1.905 + log << _L("} styles{");
1.906 + for(i = 0; i != iNumStyles; ++i)
1.907 + {
1.908 + if (i)
1.909 + log << _L(", ");
1.910 + log << iStyleNames[i] << _L(":") << iStyles[i];
1.911 + }
1.912 + log << _L("} attr{");
1.913 + for (i = 0; i != length; ++i)
1.914 + log << iAttrs->At(i);
1.915 + log << _L("} ");
1.916 + }
1.917 + MTmOptionalInterface* Interface(TUint aId)
1.918 + {
1.919 + if (aId == KUidMUnifiedEditorStyleSupport)
1.920 + return static_cast<MUnifiedEditor::MStyleSupport*>(this);
1.921 + if (aId == KUidMUnifiedEditorPictureSupport)
1.922 + return static_cast<MUnifiedEditor::MPictureSupport*>(this);
1.923 + if (aId == KUidMUnifiedEditorClipboardSupport)
1.924 + return static_cast<MUnifiedEditor::MClipboardSupport*>(this);
1.925 + return 0;
1.926 + }
1.927 +
1.928 + void InsertTextL(TInt aPos, const TDesC& aText,
1.929 + const TDesC* aStyle,
1.930 + const TTmCharFormatLayer* aCharFormat,
1.931 + const RTmParFormatLayer* aParFormat)
1.932 + {
1.933 + TTestAttributes attr;
1.934 + attr.iStyle = aStyle? (TInt8)Style(*aStyle) : (TInt8)-1;
1.935 + if (aCharFormat)
1.936 + CharLayerToAttr(attr, *aCharFormat);
1.937 + if (aParFormat)
1.938 + ParLayerToAttr(attr, *aParFormat);
1.939 + iText->InsertL(aPos * sizeof(TText), aText.Ptr(), aText.Length() * sizeof(TText));
1.940 + iAttrs->InsertL(aPos, attr, aText.Length());
1.941 + CUndoTestPicture* nullPic = 0;
1.942 + iPics->InsertL(aPos, nullPic, aText.Length());
1.943 + }
1.944 + void DeleteTextL(TInt aPos, TInt aLength)
1.945 + {
1.946 + iText->Delete(aPos * sizeof(TText), aLength * sizeof(TText));
1.947 + iAttrs->Delete(aPos, aLength);
1.948 + for (int i = aPos; i != aPos + aLength; ++i)
1.949 + delete iPics->At(i);
1.950 + iPics->Delete(aPos, aLength);
1.951 + }
1.952 + void SetBaseFormatL(const TTmCharFormat& aCharFormat,const RTmParFormat& aParFormat)
1.953 + {
1.954 + CharFormatToAttr(iBase, aCharFormat);
1.955 + ParFormatToAttr(iBase, aParFormat);
1.956 + }
1.957 + void SetCharFormatL(TInt aPos,TInt aLength,const TTmCharFormatLayer& aFormat)
1.958 + {
1.959 + TInt end = aPos + aLength;
1.960 + if (DocumentLength() < end)
1.961 + end = DocumentLength();
1.962 + for (; aPos < end; ++aPos)
1.963 + CharLayerToAttr(iAttrs->At(aPos), aFormat);
1.964 + }
1.965 + void SetParFormatL(TInt aPos,TInt aLength,const RTmParFormatLayer& aFormat)
1.966 + {
1.967 + TInt end = aPos + aLength;
1.968 + if (DocumentLength() < end)
1.969 + end = DocumentLength();
1.970 + for (; aPos < end; ++aPos)
1.971 + ParLayerToAttr(iAttrs->At(aPos), aFormat);
1.972 + }
1.973 + void DeleteCharFormatL(TInt aPos,TInt aLength)
1.974 + {
1.975 + TInt end = aPos + aLength;
1.976 + if (DocumentLength() < end)
1.977 + end = DocumentLength();
1.978 + for (; aPos < end; ++aPos)
1.979 + iAttrs->At(aPos).iCharFlags = 0;
1.980 + }
1.981 + void DeleteParFormatL(TInt aPos,TInt aLength)
1.982 + {
1.983 + TInt end = aPos + aLength;
1.984 + if (DocumentLength() < end)
1.985 + end = DocumentLength();
1.986 + for (; aPos < end; ++aPos)
1.987 + iAttrs->At(aPos).iParFlags = 0;
1.988 + }
1.989 + TInt CreateStyleL(const RTmStyle& aStyle)
1.990 + {
1.991 + TInt styleNo = Style(aStyle.iName);
1.992 + if (0 <= styleNo)
1.993 + return KErrAlreadyExists;
1.994 + TTestAttributes newAttr;
1.995 + CharLayerToAttr(newAttr, aStyle.iCharFormat);
1.996 + ParLayerToAttr(newAttr, aStyle.iParFormat);
1.997 + DoAddStyle(aStyle.iName, newAttr);
1.998 + return KErrNone;
1.999 + }
1.1000 + TInt ChangeStyleL(const RTmStyle& aStyle)
1.1001 + {
1.1002 + TInt styleNo = Style(aStyle.iName);
1.1003 + if (styleNo < 0)
1.1004 + return KErrNotFound;
1.1005 + iStyles[styleNo] = TTestAttributes();
1.1006 + CharLayerToAttr(iStyles[styleNo], aStyle.iCharFormat);
1.1007 + ParLayerToAttr(iStyles[styleNo], aStyle.iParFormat);
1.1008 + return KErrNone;
1.1009 + }
1.1010 + TInt SetStyleL(TInt aPos, TInt aLength, const TDesC& aName)
1.1011 + {
1.1012 + TInt styleNo(-1);
1.1013 + if (aName.Length())
1.1014 + {
1.1015 + styleNo = Style(aName);
1.1016 + if (styleNo < 0)
1.1017 + return KErrNotFound;
1.1018 + }
1.1019 + TInt end = aPos + aLength;
1.1020 + for (; aPos < end; ++aPos)
1.1021 + iAttrs->At(aPos).iStyle = (TInt8)styleNo;
1.1022 + return KErrNone;
1.1023 + }
1.1024 + TInt RenameStyleL(const TDesC& aOldName, const TDesC& aNewName)
1.1025 + {
1.1026 + TInt oldNo = Style(aOldName);
1.1027 + if (oldNo < 0)
1.1028 + return KErrNotFound;
1.1029 + TTestAttributes temp = iStyles[oldNo];
1.1030 + TInt newNo = InsertStylePos(aNewName);
1.1031 + if (oldNo < newNo)
1.1032 + --newNo;
1.1033 + ReassignStyles(oldNo, newNo);
1.1034 + iStyles[newNo] = temp;
1.1035 + iStyleNames[newNo] = aNewName;
1.1036 + return KErrNone;
1.1037 + }
1.1038 + TInt DeleteStyleL(const TDesC& aName)
1.1039 + {
1.1040 + TInt n = Style(aName);
1.1041 + if (n < 0)
1.1042 + return KErrNotFound;
1.1043 + DoDeleteStyle(n);
1.1044 + return KErrNone;
1.1045 + }
1.1046 + void InsertPictureL(TInt aPos, const TPictureHeader& aPictureIn)
1.1047 + {
1.1048 + TBuf<1> picChar(1);
1.1049 + picChar[0] = CEditableText::EPictureCharacter;
1.1050 + InsertTextL(aPos, picChar, 0, 0, 0);
1.1051 + iPics->At(aPos) = static_cast<CUndoTestPicture*>(aPictureIn.iPicture.AsPtr());
1.1052 + }
1.1053 + void DropPictureL(TInt aPos)
1.1054 + {
1.1055 + TPtrC ptr;
1.1056 + GetText(aPos, ptr);
1.1057 + if (ptr[0] == CEditableText::EPictureCharacter)
1.1058 + {
1.1059 + iPics->At(aPos) = 0;
1.1060 + DeleteTextL(aPos, 1);
1.1061 + }
1.1062 + }
1.1063 + void Picture(TInt aPos, TPictureHeader& aPictureOut) const
1.1064 + {
1.1065 + CPicture* pic = iPics->At(aPos);
1.1066 + aPictureOut.iPictureType = KUidXzePictureType;
1.1067 + aPictureOut.iPicture = pic;
1.1068 + }
1.1069 + TInt DocumentLength() const
1.1070 + {
1.1071 + return iText->Size() / sizeof(TText);
1.1072 + }
1.1073 + void GetText(TInt aPos, TPtrC& aText) const
1.1074 + {
1.1075 + iText->Compress();
1.1076 + if (DocumentLength() <= aPos)
1.1077 + aPos = DocumentLength();
1.1078 + TPtr8 ptr = iText->Ptr(aPos * sizeof(TText));
1.1079 + aText.Set((TText*)ptr.Ptr(), ptr.Length()/sizeof(TText));
1.1080 + }
1.1081 + void GetBaseFormatL(TTmCharFormat& aCharFormat, RTmParFormat& aParFormat) const
1.1082 + {
1.1083 + AttrToCharFormat(aCharFormat, iBase);
1.1084 + AttrToParFormat(aParFormat, iBase);
1.1085 + }
1.1086 + void GetCharFormat(TInt aPos, TFormatLevel aLevel,
1.1087 + TTmCharFormatLayer& aFormat, TInt& aRunLength) const
1.1088 + {
1.1089 + TInt length = DocumentLength();
1.1090 + if (length <= aPos)
1.1091 + {
1.1092 + aRunLength = 0;
1.1093 + return;
1.1094 + }
1.1095 + TTestAttributes attr = iAttrs->At(aPos);
1.1096 + if (aLevel == ESpecific)
1.1097 + {
1.1098 + AttrToCharLayer(aFormat, attr);
1.1099 + }
1.1100 + else
1.1101 + {
1.1102 + AttrToCharLayer(aFormat, iBase);
1.1103 + MergeAttrToCharLayer(aFormat, attr);
1.1104 + }
1.1105 + TInt pos = aPos + 1;
1.1106 + while (pos < length && attr == iAttrs->At(pos))
1.1107 + ++pos;
1.1108 + aRunLength = pos - aPos;
1.1109 + }
1.1110 + void GetParFormatL(TInt aPos, TFormatLevel aLevel,
1.1111 + RTmParFormatLayer& aFormat, TInt& aRunLength) const
1.1112 + {
1.1113 + TInt length = DocumentLength();
1.1114 + if (length <= aPos)
1.1115 + {
1.1116 + aRunLength = 0;
1.1117 + return;
1.1118 + }
1.1119 + TTestAttributes attr = iAttrs->At(aPos);
1.1120 + if (aLevel == ESpecific)
1.1121 + {
1.1122 + AttrToParLayer(aFormat, attr);
1.1123 + }
1.1124 + else
1.1125 + {
1.1126 + AttrToParLayer(aFormat, iBase);
1.1127 + MergeAttrToParLayer(aFormat, attr);
1.1128 + }
1.1129 + TInt pos = aPos + 1;
1.1130 + while (pos < length && attr == iAttrs->At(pos))
1.1131 + ++pos;
1.1132 + aRunLength = pos - aPos;
1.1133 + }
1.1134 + TInt StyleCount() const { return iNumStyles; }
1.1135 + void GetStyle(TInt aPos, TPtrC& aName, TInt& aRunLength) const
1.1136 + {
1.1137 + TInt length = DocumentLength();
1.1138 + if (aPos < 0 || length <= aPos)
1.1139 + {
1.1140 + aName.Set(iStyleNames[0].Ptr(), 0);
1.1141 + aRunLength = 0;
1.1142 + return;
1.1143 + }
1.1144 + TInt styleNo = iAttrs->At(aPos).iStyle;
1.1145 + if (styleNo < 0)
1.1146 + aName.Set(iStyleNames[0].Ptr(), 0);
1.1147 + else
1.1148 + aName.Set(iStyleNames[styleNo]);
1.1149 + TInt pos = aPos + 1;
1.1150 + while (pos < length && iAttrs->At(pos).iStyle == styleNo)
1.1151 + ++pos;
1.1152 + aRunLength = pos - aPos;
1.1153 + return;
1.1154 + }
1.1155 + TInt GetStyleByNameL(const TDesC& aName, RTmStyle& aStyle) const
1.1156 + {
1.1157 + return GetStyleByIndexL(Style(aName), aStyle);
1.1158 + }
1.1159 + TInt GetStyleByIndexL(TInt aIndex, RTmStyle& aStyle) const
1.1160 + {
1.1161 + if (aIndex < 0 || iNumStyles <= aIndex)
1.1162 + return KErrNotFound;
1.1163 + aStyle.iName = iStyleNames[aIndex];
1.1164 + AttrToParLayer(aStyle.iParFormat, iStyles[aIndex]);
1.1165 + AttrToCharLayer(aStyle.iCharFormat, iStyles[aIndex]);
1.1166 + return KErrNone;
1.1167 + }
1.1168 + void CopyToStoreL(CStreamStore& aStore, CStreamDictionary& aDictionary,
1.1169 + TInt aPos, TInt aLength) const
1.1170 + {
1.1171 + ASSERT(aPos + aLength <= DocumentLength());
1.1172 + if (aLength <= 0)
1.1173 + return;
1.1174 + RStoreWriteStream stream;
1.1175 + TStreamId id = stream.CreateLC(aStore);
1.1176 + stream.WriteInt32L(aLength);
1.1177 + RBufReadStream input_stream(*iText, aPos * sizeof(TText));
1.1178 + TMemoryStreamUnicodeSource source(input_stream);
1.1179 + TUnicodeCompressor c;
1.1180 + c.CompressL(stream, source, KMaxTInt, aLength);
1.1181 + input_stream.Close();
1.1182 + stream.CommitL();
1.1183 + aDictionary.AssignL(KClipboardUidTypePlainText, id);
1.1184 + CleanupStack::PopAndDestroy(); // close stream
1.1185 +
1.1186 + // now write out formatting in our own bizarre format
1.1187 + //...
1.1188 + // in actual fact this probably wouldn't test that much, so I won't
1.1189 + // bother right now.
1.1190 + }
1.1191 + void PasteFromStoreL(const CStreamStore& aStore,
1.1192 + const CStreamDictionary& aDictionary, TInt aPos)
1.1193 + {
1.1194 + ASSERT(aPos <= DocumentLength());
1.1195 + TStreamId id = aDictionary.At(KClipboardUidTypePlainText);
1.1196 + RStoreReadStream stream;
1.1197 + stream.OpenLC(aStore, id);
1.1198 + TInt length = stream.ReadInt32L();
1.1199 + RBufWriteStream bufferStream;
1.1200 + bufferStream.Insert(*iText, aPos * sizeof(TText));
1.1201 + TMemoryStreamUnicodeSink sink(bufferStream);
1.1202 + TUnicodeExpander e;
1.1203 + e.ExpandL(sink, stream, length);
1.1204 + bufferStream.CommitL();
1.1205 + bufferStream.Close();
1.1206 + CleanupStack::PopAndDestroy(); // close stream
1.1207 +
1.1208 + // and if we get round to adding some formatting to the copy method,
1.1209 + // then we should deal with it here also
1.1210 + //...
1.1211 + // but not today. Just add the appropriate spaces into all the structures.
1.1212 + TTestAttributes attr;
1.1213 + iAttrs->InsertL(aPos, attr, length);
1.1214 + CUndoTestPicture* nullPic = 0;
1.1215 + iPics->InsertL(aPos, nullPic, length);
1.1216 + }
1.1217 + };
1.1218 +
1.1219 +CLogger& operator<<(CLogger& log, CTestEditor& ed) { ed.Print(log); return log; }
1.1220 +
1.1221 +// 1 - CCommandStack test
1.1222 +TInt ExecuteStackL(CCommandStack& a)
1.1223 + {
1.1224 + while (a.Top())
1.1225 + {
1.1226 + CSingleCommand* single = a.Top()->Single();
1.1227 + if (!single)
1.1228 + {
1.1229 + TESTPRINT(_L("CCommandStack : stack unexpectedly contained batches"));
1.1230 + a.Reset();
1.1231 + return 1;
1.1232 + }
1.1233 + single->ExecuteL();
1.1234 + delete single;
1.1235 + a.Pop();
1.1236 + }
1.1237 + return 0;
1.1238 + }
1.1239 +TInt CheckLog(CCheckingLogger& a)
1.1240 + {
1.1241 + if (a.Passed())
1.1242 + return 0;
1.1243 + TESTPRINT(_L("CCommandStack... : log failed"));
1.1244 + return 1;
1.1245 + }
1.1246 +TInt CheckTop(CCommandStack& aStack, CCommand* aTop)
1.1247 + {
1.1248 + if (aStack.Top() != aTop)
1.1249 + {
1.1250 + TESTPRINT(_L("CCommandStack : unexpected item at top of stack"));
1.1251 + return 1;
1.1252 + }
1.1253 + return 0;
1.1254 + }
1.1255 +TInt CheckCount(CCommandStack& aStack, TInt aExpectedCount)
1.1256 + {
1.1257 + if (aStack.Count() != aExpectedCount)
1.1258 + {
1.1259 + TESTPRINT(_L("CCommandStack : stack an unexpected size"));
1.1260 + return 1;
1.1261 + }
1.1262 + return 0;
1.1263 + }
1.1264 +TInt CheckPop(CCommandStack& aStack)
1.1265 + {
1.1266 + CCommand* check = aStack.Top();
1.1267 + if (aStack.Pop() != check)
1.1268 + {
1.1269 + TESTPRINT(_L("CCommandStack : Pop() does not match Top()"));
1.1270 + return 1;
1.1271 + }
1.1272 + return 0;
1.1273 + }
1.1274 +void AddStuffL(CCommandStack& aStack, TInt* aTarget, CLogger* aLog)
1.1275 + {
1.1276 + TInt startCount = aStack.Count();
1.1277 + CheckTop(aStack, 0);
1.1278 + aStack.PrepareToPushL(1);
1.1279 + CheckCount(aStack, startCount);
1.1280 + CheckTop(aStack, 0);
1.1281 + CheckCount(aStack, startCount);
1.1282 + CCommand* temp = CCommandIncProto::NewL(aTarget, aLog);
1.1283 + aStack.Push(temp);
1.1284 + CheckCount(aStack, startCount + 1);
1.1285 + CheckTop(aStack, temp);
1.1286 + aStack.PrepareToPushL(2);
1.1287 + CheckCount(aStack, startCount + 1);
1.1288 + CheckTop(aStack, temp);
1.1289 + CheckCount(aStack, startCount + 1);
1.1290 + CheckTop(aStack, temp);
1.1291 + aStack.PrepareToPushL(1);
1.1292 + aStack.PrepareToPushL(3);
1.1293 + CheckCount(aStack, startCount + 1);
1.1294 + CheckTop(aStack, temp);
1.1295 + temp = CCommandDecProto::NewL(aTarget, aLog);
1.1296 + CheckCount(aStack, startCount + 1);
1.1297 + aStack.Push(temp);
1.1298 + CheckCount(aStack, startCount + 2);
1.1299 + CheckTop(aStack, temp);
1.1300 + CheckTop(aStack, temp);
1.1301 + CheckCount(aStack, startCount + 2);
1.1302 + CheckTop(aStack, temp);
1.1303 + temp = CCommandIncProto::NewL(aTarget, aLog);
1.1304 + aStack.Push(temp);
1.1305 + CheckTop(aStack, temp);
1.1306 + CheckCount(aStack, startCount + 3);
1.1307 + aStack.PrepareToPushL(1);
1.1308 + CheckTop(aStack, temp);
1.1309 + aStack.PrepareToPushL(2);
1.1310 + CheckTop(aStack, temp);
1.1311 + temp = CCommandNegProto::NewL(aTarget, aLog);
1.1312 + CheckCount(aStack, startCount + 3);
1.1313 + aStack.Push(temp);
1.1314 + CheckCount(aStack, startCount + 4);
1.1315 + CheckTop(aStack, temp);
1.1316 + CheckCount(aStack, startCount + 4);
1.1317 + CheckTop(aStack, temp);
1.1318 + temp = CCommandIncProto::NewL(aTarget, aLog);
1.1319 + CheckCount(aStack, startCount + 4);
1.1320 + aStack.Push(temp);
1.1321 + CheckTop(aStack, temp);
1.1322 + CheckCount(aStack, startCount + 5);
1.1323 + }
1.1324 +void TestCCommandStackL()
1.1325 + {
1.1326 + __UHEAP_MARK;
1.1327 + TInt target;
1.1328 + CCheckingLogger* log = new(ELeave) CCheckingLogger;
1.1329 +
1.1330 + CCommandStack* stack = CCommandStack::NewL();
1.1331 +
1.1332 + AddStuffL(*stack, &target, log);
1.1333 +
1.1334 + log->SetCheckString(_L("inc<>neg<>inc<>dec<>inc<>"));
1.1335 + ExecuteStackL(*stack);
1.1336 + CheckLog(*log);
1.1337 +
1.1338 + CheckCount(*stack, 0);
1.1339 + CCommand* temp = CCommandIncProto::NewL(&target, log);
1.1340 + CheckTop(*stack, 0);
1.1341 + stack->PrepareToPushL(1);
1.1342 + CheckCount(*stack, 0);
1.1343 + CheckTop(*stack, 0);
1.1344 + CheckCount(*stack, 0);
1.1345 + stack->Push(temp);
1.1346 + CheckCount(*stack, 1);
1.1347 + stack->PrepareToPushL(1);
1.1348 + CheckCount(*stack, 1);
1.1349 + CCommand* next = CCommandDecProto::NewL(&target, log);
1.1350 + stack->Push(next);
1.1351 + CheckCount(*stack, 2);
1.1352 + stack->PrepareToPushL(1);
1.1353 + CheckPop(*stack);
1.1354 + stack->PrepareToPushL(1);
1.1355 + CheckCount(*stack, 1);
1.1356 + CheckTop(*stack, temp);
1.1357 + CheckCount(*stack, 1);
1.1358 + stack->Push(next);
1.1359 + stack->PrepareToPushL(1);
1.1360 + CheckCount(*stack, 2);
1.1361 + CheckCount(*stack, 2);
1.1362 + CheckPop(*stack);
1.1363 + CheckCount(*stack, 1);
1.1364 + CheckTop(*stack, temp);
1.1365 + delete next;
1.1366 +
1.1367 + stack->Reset();
1.1368 + CheckCount(*stack, 0);
1.1369 +
1.1370 + AddStuffL(*stack, &target, log);
1.1371 + stack->PruneTo(3);
1.1372 + CheckCount(*stack, 3);
1.1373 + log->SetCheckString(_L("inc<>neg<>inc<>"));
1.1374 + ExecuteStackL(*stack);
1.1375 + CheckLog(*log);
1.1376 +
1.1377 + AddStuffL(*stack, &target, log);
1.1378 + stack->PrepareToPushL(1);
1.1379 + CheckCount(*stack, 5);
1.1380 + stack->PruneTo(2);
1.1381 + CheckCount(*stack, 2);
1.1382 + log->SetCheckString(_L("inc<>neg<>"));
1.1383 + ExecuteStackL(*stack);
1.1384 + CheckLog(*log);
1.1385 +
1.1386 + delete stack;
1.1387 + delete log;
1.1388 +
1.1389 + __UHEAP_MARKENDC(0);
1.1390 + }
1.1391 +
1.1392 +// 2 - CBatchCommand test
1.1393 +void ExecuteBatchL(CBatchCommand& a)
1.1394 + {
1.1395 + while (a.Top())
1.1396 + {
1.1397 + CSingleCommand* single = a.Top();
1.1398 + single->ExecuteL();
1.1399 + if (a.Pop() != single)
1.1400 + {
1.1401 + TESTPRINT(_L("CBatchCommand : Pop() didn't match Top()"));
1.1402 + TESTPOINT(0);
1.1403 + }
1.1404 + delete single;
1.1405 + }
1.1406 + TESTPOINT(1);
1.1407 + }
1.1408 +void CheckTop(CBatchCommand& aBatch, CCommand* aTop)
1.1409 + {
1.1410 + if (aBatch.Top() != aTop)
1.1411 + {
1.1412 + TESTPRINT(_L("CCommandBatch : unexpected item at top of stack"));
1.1413 + TESTPOINT(0);
1.1414 + }
1.1415 + TESTPOINT(1);
1.1416 + }
1.1417 +void TestCBatchCommandL()
1.1418 + {
1.1419 + __UHEAP_MARK;
1.1420 + TInt target = 0;
1.1421 + CCheckingLogger* log = new(ELeave) CCheckingLogger;
1.1422 +
1.1423 + CBatchCommand* batch = CBatchCommand::NewL();
1.1424 +
1.1425 + CBatchCommand* b1 = CBatchCommand::NewL();
1.1426 + CBatchCommand* b2 = CBatchCommand::NewL();
1.1427 + CBatchCommand* b3 = CBatchCommand::NewL();
1.1428 +
1.1429 + CCommand* s1 = CCommandIncProto::NewL(&target, log);
1.1430 + CCommand* s2 = CCommandDecProto::NewL(&target, log);
1.1431 + CCommand* s3 = CCommandNegProto::NewL(&target, log);
1.1432 + CCommand* s4 = CCommandIncProto::NewL(&target, log);
1.1433 + CCommand* s5 = CCommandDecProto::NewL(&target, log);
1.1434 + CCommand* s6 = CCommandNegProto::NewL(&target, log);
1.1435 + CCommand* s7 = CCommandIncProto::NewL(&target, log);
1.1436 + CCommand* s8 = CCommandDecProto::NewL(&target, log);
1.1437 + CCommand* s9 = CCommandNegProto::NewL(&target, log);
1.1438 +
1.1439 + b2->PrepareToPushL(s4);
1.1440 + b2->Push(s4);
1.1441 + b2->PrepareToPushL(s8);
1.1442 + b2->Push(s8);
1.1443 + b2->PrepareToPushL(s2);
1.1444 + b2->PrepareToPushL(s2);
1.1445 + b2->Push(s2);
1.1446 +
1.1447 + b3->PrepareToPushL(s3);
1.1448 + b3->PrepareToPushL(s9);
1.1449 + b3->Push(s9);
1.1450 + b3->PrepareToPushL(s3);
1.1451 + b3->Push(s3);
1.1452 + b3->PrepareToPushL(s7);
1.1453 + b3->Push(s7);
1.1454 +
1.1455 + b1->PrepareToPushL(s6);
1.1456 + b1->Push(s6);
1.1457 + b1->PrepareToPushL(s5);
1.1458 + b1->Push(s5);
1.1459 + b1->PrepareToPushL(b3);
1.1460 + b1->Push(b3);
1.1461 + b1->PrepareToPushL(b1);
1.1462 + b1->PrepareToPushL(s1);
1.1463 + b1->PrepareToPushL(s1);
1.1464 + b1->PrepareToPushL(b2);
1.1465 +
1.1466 + batch->PrepareToPushL(b2);
1.1467 + batch->Push(b2);
1.1468 + batch->PrepareToPushL(s1);
1.1469 + batch->PrepareToPushL(s1);
1.1470 + batch->PrepareToPushL(b1);
1.1471 + batch->Push(b1);
1.1472 + batch->PrepareToPushL(s1);
1.1473 + batch->Push(s1);
1.1474 +
1.1475 + CheckTop(*batch, s1);
1.1476 + batch->Pop();
1.1477 + CheckTop(*batch, s7);
1.1478 + batch->PrepareToPushL(s1);
1.1479 + CheckTop(*batch, s7);
1.1480 + batch->Push(s1);
1.1481 + CheckTop(*batch, s1);
1.1482 + batch->PrepareToPushL(s1);
1.1483 + CheckTop(*batch, s1);
1.1484 + batch->Pop();
1.1485 + CheckTop(*batch, s7);
1.1486 + batch->Pop();
1.1487 + CheckTop(*batch, s3);
1.1488 + batch->Pop();
1.1489 + CheckTop(*batch, s9);
1.1490 + batch->Pop();
1.1491 + CheckTop(*batch, s5);
1.1492 + batch->Pop();
1.1493 + CheckTop(*batch, s6);
1.1494 + batch->PrepareToPushL(s5);
1.1495 + CheckTop(*batch, s6);
1.1496 + batch->Push(s5);
1.1497 + CheckTop(*batch, s5);
1.1498 + b3 = CBatchCommand::NewL();
1.1499 + b3->PrepareToPushL(s9);
1.1500 + CheckTop(*b3, 0);
1.1501 + b3->Push(s9);
1.1502 + CheckTop(*b3, s9);
1.1503 + b3->PrepareToPushL(s3);
1.1504 + CheckTop(*b3, s9);
1.1505 + b3->Push(s3);
1.1506 + CheckTop(*b3, s3);
1.1507 + b3->PrepareToPushL(s7);
1.1508 + CheckTop(*b3, s3);
1.1509 + b3->Push(s7);
1.1510 + CheckTop(*b3, s7);
1.1511 + batch->PrepareToPushL(b3);
1.1512 + CheckTop(*batch, s5);
1.1513 + batch->Push(b3);
1.1514 + CheckTop(*batch, s7);
1.1515 + batch->PrepareToPushL(s1);
1.1516 + batch->Push(s1);
1.1517 +
1.1518 + log->SetCheckString(_L("inc<>inc<>neg<>neg<>dec<>neg<>dec<>dec<>inc<>"));
1.1519 + ExecuteBatchL(*batch);
1.1520 + CheckLog(*log);
1.1521 +
1.1522 + delete log;
1.1523 + delete batch;
1.1524 +
1.1525 + __UHEAP_MARKENDC(0);
1.1526 + }
1.1527 +
1.1528 +// 3 - CCommandHistory test
1.1529 +void ExecuteHistoryL(CCommandHistory& aHistory, CLogger& aLog)
1.1530 + {
1.1531 + while (aHistory.Top())
1.1532 + {
1.1533 + if (aHistory.Top()->Single())
1.1534 + {
1.1535 + aHistory.Top()->Single()->ExecuteL();
1.1536 + }
1.1537 + else
1.1538 + {
1.1539 + CBatchCommand* batch = aHistory.Top()->Batch();
1.1540 + TESTPOINT(batch != 0);
1.1541 + aLog << _L("batch{");
1.1542 + ExecuteBatchL(*batch);
1.1543 + aLog << _L("}");
1.1544 + }
1.1545 + delete aHistory.Pop();
1.1546 + }
1.1547 + }
1.1548 +void TestCCommandHistoryL()
1.1549 + {
1.1550 + __UHEAP_MARK;
1.1551 +
1.1552 + CCommandHistory* history = CCommandHistory::NewL();
1.1553 + CCheckingLogger* log = new(ELeave) CCheckingLogger;
1.1554 + TInt target;
1.1555 +
1.1556 + CCommand* p;
1.1557 + history->SetMaxItems(5);
1.1558 + p = CCommandDecProto::NewL(&target, log);
1.1559 + history->PrepareToAddCommandL(p);
1.1560 + history->AddCommand(p);
1.1561 + p = CCommandIncProto::NewL(&target, log);
1.1562 + history->PrepareToAddCommandL(p);
1.1563 + history->AddCommand(p);
1.1564 + p = CCommandDecProto::NewL(&target, log);
1.1565 + history->PrepareToAddCommandL(p);
1.1566 + history->AddCommand(p);
1.1567 + p = CCommandNegProto::NewL(&target, log);
1.1568 + history->PrepareToAddCommandL(p);
1.1569 + history->AddCommand(p);
1.1570 + history->BeginBatchLC();
1.1571 + p = CCommandIncProto::NewL(&target, log);
1.1572 + history->PrepareToAddCommandL(p);
1.1573 + history->AddCommand(p);
1.1574 + p = CCommandDecProto::NewL(&target, log);
1.1575 + history->PrepareToAddCommandL(p);
1.1576 + history->AddCommand(p);
1.1577 + p = CCommandNegProto::NewL(&target, log);
1.1578 + history->PrepareToAddCommandL(p);
1.1579 + history->AddCommand(p);
1.1580 + CleanupStack::PopAndDestroy();
1.1581 + p = CCommandDecProto::NewL(&target, log);
1.1582 + history->PrepareToAddCommandL(p);
1.1583 + history->AddCommand(p);
1.1584 + CBatchCommand* batch = CBatchCommand::NewL();
1.1585 + p = CCommandDecProto::NewL(&target, log);
1.1586 + batch->PrepareToPushL(p);
1.1587 + batch->Push(p);
1.1588 + p = CCommandNegProto::NewL(&target, log);
1.1589 + batch->PrepareToPushL(p);
1.1590 + batch->Push(p);
1.1591 + p = CCommandIncProto::NewL(&target, log);
1.1592 + batch->PrepareToPushL(p);
1.1593 + batch->Push(p);
1.1594 + history->PrepareToAddCommandL(batch);
1.1595 + history->AddCommand(batch);
1.1596 + p = CCommandNegProto::NewL(&target, log);
1.1597 + history->PrepareToAddCommandL(p);
1.1598 + history->AddCommand(p);
1.1599 +
1.1600 + log->SetCheckString(_L("neg<>batch{inc<>neg<>dec<>}dec<>batch{neg<>dec<>inc<>}neg<>"));
1.1601 + ExecuteHistoryL(*history, *log);
1.1602 + CheckLog(*log);
1.1603 +
1.1604 + delete log;
1.1605 + delete history;
1.1606 +
1.1607 + __UHEAP_MARKENDC(0);
1.1608 + }
1.1609 +
1.1610 +// 4 - CCommandManager test
1.1611 +void TestCanUndo(const CCommandManager& aMan)
1.1612 + {
1.1613 + if (aMan.CanUndo())
1.1614 + {
1.1615 + TESTPOINT(1);
1.1616 + return;
1.1617 + }
1.1618 + TESTPRINT(_L("CCommandManager : unexpectedly could not undo"));
1.1619 + TESTPOINT(0);
1.1620 + }
1.1621 +void TestCanRedo(const CCommandManager& aMan)
1.1622 + {
1.1623 + if (aMan.CanRedo())
1.1624 + {
1.1625 + TESTPOINT(1);
1.1626 + return;
1.1627 + }
1.1628 + TESTPRINT(_L("CCommandManager : unexpectedly could not redo"));
1.1629 + TESTPOINT(0);
1.1630 + }
1.1631 +void TestCannotUndo(const CCommandManager& aMan)
1.1632 + {
1.1633 + if (!aMan.CanUndo())
1.1634 + {
1.1635 + TESTPOINT(1);
1.1636 + return;
1.1637 + }
1.1638 + TESTPRINT(_L("CCommandManager : unexpectedly could undo"));
1.1639 + TESTPOINT(0);
1.1640 + }
1.1641 +void TestCannotRedo(const CCommandManager& aMan)
1.1642 + {
1.1643 + if (!aMan.CanRedo())
1.1644 + {
1.1645 + TESTPOINT(1);
1.1646 + return;
1.1647 + }
1.1648 + TESTPRINT(_L("CCommandManager : unexpectedly could undo"));
1.1649 + TESTPOINT(0);
1.1650 + }
1.1651 +void SetUpTestL(CCommandManager& aMan, CSingleCommand& aCommand, TInt* aTarget, CLogger* aLogger)
1.1652 + {
1.1653 + CCommandIncProto* inc = CCommandIncProto::NewL(aTarget, aLogger);
1.1654 + CleanupStack::PushL(inc);
1.1655 + CCommandNegProto* neg = CCommandNegProto::NewL(aTarget, aLogger);
1.1656 + CleanupStack::PushL(neg);
1.1657 + CCommandDecProto* dec = CCommandDecProto::NewL(aTarget, aLogger);
1.1658 + CleanupStack::PushL(dec);
1.1659 +
1.1660 + aMan.ExecuteL(*inc);
1.1661 + aMan.BeginBatchLC();
1.1662 + aMan.ExecuteL(*neg);
1.1663 + aMan.ExecuteL(aCommand);
1.1664 + aMan.ExecuteL(*dec);
1.1665 + CleanupStack::PopAndDestroy(); // close batch
1.1666 + aMan.ExecuteL(*neg);
1.1667 + aMan.UndoL();
1.1668 +
1.1669 + CleanupStack::PopAndDestroy(dec);
1.1670 + CleanupStack::PopAndDestroy(neg);
1.1671 + CleanupStack::PopAndDestroy(inc);
1.1672 + }
1.1673 +TInt CheckErrorCode(TInt aErr, TInt aExpected)
1.1674 + {
1.1675 + if (aErr == aExpected)
1.1676 + return 0;
1.1677 + if (aErr == KErrNone)
1.1678 + TESTPRINT(_L("CCommandManager : no leave where one was expected"));
1.1679 + else
1.1680 + TESTPRINT(_L("CCommandManager : unexpected leave code"));
1.1681 + return 1;
1.1682 + }
1.1683 +void TestCCommandManagerL()
1.1684 + {
1.1685 + __UHEAP_MARK;
1.1686 +
1.1687 + CCommandManager* manager = CCommandManager::NewL();
1.1688 + CCheckingLogger* log = new(ELeave) CCheckingLogger;
1.1689 + TInt target = 0;
1.1690 + CRefuserGatekeeper* refuser = new(ELeave) CRefuserGatekeeper;
1.1691 + CPermitterGatekeeper* permitter = new(ELeave) CPermitterGatekeeper;
1.1692 + CMemoryReclaimGatekeeper* reclaimer = new(ELeave) CMemoryReclaimGatekeeper;
1.1693 +
1.1694 + TestCannotUndo(*manager);
1.1695 + TestCannotRedo(*manager);
1.1696 +
1.1697 + CCommandIncProto* inc = CCommandIncProto::NewL(&target, log);
1.1698 + CCommandDecProto* dec = CCommandDecProto::NewL(&target, log);
1.1699 + CCommandNegProto* neg = CCommandNegProto::NewL(&target, log);
1.1700 +
1.1701 + log->SetCheckString(_L("inc<>neg<>inc<>dec<>neg<>negate<1>"));
1.1702 + SetUpTestL(*manager, *inc, &target, log);
1.1703 + CheckLog(*log);
1.1704 + TestCanUndo(*manager);
1.1705 + TestCanRedo(*manager);
1.1706 + log->SetCheckString(_L("offset<0>negate<1>"));
1.1707 + manager->UndoL();
1.1708 + CheckLog(*log);
1.1709 + TestCanUndo(*manager);
1.1710 + TestCanRedo(*manager);
1.1711 + log->SetCheckString(_L("offset<-1>"));
1.1712 + manager->UndoL();
1.1713 + CheckLog(*log);
1.1714 + TestCannotUndo(*manager);
1.1715 + TestCanRedo(*manager);
1.1716 + log->SetCheckString(_L("offset<1>"));
1.1717 + manager->RedoL();
1.1718 + CheckLog(*log);
1.1719 + TestCanUndo(*manager);
1.1720 + TestCanRedo(*manager);
1.1721 + log->SetCheckString(_L("negate<1>offset<0>"));
1.1722 + manager->RedoL();
1.1723 + CheckLog(*log);
1.1724 + TestCanUndo(*manager);
1.1725 + TestCanRedo(*manager);
1.1726 + log->SetCheckString(_L("negate<1>"));
1.1727 + manager->RedoL();
1.1728 + CheckLog(*log);
1.1729 + TestCanUndo(*manager);
1.1730 + TestCannotRedo(*manager);
1.1731 + log->SetCheckString(_L("negate<1>"));
1.1732 + manager->UndoL();
1.1733 + CheckLog(*log);
1.1734 + TestCanUndo(*manager);
1.1735 + TestCanRedo(*manager);
1.1736 + log->SetCheckString(_L("inc<>"));
1.1737 + manager->ExecuteL(*inc);
1.1738 + CheckLog(*log);
1.1739 + TestCanUndo(*manager);
1.1740 + TestCannotRedo(*manager);
1.1741 + log->SetCheckString(_L("offset<-1>negate<1>"));
1.1742 + manager->UndoL();
1.1743 + CheckLog(*log);
1.1744 + TestCanUndo(*manager);
1.1745 + TestCanRedo(*manager);
1.1746 + log->SetCheckString(_L("negate<1>offset<1>"));
1.1747 + manager->RedoL();
1.1748 + CheckLog(*log);
1.1749 + TestCanUndo(*manager);
1.1750 + TestCannotRedo(*manager);
1.1751 +
1.1752 + manager->ResetUndo();
1.1753 + TestCannotUndo(*manager);
1.1754 + TestCannotRedo(*manager);
1.1755 +
1.1756 + // test coalescence
1.1757 +
1.1758 + log->SetCheckString(_L("inc<>inc<>inc<>inc<>inc<>inc<>"));
1.1759 +
1.1760 + manager->ExecuteL(*inc);
1.1761 + manager->ExecuteL(*inc);
1.1762 + manager->BeginBatchLC();
1.1763 + manager->ExecuteL(*inc);
1.1764 + manager->ExecuteL(*inc);
1.1765 + CleanupStack::PopAndDestroy(); // close batch
1.1766 + manager->ExecuteL(*inc);
1.1767 + manager->ExecuteL(*inc);
1.1768 + CheckLog(*log);
1.1769 +
1.1770 + log->SetCheckString(_L("offset<-4>offset<-2>"));
1.1771 + manager->UndoL();
1.1772 + manager->UndoL();
1.1773 + CheckLog(*log);
1.1774 +
1.1775 + log->SetCheckString(_L("offset<2>offset<4>"));
1.1776 + manager->RedoL();
1.1777 + manager->RedoL();
1.1778 + TestCannotRedo(*manager);
1.1779 + CheckLog(*log);
1.1780 +
1.1781 + manager->ResetUndo();
1.1782 + TestCannotUndo(*manager);
1.1783 + TestCannotRedo(*manager);
1.1784 +
1.1785 + // test command with batch inverse
1.1786 + log->SetCheckString(_L("inc<>decneg<>inc<>"));
1.1787 + CCommandDecThenNegProto* dnp = CCommandDecThenNegProto::NewL(&target, log);
1.1788 + manager->ExecuteL(*inc);
1.1789 + manager->ExecuteL(*dnp);
1.1790 + manager->ExecuteL(*inc);
1.1791 + CheckLog(*log);
1.1792 + delete dnp;
1.1793 + log->SetCheckString(_L("offset<-1>"));
1.1794 + manager->UndoL();
1.1795 + CheckLog(*log);
1.1796 + log->SetCheckString(_L("negate<1>offset<1>"));
1.1797 + manager->UndoL();
1.1798 + CheckLog(*log);
1.1799 + log->SetCheckString(_L("offset<-1>"));
1.1800 + manager->UndoL();
1.1801 + CheckLog(*log);
1.1802 + manager->ResetUndo();
1.1803 +
1.1804 + // Test case when undo is not supported
1.1805 + // 1. execution is permitted
1.1806 + log->SetCheckString(_L("inc<>neg<>noinvfail.noinv<>dec<>neg<>negate<1>"));
1.1807 + CCommandCannotInvert* noInv = CCommandCannotInvert::NewL(log);
1.1808 + SetUpTestL(*manager, *noInv, &target, log);
1.1809 + CheckLog(*log);
1.1810 + TestCannotUndo(*manager);
1.1811 + log->SetCheckString(_L("negate<1>"));
1.1812 + manager->RedoL();
1.1813 + CheckLog(*log);
1.1814 + TestCannotRedo(*manager);
1.1815 + manager->ResetUndo();
1.1816 +
1.1817 + //2. execution is supressed
1.1818 + manager->SetGatekeeper(refuser);
1.1819 + log->SetCheckString(_L("inc<>neg<>noinvfail.dec<>neg<>negate<1>"));
1.1820 + SetUpTestL(*manager, *noInv, &target, log);
1.1821 + CheckLog(*log);
1.1822 + delete noInv;
1.1823 + log->SetCheckString(_L("offset<1>negate<1>"));
1.1824 + manager->UndoL();
1.1825 + CheckLog(*log);
1.1826 + log->SetCheckString(_L("offset<-1>"));
1.1827 + manager->UndoL();
1.1828 + CheckLog(*log);
1.1829 + TestCannotUndo(*manager);
1.1830 + manager->ResetUndo();
1.1831 + manager->SetGatekeeper(0);
1.1832 +
1.1833 + // Test case when execution fails (with returned error code)
1.1834 + CCommandCannotDo* noDo = CCommandCannotDo::NewL(log);
1.1835 + log->SetCheckString(_L("inc<>neg<>nodo<>dec<>neg<>negate<1>"));
1.1836 + SetUpTestL(*manager, *noDo, &target, log);
1.1837 + delete noDo;
1.1838 + log->SetCheckString(_L("offset<1>negate<1>"));
1.1839 + manager->UndoL();
1.1840 + CheckLog(*log);
1.1841 + log->SetCheckString(_L("offset<-1>"));
1.1842 + manager->UndoL();
1.1843 + CheckLog(*log);
1.1844 + TestCannotUndo(*manager);
1.1845 + manager->ResetUndo();
1.1846 +
1.1847 + // Test case when inversion fails (not inversion is reported as impossible)
1.1848 + // 1. when execution is permitted
1.1849 + manager->SetGatekeeper(permitter);
1.1850 + log->SetCheckString(_L("inc<>neg<>noinvfail.leaveinv<>dec<>neg<>negate<1>"));
1.1851 + CCommandLeavesInvert* leaveInv = CCommandLeavesInvert::NewL(log);
1.1852 + SetUpTestL(*manager, *leaveInv, &target, log);
1.1853 + CheckLog(*log);
1.1854 + TestCannotUndo(*manager);
1.1855 + log->SetCheckString(_L("negate<1>"));
1.1856 + manager->RedoL();
1.1857 + CheckLog(*log);
1.1858 + TestCannotRedo(*manager);
1.1859 + manager->ResetUndo();
1.1860 +
1.1861 + // 2. when execution is supressed
1.1862 + manager->SetGatekeeper(refuser);
1.1863 + log->SetCheckString(_L("inc<>neg<>noinvfail.dec<>neg<>negate<1>"));
1.1864 + leaveInv->iFail = ETrue;
1.1865 + TRAPD(err, SetUpTestL(*manager, *leaveInv, &target, log));
1.1866 + CheckErrorCode(err, KErrNone);
1.1867 + CheckLog(*log);
1.1868 + log->SetCheckString(_L("offset<1>negate<1>"));
1.1869 + manager->UndoL();
1.1870 + CheckLog(*log);
1.1871 + log->SetCheckString(_L("offset<-1>"));
1.1872 + manager->UndoL();
1.1873 + CheckLog(*log);
1.1874 + TestCannotUndo(*manager);
1.1875 + manager->ResetUndo();
1.1876 +
1.1877 + // 3. when execution is terminated by leaving
1.1878 + manager->SetGatekeeper(0);
1.1879 + log->SetCheckString(_L("inc<>neg<>noinvfail."));
1.1880 + leaveInv->iFail = ETrue;
1.1881 + TRAP(err, SetUpTestL(*manager, *leaveInv, &target, log));
1.1882 + CheckErrorCode(err, KErrNotFound);
1.1883 + CheckLog(*log);
1.1884 + delete leaveInv;
1.1885 + log->SetCheckString(_L("negate<1>"));
1.1886 + manager->UndoL();
1.1887 + CheckLog(*log);
1.1888 + log->SetCheckString(_L("offset<-1>"));
1.1889 + manager->UndoL();
1.1890 + CheckLog(*log);
1.1891 + TestCannotUndo(*manager);
1.1892 + manager->ResetUndo();
1.1893 +
1.1894 + // Test case when inversion runs out of memory
1.1895 + // 1. when execution is permitted with no undo
1.1896 + manager->SetGatekeeper(permitter);
1.1897 + log->SetCheckString(_L("inc<>neg<>nomemfailadd.nomem<>dec<>neg<>negate<1>"));
1.1898 + CCommandNoMemory* noMem = CCommandNoMemory::NewL(log);
1.1899 + noMem->iFailExecute = EFalse;
1.1900 + SetUpTestL(*manager, *noMem, &target, log);
1.1901 + CheckLog(*log);
1.1902 + TestCannotUndo(*manager);
1.1903 + log->SetCheckString(_L("negate<1>"));
1.1904 + manager->RedoL();
1.1905 + CheckLog(*log);
1.1906 + TestCannotRedo(*manager);
1.1907 + manager->ResetUndo();
1.1908 +
1.1909 + // 2. when execution is supressed
1.1910 + manager->SetGatekeeper(refuser);
1.1911 + log->SetCheckString(_L("inc<>neg<>nomemfailadd.dec<>neg<>negate<1>"));
1.1912 + TRAP(err, SetUpTestL(*manager, *noMem, &target, log));
1.1913 + CheckErrorCode(err, KErrNone);
1.1914 + CheckLog(*log);
1.1915 + log->SetCheckString(_L("offset<1>negate<1>"));
1.1916 + manager->UndoL();
1.1917 + CheckLog(*log);
1.1918 + log->SetCheckString(_L("offset<-1>"));
1.1919 + manager->UndoL();
1.1920 + CheckLog(*log);
1.1921 + TestCannotUndo(*manager);
1.1922 + manager->ResetUndo();
1.1923 + manager->SetGatekeeper(0);
1.1924 +
1.1925 + // 3. when memory is reclaimed
1.1926 + reclaimer->iTarget = noMem;
1.1927 + manager->SetGatekeeper(reclaimer);
1.1928 + log->SetCheckString(_L("inc<>neg<>nomemfailadd.nomemfailinv.nomem<>dec<>neg<>negate<1>"));
1.1929 + TRAP(err, SetUpTestL(*manager, *noMem, &target, log));
1.1930 + CheckErrorCode(err, KErrNone);
1.1931 + CheckLog(*log);
1.1932 + log->SetCheckString(_L("offset<1>negate<1>"));
1.1933 + manager->UndoL();
1.1934 + CheckLog(*log);
1.1935 + log->SetCheckString(_L("offset<-1>"));
1.1936 + manager->UndoL();
1.1937 + CheckLog(*log);
1.1938 + TestCannotUndo(*manager);
1.1939 + manager->ResetUndo();
1.1940 + manager->SetGatekeeper(0);
1.1941 +
1.1942 + // Test when execution runs out of memory
1.1943 + // 1. with no reclaimation
1.1944 + noMem->iFailAddToLast = EFalse;
1.1945 + noMem->iFailInvert = EFalse;
1.1946 + noMem->iFailExecute = ETrue;
1.1947 + noMem->iLogExecuteFailed= ETrue;
1.1948 + log->SetCheckString(_L("inc<>neg<>nomemfailexe."));
1.1949 + TRAP(err, SetUpTestL(*manager, *noMem, &target, log));
1.1950 + CheckErrorCode(err, KErrNoMemory);
1.1951 + CheckLog(*log);
1.1952 + TestCannotRedo(*manager);
1.1953 + log->SetCheckString(_L("negate<1>"));
1.1954 + manager->UndoL();
1.1955 + CheckLog(*log);
1.1956 + log->SetCheckString(_L("offset<-1>"));
1.1957 + manager->UndoL();
1.1958 + CheckLog(*log);
1.1959 + TestCannotUndo(*manager);
1.1960 + manager->ResetUndo();
1.1961 + // 2. with reclaimation
1.1962 + noMem->iFailAddToLast = EFalse;
1.1963 + noMem->iFailInvert = EFalse;
1.1964 + noMem->iFailExecute = ETrue;
1.1965 + noMem->iLogExecuteFailed= ETrue;
1.1966 + reclaimer->iTarget = noMem;
1.1967 + manager->SetGatekeeper(reclaimer);
1.1968 + log->SetCheckString(_L("inc<>neg<>nomemfailexe.nomem<>dec<>neg<>negate<1>"));
1.1969 + TRAP(err, SetUpTestL(*manager, *noMem, &target, log));
1.1970 + CheckErrorCode(err, KErrNone);
1.1971 + CheckLog(*log);
1.1972 + log->SetCheckString(_L("offset<1>negate<1>"));
1.1973 + manager->UndoL();
1.1974 + CheckLog(*log);
1.1975 + log->SetCheckString(_L("offset<-1>"));
1.1976 + manager->UndoL();
1.1977 + CheckLog(*log);
1.1978 + TestCannotUndo(*manager);
1.1979 + manager->ResetUndo();
1.1980 + manager->SetGatekeeper(0);
1.1981 + delete noMem;
1.1982 +
1.1983 + delete inc;
1.1984 + delete dec;
1.1985 + delete neg;
1.1986 + delete reclaimer;
1.1987 + delete refuser;
1.1988 + delete permitter;
1.1989 + delete log;
1.1990 + manager->Release();
1.1991 +
1.1992 + __UHEAP_MARKENDC(0);
1.1993 + }
1.1994 +
1.1995 +//
1.1996 +//
1.1997 +// Tests involving CTestEditor
1.1998 +//
1.1999 +//
1.2000 +
1.2001 +void CheckEditorLog(CCheckingLogger& a)
1.2002 + {
1.2003 + if (a.Passed())
1.2004 + {
1.2005 + TESTPOINT(1);
1.2006 + return;
1.2007 + }
1.2008 + TESTPRINT(_L("EditorUndo : log failed"));
1.2009 + TESTPOINT(0);
1.2010 + }
1.2011 +
1.2012 +void TestPlainText(CTestEditor& aTestEditor, MUnifiedEditor& aUndoEditor,
1.2013 + CCommandManager& aCommandManager)
1.2014 + {
1.2015 + CCheckingLogger* check = new(ELeave) CCheckingLogger;
1.2016 + CStoringLogger* log = new(ELeave) CStoringLogger;
1.2017 +
1.2018 + //
1.2019 + // general inserting and deleting text
1.2020 + //
1.2021 + aUndoEditor.InsertTextL(0, _L("Hello world!"), 0, 0, 0);
1.2022 +
1.2023 + aCommandManager.ResetUndo();
1.2024 +
1.2025 + aTestEditor.Print(*log);
1.2026 + HBufC* helloWorldLog = log->GetStore();
1.2027 +
1.2028 + check->SetCheckString(*helloWorldLog);
1.2029 + aTestEditor.Print(*check);
1.2030 + CheckEditorLog(*check);
1.2031 + aUndoEditor.InsertTextL(5, _L(" lovely"), 0, 0, 0);
1.2032 + aTestEditor.Print(*log);
1.2033 + HBufC* helloLovelyWorldLog = log->GetStore();
1.2034 + aUndoEditor.DeleteTextL(10, 8);
1.2035 + aTestEditor.Print(*log);
1.2036 + HBufC* helloLoveLog = log->GetStore();
1.2037 + aCommandManager.UndoL();
1.2038 + check->SetCheckString(*helloLovelyWorldLog);
1.2039 + aTestEditor.Print(*check);
1.2040 + CheckEditorLog(*check);
1.2041 + aCommandManager.UndoL();
1.2042 + check->SetCheckString(*helloWorldLog);
1.2043 + aTestEditor.Print(*check);
1.2044 + CheckEditorLog(*check);
1.2045 + aCommandManager.RedoL();
1.2046 + check->SetCheckString(*helloLovelyWorldLog);
1.2047 + aTestEditor.Print(*check);
1.2048 + CheckEditorLog(*check);
1.2049 + aCommandManager.RedoL();
1.2050 + check->SetCheckString(*helloLoveLog);
1.2051 + aTestEditor.Print(*check);
1.2052 + CheckEditorLog(*check);
1.2053 + aCommandManager.UndoL();
1.2054 + check->SetCheckString(*helloLovelyWorldLog);
1.2055 + aTestEditor.Print(*check);
1.2056 + CheckEditorLog(*check);
1.2057 + aCommandManager.UndoL();
1.2058 + check->SetCheckString(*helloWorldLog);
1.2059 + aTestEditor.Print(*check);
1.2060 + CheckEditorLog(*check);
1.2061 +
1.2062 + aUndoEditor.InsertTextL(6, _L("w"), 0, 0, 0);
1.2063 + aUndoEditor.InsertTextL(7, _L("h"), 0, 0, 0);
1.2064 + aUndoEditor.InsertTextL(8, _L("at's"), 0, 0, 0);
1.2065 + aUndoEditor.InsertTextL(12, _L(" "), 0, 0, 0);
1.2066 + aUndoEditor.InsertTextL(13, _L("w"), 0, 0, 0);
1.2067 + aUndoEditor.InsertTextL(14, _L("i"), 0, 0, 0);
1.2068 + aUndoEditor.InsertTextL(6, _L("there "), 0, 0, 0);
1.2069 + aUndoEditor.InsertTextL(21, _L("t"), 0, 0, 0);
1.2070 + aUndoEditor.InsertTextL(22, _L("h"), 0, 0, 0);
1.2071 + aUndoEditor.InsertTextL(23, _L(" "), 0, 0, 0);
1.2072 + aTestEditor.Print(*log);
1.2073 + HBufC* textLog0 = log->GetStore();
1.2074 + aUndoEditor.InsertTextL(24, _L("the"), 0, 0, 0); // first of next
1.2075 + aUndoEditor.InsertTextL(27, _L(" "), 0, 0, 0);
1.2076 + aUndoEditor.InsertTextL(28, _L("d "), 0, 0, 0);
1.2077 + aUndoEditor.InsertTextL(28, _L("ol"), 0, 0, 0);
1.2078 + aTestEditor.Print(*log);
1.2079 + HBufC* textLog1 = log->GetStore();
1.2080 +
1.2081 + aCommandManager.UndoL();
1.2082 + check->SetCheckString(*textLog0);
1.2083 + aTestEditor.Print(*check);
1.2084 + CheckEditorLog(*check);
1.2085 +
1.2086 + aCommandManager.UndoL();
1.2087 + check->SetCheckString(*helloWorldLog);
1.2088 + aTestEditor.Print(*check);
1.2089 + CheckEditorLog(*check);
1.2090 +
1.2091 + aCommandManager.RedoL();
1.2092 + check->SetCheckString(*textLog0);
1.2093 + aTestEditor.Print(*check);
1.2094 + CheckEditorLog(*check);
1.2095 +
1.2096 + aCommandManager.RedoL();
1.2097 + check->SetCheckString(*textLog1);
1.2098 + aTestEditor.Print(*check);
1.2099 + CheckEditorLog(*check);
1.2100 +
1.2101 + // check coalescence of insertions
1.2102 + aTestEditor.AlterGranularityL(5);
1.2103 + aUndoEditor.DeleteTextL(22, 1);
1.2104 + aUndoEditor.DeleteTextL(21, 1);
1.2105 + aUndoEditor.DeleteTextL(20, 1);
1.2106 + aUndoEditor.DeleteTextL(19, 1);
1.2107 + aUndoEditor.DeleteTextL(18, 1);
1.2108 + aUndoEditor.DeleteTextL(18, 1);
1.2109 + aUndoEditor.DeleteTextL(15, 3); // this will coalesce
1.2110 + aUndoEditor.DeleteTextL(6, 9); // this won't, as it does not fit in one command
1.2111 + aTestEditor.Print(*log);
1.2112 + HBufC* delLog0 = log->GetStore();
1.2113 + aUndoEditor.DeleteTextL(4, 1);
1.2114 + aTestEditor.Print(*log);
1.2115 + HBufC* delLog1 = log->GetStore();
1.2116 + aUndoEditor.DeleteTextL(8, 2);
1.2117 + aUndoEditor.DeleteTextL(8, 1); // should coalesce
1.2118 + aUndoEditor.DeleteTextL(8, 1); // should coalesce
1.2119 + aTestEditor.Print(*log);
1.2120 + HBufC* delLog3 = log->GetStore();
1.2121 +
1.2122 + aCommandManager.UndoL();
1.2123 + check->SetCheckString(*delLog1);
1.2124 + aTestEditor.Print(*check);
1.2125 + CheckEditorLog(*check);
1.2126 +
1.2127 + aCommandManager.UndoL();
1.2128 + check->SetCheckString(*delLog0);
1.2129 + aTestEditor.Print(*check);
1.2130 + CheckEditorLog(*check);
1.2131 +
1.2132 + aCommandManager.UndoL();
1.2133 + aCommandManager.UndoL();
1.2134 + check->SetCheckString(*textLog1);
1.2135 + aTestEditor.Print(*check);
1.2136 + CheckEditorLog(*check);
1.2137 +
1.2138 + aCommandManager.RedoL();
1.2139 + aCommandManager.RedoL();
1.2140 + check->SetCheckString(*delLog0);
1.2141 + aTestEditor.Print(*check);
1.2142 + CheckEditorLog(*check);
1.2143 +
1.2144 + aCommandManager.RedoL();
1.2145 + check->SetCheckString(*delLog1);
1.2146 + aTestEditor.Print(*check);
1.2147 + CheckEditorLog(*check);
1.2148 +
1.2149 + aCommandManager.RedoL();
1.2150 + check->SetCheckString(*delLog3);
1.2151 + aTestEditor.Print(*check);
1.2152 + CheckEditorLog(*check);
1.2153 +
1.2154 + aCommandManager.UndoL();
1.2155 + check->SetCheckString(*delLog1);
1.2156 + aTestEditor.Print(*check);
1.2157 + CheckEditorLog(*check);
1.2158 +
1.2159 + aCommandManager.UndoL();
1.2160 + check->SetCheckString(*delLog0);
1.2161 + aTestEditor.Print(*check);
1.2162 + CheckEditorLog(*check);
1.2163 +
1.2164 + aCommandManager.UndoL();
1.2165 + aCommandManager.UndoL();
1.2166 + check->SetCheckString(*textLog1);
1.2167 + aTestEditor.Print(*check);
1.2168 + CheckEditorLog(*check);
1.2169 +
1.2170 + aCommandManager.UndoL();
1.2171 + aCommandManager.UndoL();
1.2172 + check->SetCheckString(*helloWorldLog);
1.2173 + aTestEditor.Print(*check);
1.2174 + CheckEditorLog(*check);
1.2175 +
1.2176 + aCommandManager.ResetUndo();
1.2177 + delete delLog0;
1.2178 + delete delLog1;
1.2179 + delete delLog3;
1.2180 +
1.2181 + // Check adding large amounts of text
1.2182 + aTestEditor.AlterGranularityL(32);
1.2183 + aUndoEditor.InsertTextL(0, _L("123456789"), 0, 0, 0);
1.2184 + aUndoEditor.InsertTextL(0, _L("223456789"), 0, 0, 0);
1.2185 + aTestEditor.Print(*log);
1.2186 + HBufC* largeLog0 = log->GetStore();
1.2187 + aUndoEditor.InsertTextL(0, _L("3234567890"), 0, 0, 0);
1.2188 + aUndoEditor.InsertTextL(0, _L("4234567890"), 0, 0, 0);
1.2189 + aTestEditor.Print(*log);
1.2190 + HBufC* largeLog1 = log->GetStore();
1.2191 + aUndoEditor.InsertTextL(0, _L("523456789"), 0, 0, 0);
1.2192 + aTestEditor.Print(*log);
1.2193 + HBufC* largeLog2 = log->GetStore();
1.2194 +
1.2195 + aCommandManager.UndoL();
1.2196 + check->SetCheckString(*largeLog1);
1.2197 + aTestEditor.Print(*check);
1.2198 + CheckEditorLog(*check);
1.2199 +
1.2200 + aCommandManager.UndoL();
1.2201 + check->SetCheckString(*largeLog0);
1.2202 + aTestEditor.Print(*check);
1.2203 + CheckEditorLog(*check);
1.2204 +
1.2205 + aCommandManager.UndoL();
1.2206 + check->SetCheckString(*helloWorldLog);
1.2207 + aTestEditor.Print(*check);
1.2208 + CheckEditorLog(*check);
1.2209 +
1.2210 + aCommandManager.RedoL();
1.2211 + check->SetCheckString(*largeLog0);
1.2212 + aTestEditor.Print(*check);
1.2213 + CheckEditorLog(*check);
1.2214 +
1.2215 + aCommandManager.RedoL();
1.2216 + check->SetCheckString(*largeLog1);
1.2217 + aTestEditor.Print(*check);
1.2218 + CheckEditorLog(*check);
1.2219 +
1.2220 + aCommandManager.RedoL();
1.2221 + check->SetCheckString(*largeLog2);
1.2222 + aTestEditor.Print(*check);
1.2223 + CheckEditorLog(*check);
1.2224 +
1.2225 + aCommandManager.UndoL();
1.2226 + check->SetCheckString(*largeLog1);
1.2227 + aTestEditor.Print(*check);
1.2228 + CheckEditorLog(*check);
1.2229 +
1.2230 + aCommandManager.UndoL();
1.2231 + check->SetCheckString(*largeLog0);
1.2232 + aTestEditor.Print(*check);
1.2233 + CheckEditorLog(*check);
1.2234 +
1.2235 + aCommandManager.UndoL();
1.2236 + check->SetCheckString(*helloWorldLog);
1.2237 + aTestEditor.Print(*check);
1.2238 + CheckEditorLog(*check);
1.2239 +
1.2240 + aCommandManager.RedoL();
1.2241 + aCommandManager.RedoL();
1.2242 + aCommandManager.RedoL();
1.2243 +
1.2244 + // test copy and paste
1.2245 + MUnifiedEditor::MClipboardSupport* ci = aUndoEditor.ClipboardSupport();
1.2246 + ASSERT(ci);
1.2247 +
1.2248 + CBufStore* clipboardBuffer = CBufStore::NewL(100);
1.2249 + CStreamDictionary* clipboardDictionary = CStreamDictionary::NewL();
1.2250 +
1.2251 + ci->CopyToStoreL(*clipboardBuffer, *clipboardDictionary, 5, 40);
1.2252 + aTestEditor.Print(*log);
1.2253 + HBufC* clipLog0 = log->GetStore();
1.2254 + ci->PasteFromStoreL(*clipboardBuffer, *clipboardDictionary, 2);
1.2255 + aTestEditor.Print(*log);
1.2256 + HBufC* clipLog1 = log->GetStore();
1.2257 + ci->PasteFromStoreL(*clipboardBuffer, *clipboardDictionary, 55);
1.2258 + aTestEditor.Print(*log);
1.2259 + HBufC* clipLog2 = log->GetStore();
1.2260 + ci->PasteFromStoreL(*clipboardBuffer, *clipboardDictionary, 23);
1.2261 + aTestEditor.Print(*log);
1.2262 + HBufC* clipLog3 = log->GetStore();
1.2263 +
1.2264 + aCommandManager.UndoL();
1.2265 + check->SetCheckString(*clipLog2);
1.2266 + aTestEditor.Print(*check);
1.2267 + CheckEditorLog(*check);
1.2268 +
1.2269 + aCommandManager.UndoL();
1.2270 + check->SetCheckString(*clipLog1);
1.2271 + aTestEditor.Print(*check);
1.2272 + CheckEditorLog(*check);
1.2273 +
1.2274 + aCommandManager.UndoL();
1.2275 + check->SetCheckString(*clipLog0);
1.2276 + aTestEditor.Print(*check);
1.2277 + CheckEditorLog(*check);
1.2278 +
1.2279 + aCommandManager.RedoL();
1.2280 + check->SetCheckString(*clipLog1);
1.2281 + aTestEditor.Print(*check);
1.2282 + CheckEditorLog(*check);
1.2283 +
1.2284 + aCommandManager.RedoL();
1.2285 + check->SetCheckString(*clipLog2);
1.2286 + aTestEditor.Print(*check);
1.2287 + CheckEditorLog(*check);
1.2288 +
1.2289 + aCommandManager.RedoL();
1.2290 + check->SetCheckString(*clipLog3);
1.2291 + aTestEditor.Print(*check);
1.2292 + CheckEditorLog(*check);
1.2293 +
1.2294 + aCommandManager.UndoL();
1.2295 + check->SetCheckString(*clipLog2);
1.2296 + aTestEditor.Print(*check);
1.2297 + CheckEditorLog(*check);
1.2298 +
1.2299 + aCommandManager.UndoL();
1.2300 + check->SetCheckString(*clipLog1);
1.2301 + aTestEditor.Print(*check);
1.2302 + CheckEditorLog(*check);
1.2303 +
1.2304 + aCommandManager.UndoL();
1.2305 + check->SetCheckString(*clipLog0);
1.2306 + aTestEditor.Print(*check);
1.2307 + CheckEditorLog(*check);
1.2308 +
1.2309 + delete clipLog0;
1.2310 + delete clipLog1;
1.2311 + delete clipLog2;
1.2312 + delete clipLog3;
1.2313 + delete clipboardDictionary;
1.2314 + delete clipboardBuffer;
1.2315 +
1.2316 + delete textLog0;
1.2317 + delete textLog1;
1.2318 +
1.2319 + delete largeLog0;
1.2320 + delete largeLog1;
1.2321 + delete largeLog2;
1.2322 +
1.2323 + delete helloWorldLog;
1.2324 + delete helloLovelyWorldLog;
1.2325 + delete helloLoveLog;
1.2326 + delete log;
1.2327 + delete check;
1.2328 + }
1.2329 +
1.2330 +// This class merely splits the test function into little functions
1.2331 +// to help out the MW compiler
1.2332 +class TestEditorUndo
1.2333 + {
1.2334 + CCheckingLogger* check;
1.2335 + CStoringLogger* log;
1.2336 + CTestEditor* testEd;
1.2337 + CCommandManager* manager;
1.2338 + CEditorPlainTextWithUndo* plainEd;
1.2339 + CEditorWithUndo* ed;
1.2340 + TTmCharFormatMask charBMask;
1.2341 + TTmCharFormatMask charIMask;
1.2342 + TTmCharFormatMask charBIMask;
1.2343 + TOpenFontFaceAttribBase attrib;
1.2344 + TTmCharFormat charB;
1.2345 + TTmCharFormat charIB;
1.2346 + TTmCharFormat charI;
1.2347 + TTmParFormatMask parTMask;
1.2348 + TTmParFormatMask parNMask;
1.2349 + TTmParFormatMask parTNMask;
1.2350 + RTmParFormat par0;
1.2351 + RTmParFormat parT;
1.2352 + RTmParFormat parN;
1.2353 + RTmParFormat parTN;
1.2354 + TTmCharFormatLayer charLayer;
1.2355 + RTmParFormatLayer parLayer;
1.2356 + RTmStyle style1;
1.2357 + RTmStyle style2;
1.2358 + HBufC* charLog0;
1.2359 + HBufC* charLog1;
1.2360 + HBufC* charLog2;
1.2361 + HBufC* charLog3;
1.2362 + HBufC* textLog0;
1.2363 + HBufC* textLog1;
1.2364 + HBufC* textLog2;
1.2365 + HBufC* textLog3;
1.2366 + HBufC* parLog0;
1.2367 + HBufC* parLog1;
1.2368 + HBufC* parLog2;
1.2369 + HBufC* parLog3;
1.2370 + HBufC* delLog0;
1.2371 + HBufC* delLog1;
1.2372 + HBufC* delLog2;
1.2373 + HBufC* delLog3;
1.2374 + HBufC* styleLog1;
1.2375 + HBufC* styleLog2;
1.2376 + HBufC* styleLog3;
1.2377 + HBufC* styleLog4;
1.2378 + HBufC* styleLog5;
1.2379 + HBufC* styleLog6;
1.2380 + HBufC* styleLog7;
1.2381 + HBufC* styleLog8;
1.2382 + HBufC* styleLog9;
1.2383 + HBufC* styleLog10;
1.2384 + HBufC* styleLog11;
1.2385 + HBufC* styleLog12;
1.2386 + HBufC* styleLog13;
1.2387 + HBufC* picLog0;
1.2388 + HBufC* picLog1;
1.2389 + HBufC* picLog2;
1.2390 + HBufC* picLog3;
1.2391 + HBufC* picLog4;
1.2392 + HBufC* picLog5;
1.2393 + HBufC* bookMarkLog0;
1.2394 + HBufC* bookMarkLog1;
1.2395 + HBufC* bookMarkLog2;
1.2396 + HBufC* bookMarkLog3;
1.2397 + HBufC* bookMarkLog4;
1.2398 + HBufC* bookMarkLog5;
1.2399 +public:
1.2400 + void Test1L();
1.2401 + void Test2L();
1.2402 + void Test3L();
1.2403 + void Test4L();
1.2404 + void Test5L();
1.2405 + void Test6L();
1.2406 + void Test7L();
1.2407 + void Test8L();
1.2408 + };
1.2409 +
1.2410 +void TestEditorUndo::Test1L()
1.2411 + {
1.2412 + check = new(ELeave) CCheckingLogger;
1.2413 + log = new(ELeave) CStoringLogger;
1.2414 + testEd = CTestEditor::NewL();
1.2415 + manager = CCommandManager::NewL();
1.2416 + plainEd = CEditorPlainTextWithUndo::NewL(*testEd, manager);
1.2417 +
1.2418 + TestPlainText(*testEd, *plainEd, *manager);
1.2419 + ed = CEditorWithUndo::NewL(*testEd, manager);
1.2420 + testEd->DeleteTextL(0, testEd->DocumentLength());
1.2421 + manager->ResetUndo();
1.2422 +
1.2423 + delete plainEd;
1.2424 + plainEd = 0;
1.2425 +
1.2426 + TestPlainText(*testEd, *ed, *manager);
1.2427 + manager->Release();
1.2428 + }
1.2429 +
1.2430 +void TestEditorUndo::Test2L()
1.2431 + {
1.2432 + // char and par formats
1.2433 + charBMask.iFlags = TTmCharFormatMask::EBold;
1.2434 + charIMask.iFlags = TTmCharFormatMask::EItalic;
1.2435 + charBIMask.iFlags = TTmCharFormatMask::EItalic | TTmCharFormatMask::EBold;
1.2436 + attrib.SetBold(ETrue);
1.2437 + charB.iFontSpec.SetAttrib(attrib);
1.2438 + attrib.SetItalic(ETrue);
1.2439 + charIB.iFontSpec.SetAttrib(attrib);
1.2440 + attrib.SetBold(EFalse);
1.2441 + charI.iFontSpec.SetAttrib(attrib);
1.2442 +
1.2443 + parTMask.iFlags = TTmParFormatMask::EKeepTogether;
1.2444 + parNMask.iFlags = TTmParFormatMask::EKeepWithNext;
1.2445 + parTNMask.iFlags = TTmParFormatMask::EKeepTogether | TTmParFormatMask::EKeepWithNext;
1.2446 + parT.iFlags = RTmParFormat::EKeepTogether;
1.2447 + parN.iFlags = RTmParFormat::EKeepWithNext;
1.2448 + parTN.iFlags = RTmParFormat::EKeepWithNext | RTmParFormat::EKeepTogether;
1.2449 +
1.2450 + charLayer.iFormat = charB;
1.2451 + charLayer.iMask = charBMask;
1.2452 + ed->SetCharFormatL(0, 5, charLayer);
1.2453 + testEd->Print(*log);
1.2454 + charLog0 = log->GetStore();
1.2455 +
1.2456 + charLayer.iFormat = charI;
1.2457 + charLayer.iMask = charIMask;
1.2458 + ed->SetCharFormatL(3, 9, charLayer);
1.2459 + testEd->Print(*log);
1.2460 + charLog1 = log->GetStore();
1.2461 +
1.2462 + charLayer.iFormat = charB;
1.2463 + charLayer.iMask = charBIMask;
1.2464 + ed->SetCharFormatL(2, 5, charLayer);
1.2465 + testEd->Print(*log);
1.2466 + charLog2 = log->GetStore();
1.2467 +
1.2468 + ed->DeleteCharFormatL(1, 10);
1.2469 + testEd->Print(*log);
1.2470 + charLog3 = log->GetStore();
1.2471 +
1.2472 + ed->UndoL();
1.2473 + check->SetCheckString(*charLog2);
1.2474 + testEd->Print(*check);
1.2475 + CheckEditorLog(*check);
1.2476 +
1.2477 + ed->UndoL();
1.2478 + check->SetCheckString(*charLog1);
1.2479 + testEd->Print(*check);
1.2480 + CheckEditorLog(*check);
1.2481 +
1.2482 + ed->UndoL();
1.2483 + check->SetCheckString(*charLog0);
1.2484 + testEd->Print(*check);
1.2485 + CheckEditorLog(*check);
1.2486 +
1.2487 + ed->RedoL();
1.2488 + check->SetCheckString(*charLog1);
1.2489 + testEd->Print(*check);
1.2490 + CheckEditorLog(*check);
1.2491 +
1.2492 + ed->RedoL();
1.2493 + check->SetCheckString(*charLog2);
1.2494 + testEd->Print(*check);
1.2495 + CheckEditorLog(*check);
1.2496 +
1.2497 + ed->RedoL();
1.2498 + check->SetCheckString(*charLog3);
1.2499 + testEd->Print(*check);
1.2500 + CheckEditorLog(*check);
1.2501 +
1.2502 + parLayer.iMask = parTMask;
1.2503 + parLayer.iFormat.CopyL(parT);
1.2504 + ed->SetParFormatL(5, 7, parLayer);
1.2505 + testEd->Print(*log);
1.2506 + parLog0 = log->GetStore();
1.2507 +
1.2508 + parLayer.iMask = parTNMask;
1.2509 + parLayer.iFormat.CopyL(parN);
1.2510 + ed->SetParFormatL(0, 7, parLayer);
1.2511 + testEd->Print(*log);
1.2512 + parLog1 = log->GetStore();
1.2513 +
1.2514 + ed->DeleteParFormatL(4, 4);
1.2515 + testEd->Print(*log);
1.2516 + parLog2 = log->GetStore();
1.2517 +
1.2518 + parLayer.iMask = parNMask;
1.2519 + parLayer.iFormat.CopyL(parN);
1.2520 + ed->SetParFormatL(3, 6, parLayer);
1.2521 + testEd->Print(*log);
1.2522 + parLog3 = log->GetStore();
1.2523 +
1.2524 + ed->UndoL();
1.2525 + check->SetCheckString(*parLog2);
1.2526 + testEd->Print(*check);
1.2527 + CheckEditorLog(*check);
1.2528 +
1.2529 + ed->UndoL();
1.2530 + check->SetCheckString(*parLog1);
1.2531 + testEd->Print(*check);
1.2532 + CheckEditorLog(*check);
1.2533 +
1.2534 + ed->UndoL();
1.2535 + check->SetCheckString(*parLog0);
1.2536 + testEd->Print(*check);
1.2537 + CheckEditorLog(*check);
1.2538 +
1.2539 + ed->UndoL();
1.2540 + check->SetCheckString(*charLog3);
1.2541 + testEd->Print(*check);
1.2542 + CheckEditorLog(*check);
1.2543 +
1.2544 + ed->RedoL();
1.2545 + check->SetCheckString(*parLog0);
1.2546 + testEd->Print(*check);
1.2547 + CheckEditorLog(*check);
1.2548 +
1.2549 + ed->RedoL();
1.2550 + check->SetCheckString(*parLog1);
1.2551 + testEd->Print(*check);
1.2552 + CheckEditorLog(*check);
1.2553 +
1.2554 + ed->RedoL();
1.2555 + check->SetCheckString(*parLog2);
1.2556 + testEd->Print(*check);
1.2557 + CheckEditorLog(*check);
1.2558 +
1.2559 + ed->RedoL();
1.2560 + check->SetCheckString(*parLog3);
1.2561 + testEd->Print(*check);
1.2562 + CheckEditorLog(*check);
1.2563 + }
1.2564 +
1.2565 +void TestEditorUndo::Test3L()
1.2566 + {
1.2567 + // check coalescence of deletions
1.2568 + charLayer.iMask = charIMask;
1.2569 + charLayer.iFormat = charI;
1.2570 + parLayer.iMask = parNMask;
1.2571 + parLayer.iFormat.CopyL(parN);
1.2572 + ed->InsertTextL(6, _L("w"), 0, &charLayer, &parLayer);
1.2573 + ed->InsertTextL(7, _L("h"), 0, &charLayer, &parLayer);
1.2574 + ed->InsertTextL(8, _L("at's"), 0, &charLayer, &parLayer);
1.2575 + ed->InsertTextL(12, _L(" "), 0, &charLayer, &parLayer);
1.2576 + ed->InsertTextL(13, _L("w"), 0, &charLayer, &parLayer);
1.2577 + ed->InsertTextL(14, _L("i"), 0, &charLayer, &parLayer);
1.2578 + ed->InsertTextL(6, _L("there "), 0, &charLayer, &parLayer);
1.2579 + ed->InsertTextL(21, _L("t"), 0, &charLayer, &parLayer);
1.2580 + ed->InsertTextL(22, _L("h"), 0, &charLayer, &parLayer);
1.2581 + ed->InsertTextL(23, _L(" "), 0, &charLayer, &parLayer);
1.2582 + testEd->Print(*log);
1.2583 + textLog0 = log->GetStore();
1.2584 + ed->InsertTextL(24, _L("the"), 0, &charLayer, &parLayer); // first of next?
1.2585 + ed->InsertTextL(27, _L(" "), 0, &charLayer, &parLayer);
1.2586 + testEd->Print(*log);
1.2587 + textLog1 = log->GetStore();
1.2588 + charLayer.iMask = charBIMask;
1.2589 + ed->InsertTextL(28, _L("ol"), 0, &charLayer, &parLayer);
1.2590 + testEd->Print(*log);
1.2591 + textLog2 = log->GetStore();
1.2592 + parLayer.iMask = parTNMask;
1.2593 + ed->InsertTextL(30, _L("d "), 0, &charLayer, &parLayer);
1.2594 + testEd->Print(*log);
1.2595 + textLog3 = log->GetStore();
1.2596 +
1.2597 + ed->UndoL();
1.2598 + check->SetCheckString(*textLog0);
1.2599 + testEd->Print(*check);
1.2600 + CheckEditorLog(*check);
1.2601 +
1.2602 + ed->UndoL();
1.2603 + check->SetCheckString(*parLog3);
1.2604 + testEd->Print(*check);
1.2605 + CheckEditorLog(*check);
1.2606 +
1.2607 + ed->RedoL();
1.2608 + check->SetCheckString(*textLog0);
1.2609 + testEd->Print(*check);
1.2610 + CheckEditorLog(*check);
1.2611 +
1.2612 + ed->RedoL();
1.2613 + check->SetCheckString(*textLog3);
1.2614 + testEd->Print(*check);
1.2615 + CheckEditorLog(*check);
1.2616 + ed->ResetUndo();
1.2617 + }
1.2618 +
1.2619 +void TestEditorUndo::Test4L()
1.2620 + {
1.2621 + // check coalescence of insertions
1.2622 + testEd->AlterGranularityL(5);
1.2623 + ed->DeleteTextL(22, 1);
1.2624 + ed->DeleteTextL(21, 1);
1.2625 + ed->DeleteTextL(20, 1);
1.2626 + ed->DeleteTextL(19, 1);
1.2627 + ed->DeleteTextL(18, 1);
1.2628 + ed->DeleteTextL(18, 1);
1.2629 + ed->DeleteTextL(15, 3); // this will coalesce
1.2630 + ed->DeleteTextL(6, 9); // this won't, as it does not fit in one command
1.2631 + testEd->Print(*log);
1.2632 + delLog0 = log->GetStore();
1.2633 + ed->DeleteTextL(4, 1);
1.2634 + testEd->Print(*log);
1.2635 + delLog1 = log->GetStore();
1.2636 + ed->DeleteTextL(8, 2);
1.2637 + ed->DeleteTextL(8, 1); // should coalesce
1.2638 + testEd->Print(*log);
1.2639 + delLog2 = log->GetStore();
1.2640 + ed->DeleteTextL(8, 1); // should fail to coalesce
1.2641 + testEd->Print(*log);
1.2642 + delLog3 = log->GetStore();
1.2643 +
1.2644 + ed->UndoL();
1.2645 + check->SetCheckString(*delLog2);
1.2646 + testEd->Print(*check);
1.2647 + CheckEditorLog(*check);
1.2648 +
1.2649 + ed->UndoL();
1.2650 + check->SetCheckString(*delLog1);
1.2651 + testEd->Print(*check);
1.2652 + CheckEditorLog(*check);
1.2653 +
1.2654 + ed->UndoL();
1.2655 + check->SetCheckString(*delLog0);
1.2656 + testEd->Print(*check);
1.2657 + CheckEditorLog(*check);
1.2658 +
1.2659 + ed->UndoL();
1.2660 + ed->UndoL();
1.2661 + check->SetCheckString(*textLog3);
1.2662 + testEd->Print(*check);
1.2663 + CheckEditorLog(*check);
1.2664 +
1.2665 + ed->RedoL();
1.2666 + ed->RedoL();
1.2667 + check->SetCheckString(*delLog0);
1.2668 + testEd->Print(*check);
1.2669 + CheckEditorLog(*check);
1.2670 +
1.2671 + ed->RedoL();
1.2672 + check->SetCheckString(*delLog1);
1.2673 + testEd->Print(*check);
1.2674 + CheckEditorLog(*check);
1.2675 +
1.2676 + ed->RedoL();
1.2677 + check->SetCheckString(*delLog2);
1.2678 + testEd->Print(*check);
1.2679 + CheckEditorLog(*check);
1.2680 +
1.2681 + ed->RedoL();
1.2682 + check->SetCheckString(*delLog3);
1.2683 + testEd->Print(*check);
1.2684 + CheckEditorLog(*check);
1.2685 +
1.2686 + ed->UndoL();
1.2687 + check->SetCheckString(*delLog2);
1.2688 + testEd->Print(*check);
1.2689 + CheckEditorLog(*check);
1.2690 +
1.2691 + ed->UndoL();
1.2692 + check->SetCheckString(*delLog1);
1.2693 + testEd->Print(*check);
1.2694 + CheckEditorLog(*check);
1.2695 +
1.2696 + ed->UndoL();
1.2697 + check->SetCheckString(*delLog0);
1.2698 + testEd->Print(*check);
1.2699 + CheckEditorLog(*check);
1.2700 +
1.2701 + ed->UndoL();
1.2702 + ed->UndoL();
1.2703 + check->SetCheckString(*textLog3);
1.2704 + testEd->Print(*check);
1.2705 + CheckEditorLog(*check);
1.2706 + ed->ResetUndo();
1.2707 + delete delLog0;
1.2708 + delete delLog1;
1.2709 + delete delLog2;
1.2710 + delete delLog3;
1.2711 + }
1.2712 +
1.2713 +void TestEditorUndo::Test5L()
1.2714 + {
1.2715 + // Check adding large amounts of text
1.2716 + testEd->AlterGranularityL(32);
1.2717 + ed->InsertTextL(0, _L("123456789"), 0, 0, 0);
1.2718 + ed->InsertTextL(0, _L("223456789"), 0, 0, 0);
1.2719 + testEd->Print(*log);
1.2720 + delete textLog0;
1.2721 + textLog0 = log->GetStore();
1.2722 + ed->InsertTextL(0, _L("3234567890"), 0, 0, 0);
1.2723 + ed->InsertTextL(0, _L("4234567890"), 0, 0, 0);
1.2724 + testEd->Print(*log);
1.2725 + delete textLog1;
1.2726 + textLog1 = log->GetStore();
1.2727 + ed->InsertTextL(0, _L("523456789"), 0, 0, 0);
1.2728 + testEd->Print(*log);
1.2729 + delete textLog2;
1.2730 + textLog2 = log->GetStore();
1.2731 +
1.2732 + ed->UndoL();
1.2733 + check->SetCheckString(*textLog1);
1.2734 + testEd->Print(*check);
1.2735 + CheckEditorLog(*check);
1.2736 +
1.2737 + ed->UndoL();
1.2738 + check->SetCheckString(*textLog0);
1.2739 + testEd->Print(*check);
1.2740 + CheckEditorLog(*check);
1.2741 +
1.2742 + ed->UndoL();
1.2743 + check->SetCheckString(*textLog3);
1.2744 + testEd->Print(*check);
1.2745 + CheckEditorLog(*check);
1.2746 +
1.2747 + ed->RedoL();
1.2748 + check->SetCheckString(*textLog0);
1.2749 + testEd->Print(*check);
1.2750 + CheckEditorLog(*check);
1.2751 +
1.2752 + ed->RedoL();
1.2753 + check->SetCheckString(*textLog1);
1.2754 + testEd->Print(*check);
1.2755 + CheckEditorLog(*check);
1.2756 +
1.2757 + ed->RedoL();
1.2758 + check->SetCheckString(*textLog2);
1.2759 + testEd->Print(*check);
1.2760 + CheckEditorLog(*check);
1.2761 +
1.2762 + ed->UndoL();
1.2763 + check->SetCheckString(*textLog1);
1.2764 + testEd->Print(*check);
1.2765 + CheckEditorLog(*check);
1.2766 +
1.2767 + ed->UndoL();
1.2768 + check->SetCheckString(*textLog0);
1.2769 + testEd->Print(*check);
1.2770 + CheckEditorLog(*check);
1.2771 +
1.2772 + ed->UndoL();
1.2773 + check->SetCheckString(*textLog3);
1.2774 + testEd->Print(*check);
1.2775 + CheckEditorLog(*check);
1.2776 + }
1.2777 +
1.2778 +void TestEditorUndo::Test6L()
1.2779 + {
1.2780 + // test style manipulation
1.2781 + style1.iName = _L("author");
1.2782 + style2.iName = _L("title");
1.2783 + style2.iNextStyleName = _L("author");
1.2784 + style1.iCharFormat.iFormat = charI;
1.2785 + style1.iCharFormat.iMask = charIMask;
1.2786 + style1.iParFormat.iFormat.CopyL(parT);
1.2787 + style1.iParFormat.iMask = parTNMask;
1.2788 + style2.iCharFormat.iFormat = charB;
1.2789 + style2.iCharFormat.iMask = charBIMask;
1.2790 + style2.iParFormat.iFormat.CopyL(parN);
1.2791 + style2.iParFormat.iMask = parNMask;
1.2792 +
1.2793 + ed->StyleSupport()->CreateStyleL(style1);
1.2794 + testEd->Print(*log);
1.2795 + styleLog1 = log->GetStore();
1.2796 + TInt retval = ed->StyleSupport()->SetStyleL(1, 3, _L("author"));
1.2797 + testEd->Print(*log);
1.2798 + styleLog2 = log->GetStore();
1.2799 + if (retval != KErrNone)
1.2800 + {
1.2801 + TESTPRINT(_L("EditorUndo : apply style failed"));
1.2802 + TESTPOINT(0);
1.2803 + }
1.2804 + TPtrC testStyleName;
1.2805 + TInt testStyleRunLength;
1.2806 + ed->StyleSupport()->GetStyle(1, testStyleName, testStyleRunLength);
1.2807 + if (testStyleRunLength != 3 || testStyleName != style1.iName)
1.2808 + {
1.2809 + TESTPRINT(_L("EditorUndo : apply style failed"));
1.2810 + TESTPOINT(0);
1.2811 + }
1.2812 + ed->InsertTextL(5, _L(","), &style1.iName, 0, 0);
1.2813 + testEd->Print(*log);
1.2814 + styleLog3 = log->GetStore();
1.2815 + ed->StyleSupport()->CreateStyleL(style2);
1.2816 + testEd->Print(*log);
1.2817 + styleLog4 = log->GetStore();
1.2818 + ed->StyleSupport()->SetStyleL(2, 7, _L("title"));
1.2819 + testEd->Print(*log);
1.2820 + styleLog5 = log->GetStore();
1.2821 + ed->StyleSupport()->SetStyleL(10, 4, _L("title"));
1.2822 + testEd->Print(*log);
1.2823 + styleLog6 = log->GetStore();
1.2824 + ed->StyleSupport()->SetStyleL(8, 4, _L("author"));
1.2825 + testEd->Print(*log);
1.2826 + styleLog7 = log->GetStore();
1.2827 + style1.iCharFormat.iFormat = charB;
1.2828 + style1.iCharFormat.iMask = charBMask;
1.2829 + ed->StyleSupport()->ChangeStyleL(style1);
1.2830 + testEd->Print(*log);
1.2831 + styleLog8 = log->GetStore();
1.2832 + ed->StyleSupport()->RenameStyleL(_L("author"), _L("version"));
1.2833 + style1.iName = _L("version");
1.2834 + testEd->Print(*log);
1.2835 + styleLog9 = log->GetStore();
1.2836 + retval = ed->StyleSupport()->SetStyleL(10, 1, _L("version"));
1.2837 + testEd->Print(*log);
1.2838 + styleLog10 = log->GetStore();
1.2839 + if (retval != KErrNone)
1.2840 + {
1.2841 + TESTPRINT(_L("EditorUndo : rename style failed"));
1.2842 + TESTPOINT(0);
1.2843 + }
1.2844 + ed->StyleSupport()->GetStyle(1, testStyleName, testStyleRunLength);
1.2845 + if (testStyleRunLength != 1 || testStyleName != style1.iName)
1.2846 + {
1.2847 + TESTPRINT(_L("EditorUndo : rename or apply style failed"));
1.2848 + TESTPOINT(0);
1.2849 + }
1.2850 + ed->StyleSupport()->RenameStyleL(_L("title"), _L("zip"));
1.2851 + style2.iName = _L("zip");
1.2852 + testEd->Print(*log);
1.2853 + styleLog11 = log->GetStore();
1.2854 + ed->StyleSupport()->SetStyleL(0, 6, _L("zip"));
1.2855 + testEd->Print(*log);
1.2856 + styleLog12 = log->GetStore();
1.2857 + ed->StyleSupport()->DeleteStyleL(_L("zip"));
1.2858 + testEd->Print(*log);
1.2859 + styleLog13 = log->GetStore();
1.2860 + ed->InsertTextL(0, _L("Well "), &style1.iName, 0, 0);
1.2861 +
1.2862 + ed->UndoL();
1.2863 + check->SetCheckString(*styleLog13);
1.2864 + testEd->Print(*check);
1.2865 + CheckEditorLog(*check);
1.2866 +
1.2867 + ed->UndoL();
1.2868 + check->SetCheckString(*styleLog12);
1.2869 + testEd->Print(*check);
1.2870 + CheckEditorLog(*check);
1.2871 +
1.2872 + ed->UndoL();
1.2873 + check->SetCheckString(*styleLog11);
1.2874 + testEd->Print(*check);
1.2875 + CheckEditorLog(*check);
1.2876 +
1.2877 + ed->UndoL();
1.2878 + check->SetCheckString(*styleLog10);
1.2879 + testEd->Print(*check);
1.2880 + CheckEditorLog(*check);
1.2881 +
1.2882 + ed->UndoL();
1.2883 + check->SetCheckString(*styleLog9);
1.2884 + testEd->Print(*check);
1.2885 + CheckEditorLog(*check);
1.2886 +
1.2887 + ed->UndoL();
1.2888 + check->SetCheckString(*styleLog8);
1.2889 + testEd->Print(*check);
1.2890 + CheckEditorLog(*check);
1.2891 +
1.2892 + ed->UndoL();
1.2893 + check->SetCheckString(*styleLog7);
1.2894 + testEd->Print(*check);
1.2895 + CheckEditorLog(*check);
1.2896 +
1.2897 + ed->UndoL();
1.2898 + check->SetCheckString(*styleLog6);
1.2899 + testEd->Print(*check);
1.2900 + CheckEditorLog(*check);
1.2901 +
1.2902 + ed->UndoL();
1.2903 + check->SetCheckString(*styleLog5);
1.2904 + testEd->Print(*check);
1.2905 + CheckEditorLog(*check);
1.2906 +
1.2907 + ed->UndoL();
1.2908 + check->SetCheckString(*styleLog4);
1.2909 + testEd->Print(*check);
1.2910 + CheckEditorLog(*check);
1.2911 +
1.2912 + ed->UndoL();
1.2913 + check->SetCheckString(*styleLog3);
1.2914 + testEd->Print(*check);
1.2915 + CheckEditorLog(*check);
1.2916 +
1.2917 + ed->UndoL();
1.2918 + check->SetCheckString(*styleLog2);
1.2919 + testEd->Print(*check);
1.2920 + CheckEditorLog(*check);
1.2921 +
1.2922 + ed->UndoL();
1.2923 + check->SetCheckString(*styleLog1);
1.2924 + testEd->Print(*check);
1.2925 + CheckEditorLog(*check);
1.2926 +
1.2927 + ed->UndoL();
1.2928 + check->SetCheckString(*textLog3);
1.2929 + testEd->Print(*check);
1.2930 + CheckEditorLog(*check);
1.2931 +
1.2932 + ed->RedoL();
1.2933 + check->SetCheckString(*styleLog1);
1.2934 + testEd->Print(*check);
1.2935 + CheckEditorLog(*check);
1.2936 +
1.2937 + ed->RedoL();
1.2938 + check->SetCheckString(*styleLog2);
1.2939 + testEd->Print(*check);
1.2940 + CheckEditorLog(*check);
1.2941 +
1.2942 + ed->RedoL();
1.2943 + check->SetCheckString(*styleLog3);
1.2944 + testEd->Print(*check);
1.2945 + CheckEditorLog(*check);
1.2946 +
1.2947 + ed->RedoL();
1.2948 + check->SetCheckString(*styleLog4);
1.2949 + testEd->Print(*check);
1.2950 + CheckEditorLog(*check);
1.2951 +
1.2952 + ed->RedoL();
1.2953 + check->SetCheckString(*styleLog5);
1.2954 + testEd->Print(*check);
1.2955 + CheckEditorLog(*check);
1.2956 +
1.2957 + ed->RedoL();
1.2958 + check->SetCheckString(*styleLog6);
1.2959 + testEd->Print(*check);
1.2960 + CheckEditorLog(*check);
1.2961 +
1.2962 + ed->RedoL();
1.2963 + check->SetCheckString(*styleLog7);
1.2964 + testEd->Print(*check);
1.2965 + CheckEditorLog(*check);
1.2966 +
1.2967 + ed->RedoL();
1.2968 + check->SetCheckString(*styleLog8);
1.2969 + testEd->Print(*check);
1.2970 + CheckEditorLog(*check);
1.2971 +
1.2972 + ed->RedoL();
1.2973 + check->SetCheckString(*styleLog9);
1.2974 + testEd->Print(*check);
1.2975 + CheckEditorLog(*check);
1.2976 +
1.2977 + ed->RedoL();
1.2978 + check->SetCheckString(*styleLog10);
1.2979 + testEd->Print(*check);
1.2980 + CheckEditorLog(*check);
1.2981 +
1.2982 + ed->RedoL();
1.2983 + check->SetCheckString(*styleLog11);
1.2984 + testEd->Print(*check);
1.2985 + CheckEditorLog(*check);
1.2986 +
1.2987 + ed->RedoL();
1.2988 + check->SetCheckString(*styleLog12);
1.2989 + testEd->Print(*check);
1.2990 + CheckEditorLog(*check);
1.2991 +
1.2992 + ed->RedoL();
1.2993 + check->SetCheckString(*styleLog13);
1.2994 + testEd->Print(*check);
1.2995 + CheckEditorLog(*check);
1.2996 +
1.2997 + // probably need some more style tests that test the full range of
1.2998 + // attributes that a style may have.
1.2999 + //...
1.3000 +
1.3001 + delete textLog0;
1.3002 + delete textLog1;
1.3003 + delete textLog2;
1.3004 + delete parLog0;
1.3005 + delete parLog1;
1.3006 + delete parLog2;
1.3007 + delete parLog3;
1.3008 + delete charLog0;
1.3009 + delete charLog1;
1.3010 + delete charLog2;
1.3011 + delete charLog3;
1.3012 + delete styleLog1;
1.3013 + delete styleLog2;
1.3014 + delete styleLog3;
1.3015 + delete styleLog4;
1.3016 + delete styleLog5;
1.3017 + delete styleLog6;
1.3018 + delete styleLog7;
1.3019 + delete styleLog8;
1.3020 + delete styleLog9;
1.3021 + delete styleLog10;
1.3022 + delete styleLog11;
1.3023 + delete styleLog12;
1.3024 + delete styleLog13;
1.3025 +
1.3026 + delete textLog3;
1.3027 + }
1.3028 +
1.3029 +void TestEditorUndo::Test7L()
1.3030 + {
1.3031 + // test picture manipulation
1.3032 + TPictureHeader pic;
1.3033 + pic.iPictureType = KUidXzePictureType;
1.3034 + testEd->Print(*log);
1.3035 + picLog0 = log->GetStore();
1.3036 + pic.iPicture = new (ELeave) CUndoTestPicture('A');
1.3037 + ed->PictureSupport()->InsertPictureL(5, pic);
1.3038 + testEd->Print(*log);
1.3039 + picLog1 = log->GetStore();
1.3040 + pic.iPicture = new (ELeave) CUndoTestPicture('B');
1.3041 + ed->PictureSupport()->InsertPictureL(8, pic);
1.3042 + testEd->Print(*log);
1.3043 + picLog2 = log->GetStore();
1.3044 + pic.iPicture = new (ELeave) CUndoTestPicture('C');
1.3045 + ed->PictureSupport()->InsertPictureL(9, pic);
1.3046 + testEd->Print(*log);
1.3047 + picLog3 = log->GetStore();
1.3048 + pic.iPicture = new (ELeave) CUndoTestPicture('D');
1.3049 + ed->PictureSupport()->InsertPictureL(12, pic);
1.3050 + ed->StyleSupport()->SetStyleL(6, 2, style1.iName);
1.3051 + ed->SetCharFormatL(8, 3, charLayer);
1.3052 + ed->SetParFormatL(7, 7, parLayer);
1.3053 + testEd->Print(*log);
1.3054 + picLog4 = log->GetStore();
1.3055 + ed->DeleteTextL(5, 8);
1.3056 + testEd->Print(*log);
1.3057 + picLog5 = log->GetStore();
1.3058 +
1.3059 + ed->UndoL();
1.3060 + check->SetCheckString(*picLog4);
1.3061 + testEd->Print(*check);
1.3062 + CheckEditorLog(*check);
1.3063 +
1.3064 + ed->UndoL();
1.3065 + ed->UndoL();
1.3066 + ed->UndoL();
1.3067 + ed->UndoL();
1.3068 + check->SetCheckString(*picLog3);
1.3069 + testEd->Print(*check);
1.3070 + CheckEditorLog(*check);
1.3071 +
1.3072 + ed->UndoL();
1.3073 + check->SetCheckString(*picLog2);
1.3074 + testEd->Print(*check);
1.3075 + CheckEditorLog(*check);
1.3076 +
1.3077 + ed->UndoL();
1.3078 + check->SetCheckString(*picLog1);
1.3079 + testEd->Print(*check);
1.3080 + CheckEditorLog(*check);
1.3081 +
1.3082 + ed->UndoL();
1.3083 + check->SetCheckString(*picLog0);
1.3084 + testEd->Print(*check);
1.3085 + CheckEditorLog(*check);
1.3086 +
1.3087 + ed->RedoL();
1.3088 + check->SetCheckString(*picLog1);
1.3089 + testEd->Print(*check);
1.3090 + CheckEditorLog(*check);
1.3091 +
1.3092 + ed->RedoL();
1.3093 + check->SetCheckString(*picLog2);
1.3094 + testEd->Print(*check);
1.3095 + CheckEditorLog(*check);
1.3096 +
1.3097 + ed->RedoL();
1.3098 + check->SetCheckString(*picLog3);
1.3099 + testEd->Print(*check);
1.3100 + CheckEditorLog(*check);
1.3101 +
1.3102 + ed->RedoL();
1.3103 + ed->RedoL();
1.3104 + ed->RedoL();
1.3105 + ed->RedoL();
1.3106 + check->SetCheckString(*picLog4);
1.3107 + testEd->Print(*check);
1.3108 + CheckEditorLog(*check);
1.3109 +
1.3110 + ed->RedoL();
1.3111 + check->SetCheckString(*picLog5);
1.3112 + testEd->Print(*check);
1.3113 + CheckEditorLog(*check);
1.3114 +
1.3115 + style1.Close();
1.3116 + style2.Close();
1.3117 + parLayer.Close();
1.3118 + par0.Close();
1.3119 + parT.Close();
1.3120 + parN.Close();
1.3121 + parTN.Close();
1.3122 + delete picLog0;
1.3123 + delete picLog1;
1.3124 + delete picLog2;
1.3125 + delete picLog3;
1.3126 + delete picLog4;
1.3127 + delete picLog5;
1.3128 + }
1.3129 +
1.3130 +void TestEditorUndo::Test8L()
1.3131 + {
1.3132 + // test bookmarking
1.3133 + for (TInt i = 0; i != 7; ++i)
1.3134 + {
1.3135 + testEd->Reset();
1.3136 + ed->ResetUndo();
1.3137 + if (i == 0)
1.3138 + manager->SetBookmark();
1.3139 + testEd->Print(*log);
1.3140 + bookMarkLog0 = log->GetStore();
1.3141 + ed->InsertTextL(0, _L("Hallo"), 0, 0, 0); // hallo
1.3142 + if (i == 1)
1.3143 + manager->SetBookmark();
1.3144 + testEd->Print(*log);
1.3145 + bookMarkLog1 = log->GetStore();
1.3146 + ed->DeleteTextL(2, 1); // halo
1.3147 + if (i == 2)
1.3148 + manager->SetBookmark();
1.3149 + testEd->Print(*log);
1.3150 + bookMarkLog2 = log->GetStore();
1.3151 + manager->BeginBatchLC();
1.3152 + ed->DeleteTextL(3, 1); // hal
1.3153 + ed->InsertTextL(3, _L("t, who goes there?"), 0, 0, 0); // halt, who goes there?
1.3154 + if (i == 3)
1.3155 + manager->SetBookmark(); // should not get set
1.3156 + ed->DeleteTextL(9, 5); // halt, who there?
1.3157 + CleanupStack::PopAndDestroy();
1.3158 + if (i == 4)
1.3159 + manager->SetBookmark();
1.3160 + testEd->Print(*log);
1.3161 + bookMarkLog3 = log->GetStore();
1.3162 + ed->InsertTextL(0, _L("Oi"), 0, 0, 0);
1.3163 + if (i == 5)
1.3164 + manager->SetBookmark();
1.3165 + testEd->Print(*log);
1.3166 + bookMarkLog4 = log->GetStore();
1.3167 + ed->InsertTextL(2, _L("! "), 0, 0, 0);
1.3168 + testEd->Print(*log);
1.3169 + bookMarkLog5 = log->GetStore();
1.3170 + if (i == 6)
1.3171 + manager->SetBookmark();
1.3172 +
1.3173 + ed->UndoL();
1.3174 + // coalescence should have happenned unless there is a bookmark
1.3175 + // in the way.
1.3176 + if (i == 5)
1.3177 + {
1.3178 + TESTPOINT(manager->IsAtBookmark());
1.3179 + check->SetCheckString(*bookMarkLog4);
1.3180 + testEd->Print(*check);
1.3181 + CheckEditorLog(*check);
1.3182 + ed->UndoL();
1.3183 + }
1.3184 + if (i == 4)
1.3185 + TESTPOINT(manager->IsAtBookmark());
1.3186 + else
1.3187 + TESTPOINT(!manager->IsAtBookmark());
1.3188 + check->SetCheckString(*bookMarkLog3);
1.3189 + testEd->Print(*check);
1.3190 + CheckEditorLog(*check);
1.3191 + ed->UndoL();
1.3192 + if (i == 2)
1.3193 + TESTPOINT(manager->IsAtBookmark());
1.3194 + else
1.3195 + TESTPOINT(!manager->IsAtBookmark());
1.3196 + check->SetCheckString(*bookMarkLog2);
1.3197 + testEd->Print(*check);
1.3198 + CheckEditorLog(*check);
1.3199 + ed->UndoL();
1.3200 + if (i == 1)
1.3201 + TESTPOINT(manager->IsAtBookmark());
1.3202 + else
1.3203 + TESTPOINT(!manager->IsAtBookmark());
1.3204 + check->SetCheckString(*bookMarkLog1);
1.3205 + testEd->Print(*check);
1.3206 + CheckEditorLog(*check);
1.3207 + ed->UndoL();
1.3208 + if (i == 0)
1.3209 + TESTPOINT(manager->IsAtBookmark());
1.3210 + else
1.3211 + TESTPOINT(!manager->IsAtBookmark());
1.3212 + check->SetCheckString(*bookMarkLog0);
1.3213 + testEd->Print(*check);
1.3214 + CheckEditorLog(*check);
1.3215 + TESTPOINT(!ed->CanUndo());
1.3216 + ed->RedoL();
1.3217 + if (i == 1)
1.3218 + TESTPOINT(manager->IsAtBookmark());
1.3219 + else
1.3220 + TESTPOINT(!manager->IsAtBookmark());
1.3221 + check->SetCheckString(*bookMarkLog1);
1.3222 + testEd->Print(*check);
1.3223 + CheckEditorLog(*check);
1.3224 + ed->RedoL();
1.3225 + if (i == 2)
1.3226 + TESTPOINT(manager->IsAtBookmark());
1.3227 + else
1.3228 + TESTPOINT(!manager->IsAtBookmark());
1.3229 + check->SetCheckString(*bookMarkLog2);
1.3230 + testEd->Print(*check);
1.3231 + CheckEditorLog(*check);
1.3232 + ed->RedoL();
1.3233 + if (i == 4)
1.3234 + TESTPOINT(manager->IsAtBookmark());
1.3235 + else
1.3236 + TESTPOINT(!manager->IsAtBookmark());
1.3237 + check->SetCheckString(*bookMarkLog3);
1.3238 + testEd->Print(*check);
1.3239 + CheckEditorLog(*check);
1.3240 + ed->RedoL();
1.3241 + if (i == 5)
1.3242 + {
1.3243 + TESTPOINT(manager->IsAtBookmark());
1.3244 + check->SetCheckString(*bookMarkLog4);
1.3245 + testEd->Print(*check);
1.3246 + CheckEditorLog(*check);
1.3247 + ed->RedoL();
1.3248 + }
1.3249 + TESTPOINT(!ed->CanRedo());
1.3250 + if (i == 6)
1.3251 + TESTPOINT(manager->IsAtBookmark());
1.3252 + else
1.3253 + TESTPOINT(!manager->IsAtBookmark());
1.3254 +
1.3255 + delete bookMarkLog0;
1.3256 + delete bookMarkLog1;
1.3257 + delete bookMarkLog2;
1.3258 + delete bookMarkLog3;
1.3259 + delete bookMarkLog4;
1.3260 + delete bookMarkLog5;
1.3261 + }
1.3262 +
1.3263 + delete ed;
1.3264 + delete testEd;
1.3265 + delete log;
1.3266 + delete check;
1.3267 + }
1.3268 +
1.3269 +void TestEditorUndoL()
1.3270 + {
1.3271 + __UHEAP_MARK;
1.3272 +
1.3273 + TestEditorUndo t;
1.3274 + t.Test1L();
1.3275 + t.Test2L();
1.3276 + t.Test3L();
1.3277 + t.Test4L();
1.3278 + t.Test5L();
1.3279 + t.Test6L();
1.3280 + t.Test7L();
1.3281 + t.Test8L();
1.3282 +
1.3283 + __UHEAP_MARKENDC(0);
1.3284 + }
1.3285 +// integration of command manager with multiple editors
1.3286 +void TestMultipleEditorsL()
1.3287 + {
1.3288 + __UHEAP_MARK;
1.3289 +
1.3290 + CCheckingLogger* check = new(ELeave) CCheckingLogger;
1.3291 + CStoringLogger* log = new(ELeave) CStoringLogger;
1.3292 +
1.3293 + CTestEditor* testEd0 = CTestEditor::NewL();
1.3294 + CTestEditor* testEd1 = CTestEditor::NewL();
1.3295 + CTestEditor* testEd2 = CTestEditor::NewL();
1.3296 + CTestEditor* testEd3 = CTestEditor::NewL();
1.3297 + CCommandManager* manager = CCommandManager::NewL();
1.3298 +
1.3299 + CEditorPlainTextWithUndo* ed0 =
1.3300 + CEditorPlainTextWithUndo::NewL(*testEd0, manager);
1.3301 + CEditorWithUndo* ed1 = CEditorWithUndo::NewL(*testEd1, manager);
1.3302 + CEditorPlainTextWithUndo* ed2 =
1.3303 + CEditorPlainTextWithUndo::NewL(*testEd2, manager);
1.3304 + CEditorWithUndo* ed3 = CEditorWithUndo::NewL(*testEd3, manager);
1.3305 + manager->Release();
1.3306 +
1.3307 + // Testing the API's of CEditorPlainTextWithUndo
1.3308 + TTmCharFormatMask charBIMask;
1.3309 + charBIMask.iFlags = TTmCharFormatMask::EItalic | TTmCharFormatMask::EBold;
1.3310 + TOpenFontFaceAttribBase attrib;
1.3311 + TTmCharFormat charB;
1.3312 + attrib.SetBold(ETrue);
1.3313 + charB.iFontSpec.SetAttrib(attrib);
1.3314 + TTmCharFormatLayer charLayer;
1.3315 + charLayer.iFormat = charB;
1.3316 + charLayer.iMask = charBIMask;
1.3317 + TTmParFormatMask parTMask;
1.3318 + parTMask.iFlags = TTmParFormatMask::EKeepTogether;
1.3319 + RTmParFormat parT;
1.3320 + parT.iFlags = RTmParFormat::EKeepTogether;
1.3321 + RTmParFormatLayer parLayer;
1.3322 + parLayer.iMask = parTMask;
1.3323 +
1.3324 + //Setting the base, character and paragraph format and then inserting the text
1.3325 + ed0->SetBaseFormatL(charB,parT);
1.3326 + ed0->SetCharFormatL(0, 1, charLayer);
1.3327 + ed0->SetParFormatL(0, 1, parLayer);
1.3328 +
1.3329 + // The main thing to check is that no commands coalesce that have
1.3330 + // different targets which would if their targets matched. The
1.3331 + // commands that can coalesce are Delete Text, Delete Plain Text,
1.3332 + // Insert Text, Insert Plain Text, Delete Character Format, Delete
1.3333 + // Paragraph Format.
1.3334 + ed0->InsertTextL(0, _L("ab"), 0, 0, 0);
1.3335 + testEd0->Print(*log);
1.3336 + HBufC* log00 = log->GetStore();
1.3337 + ed2->InsertTextL(0, _L("cd"), 0, 0, 0);
1.3338 + testEd2->Print(*log);
1.3339 + HBufC* log20 = log->GetStore();
1.3340 + ed1->InsertTextL(0, _L("ef"), 0, 0, 0);
1.3341 + testEd1->Print(*log);
1.3342 + HBufC* log10 = log->GetStore();
1.3343 + ed3->InsertTextL(0, _L("gh"), 0, 0, 0);
1.3344 + testEd3->Print(*log);
1.3345 + HBufC* log30 = log->GetStore();
1.3346 +
1.3347 + manager->UndoL();
1.3348 + check->SetCheckString(*log10);
1.3349 + testEd1->Print(*check);
1.3350 + CheckEditorLog(*check);
1.3351 +
1.3352 + manager->UndoL();
1.3353 + check->SetCheckString(*log20);
1.3354 + testEd2->Print(*check);
1.3355 + CheckEditorLog(*check);
1.3356 +
1.3357 + manager->UndoL();
1.3358 + check->SetCheckString(*log00);
1.3359 + testEd0->Print(*check);
1.3360 + CheckEditorLog(*check);
1.3361 +
1.3362 + manager->UndoL();
1.3363 + TestCannotUndo(*manager);
1.3364 +
1.3365 + manager->RedoL();
1.3366 + check->SetCheckString(*log00);
1.3367 + testEd0->Print(*check);
1.3368 + CheckEditorLog(*check);
1.3369 +
1.3370 + manager->RedoL();
1.3371 + check->SetCheckString(*log20);
1.3372 + testEd2->Print(*check);
1.3373 + CheckEditorLog(*check);
1.3374 +
1.3375 + manager->RedoL();
1.3376 + check->SetCheckString(*log10);
1.3377 + testEd1->Print(*check);
1.3378 + CheckEditorLog(*check);
1.3379 +
1.3380 + manager->RedoL();
1.3381 + check->SetCheckString(*log30);
1.3382 + testEd3->Print(*check);
1.3383 + CheckEditorLog(*check);
1.3384 + TestCannotRedo(*manager);
1.3385 +
1.3386 + ed0->DeleteTextL(1, 1);
1.3387 + testEd0->Print(*log);
1.3388 + HBufC* log01 = log->GetStore();
1.3389 + ed2->DeleteTextL(0, 1);
1.3390 + testEd2->Print(*log);
1.3391 + HBufC* log21 = log->GetStore();
1.3392 + ed3->DeleteTextL(0, 1);
1.3393 + testEd3->Print(*log);
1.3394 + HBufC* log31 = log->GetStore();
1.3395 + ed1->DeleteTextL(0, 1);
1.3396 + testEd1->Print(*log);
1.3397 + HBufC* log11 = log->GetStore();
1.3398 +
1.3399 + manager->UndoL();
1.3400 + check->SetCheckString(*log31);
1.3401 + testEd3->Print(*check);
1.3402 + CheckEditorLog(*check);
1.3403 +
1.3404 + manager->UndoL();
1.3405 + check->SetCheckString(*log21);
1.3406 + testEd2->Print(*check);
1.3407 + CheckEditorLog(*check);
1.3408 +
1.3409 + manager->UndoL();
1.3410 + check->SetCheckString(*log01);
1.3411 + testEd0->Print(*check);
1.3412 + CheckEditorLog(*check);
1.3413 +
1.3414 + manager->UndoL();
1.3415 + check->SetCheckString(*log30);
1.3416 + testEd3->Print(*check);
1.3417 + CheckEditorLog(*check);
1.3418 +
1.3419 + manager->RedoL();
1.3420 + check->SetCheckString(*log01);
1.3421 + testEd0->Print(*check);
1.3422 + CheckEditorLog(*check);
1.3423 +
1.3424 + manager->RedoL();
1.3425 + check->SetCheckString(*log21);
1.3426 + testEd2->Print(*check);
1.3427 + CheckEditorLog(*check);
1.3428 +
1.3429 + manager->RedoL();
1.3430 + check->SetCheckString(*log31);
1.3431 + testEd3->Print(*check);
1.3432 + CheckEditorLog(*check);
1.3433 +
1.3434 + manager->RedoL();
1.3435 + check->SetCheckString(*log11);
1.3436 + testEd1->Print(*check);
1.3437 + CheckEditorLog(*check);
1.3438 + TestCannotRedo(*manager);
1.3439 +
1.3440 + parLayer.iFormat.CopyL(parT);
1.3441 +
1.3442 + //Getting the base format to check if it is set accordingly
1.3443 + TTmCharFormat charB1;
1.3444 + RTmParFormat parT1;
1.3445 + ed0->GetBaseFormatL(charB1,parT1);
1.3446 + TESTPOINT(charB1==charB);
1.3447 + TESTPOINT(parT1==parT);
1.3448 +
1.3449 + //Getting the character format
1.3450 + TTmCharFormatLayer charLayer1;
1.3451 + MUnifiedEditor::TFormatLevel level=MUnifiedEditor::EEffective;
1.3452 + TInt runLen=10;
1.3453 + ed0->GetCharFormat(0,level,charLayer1,runLen);
1.3454 +
1.3455 + //Getting the paragraph format
1.3456 + RTmParFormatLayer parLayer1;
1.3457 + ed0->GetParFormatL(0,level,parLayer1,runLen);
1.3458 +
1.3459 + //Getting the text
1.3460 + TPtrC text;
1.3461 + ed0->GetText(0,text);
1.3462 + TESTPOINT(text==_L("a"));
1.3463 +
1.3464 + //Deleting the formating
1.3465 + ed0->DeleteCharFormatL(0,1);
1.3466 + ed0->DeleteParFormatL(0,1);
1.3467 +
1.3468 + // To test CEditorCommandSetBaseFormat class
1.3469 + // SetBaseFormatL calls CEditorCommandSetBaseFormatProto::CreateInverseL() which in turn calls CEditorCommandSetBaseFormat::NewL().
1.3470 + ed1->SetBaseFormatL(charB,parT);
1.3471 + ed1->SetCharFormatL(0, 1, charLayer);
1.3472 +
1.3473 + testEd1->Print(*log);
1.3474 + HBufC* log12 = log->GetStore();
1.3475 + ed3->SetCharFormatL(0, 1 ,charLayer);
1.3476 + testEd3->Print(*log);
1.3477 + HBufC* log32 = log->GetStore();
1.3478 + ed3->SetParFormatL(0, 1, parLayer);
1.3479 + testEd3->Print(*log);
1.3480 + HBufC* log33 = log->GetStore();
1.3481 + ed1->SetParFormatL(0, 1, parLayer);
1.3482 + testEd1->Print(*log);
1.3483 + HBufC* log13 = log->GetStore();
1.3484 +
1.3485 + manager->UndoL();
1.3486 + check->SetCheckString(*log33);
1.3487 + testEd3->Print(*check);
1.3488 + CheckEditorLog(*check);
1.3489 +
1.3490 + manager->UndoL();
1.3491 + check->SetCheckString(*log32);
1.3492 + testEd3->Print(*check);
1.3493 + CheckEditorLog(*check);
1.3494 +
1.3495 + manager->UndoL();
1.3496 + check->SetCheckString(*log12);
1.3497 + testEd1->Print(*check);
1.3498 + CheckEditorLog(*check);
1.3499 +
1.3500 + manager->RedoL();
1.3501 + check->SetCheckString(*log32);
1.3502 + testEd3->Print(*check);
1.3503 + CheckEditorLog(*check);
1.3504 +
1.3505 + manager->RedoL();
1.3506 + check->SetCheckString(*log33);
1.3507 + testEd3->Print(*check);
1.3508 + CheckEditorLog(*check);
1.3509 +
1.3510 + manager->RedoL();
1.3511 + check->SetCheckString(*log13);
1.3512 + testEd1->Print(*check);
1.3513 + CheckEditorLog(*check);
1.3514 +
1.3515 + parLayer.Close();
1.3516 + parT.Close();
1.3517 + delete log00;
1.3518 + delete log10;
1.3519 + delete log20;
1.3520 + delete log30;
1.3521 + delete log01;
1.3522 + delete log11;
1.3523 + delete log21;
1.3524 + delete log31;
1.3525 + delete log12;
1.3526 + delete log13;
1.3527 + delete log32;
1.3528 + delete log33;
1.3529 + manager->ResetUndo();
1.3530 + delete ed0;
1.3531 + delete ed1;
1.3532 + delete ed2;
1.3533 + delete ed3;
1.3534 + delete testEd0;
1.3535 + delete testEd1;
1.3536 + delete testEd2;
1.3537 + delete testEd3;
1.3538 + delete log;
1.3539 + delete check;
1.3540 +
1.3541 + __UHEAP_MARKENDC(0);
1.3542 + }
1.3543 +
1.3544 +//
1.3545 +//
1.3546 +// Main
1.3547 +//
1.3548 +//
1.3549 +
1.3550 +TVerdict CTUndoStep::doTestStepL()
1.3551 + {
1.3552 + SetTestStepResult(EPass);
1.3553 + TestStep = this;
1.3554 + TESTPRINT(_L("TUndo - Undo system"));
1.3555 +
1.3556 + __UHEAP_MARK;
1.3557 + TESTPRINT(_L("@SYMTestCaseID:SYSLIB-FORM-LEGACY-UNDO-0001 Undo System Tests: "));
1.3558 +
1.3559 + // test of general undo system components
1.3560 + TestCCommandStackL();
1.3561 + TestCBatchCommandL();
1.3562 + TestCCommandHistoryL();
1.3563 + TestCCommandManagerL();
1.3564 +
1.3565 + // test of editor undo components
1.3566 + TestEditorUndoL();
1.3567 +
1.3568 + // test that command manager and multiple editors integrate correctly
1.3569 + TestMultipleEditorsL();
1.3570 +
1.3571 + __UHEAP_MARKENDC(0);
1.3572 +
1.3573 + return TestStepResult();
1.3574 + }
1.3575 +