os/textandloc/textrendering/textformatting/test/src/TUndo.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2000-2010 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description: 
sl@0
    15
* TUndo.cpp test file for UndoSystem classes
sl@0
    16
*
sl@0
    17
*/
sl@0
    18
sl@0
    19
sl@0
    20
#include <e32test.h>
sl@0
    21
sl@0
    22
#include "UndoSystem.h"
sl@0
    23
#include "UndoSystemImpl.h"
sl@0
    24
#include "EditorUndo.h"
sl@0
    25
#include "EditorPlainTextUndo.h"
sl@0
    26
#include <txtetext.h>
sl@0
    27
#include <conpics.h>
sl@0
    28
#include <s32mem.h>
sl@0
    29
#include <s32ucmp.h>
sl@0
    30
#include "TGraphicsContext.h"
sl@0
    31
#include "form_and_etext_editor.h"
sl@0
    32
sl@0
    33
#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
sl@0
    34
#include <txtclipboard.h>
sl@0
    35
#include "txtfmlyr_internal.h"
sl@0
    36
#endif
sl@0
    37
sl@0
    38
#include "tundo.h"
sl@0
    39
sl@0
    40
#define UNUSED_VAR(a) a = a
sl@0
    41
sl@0
    42
using namespace UndoSystem;
sl@0
    43
sl@0
    44
namespace
sl@0
    45
{
sl@0
    46
CTUndoStep* TestStep = NULL;
sl@0
    47
#define TESTPOINT(p) TestStep->testpoint(p,(TText8*)__FILE__,__LINE__)
sl@0
    48
#define TESTPRINT(p) TestStep->print(p,(TText8*)__FILE__,__LINE__)
sl@0
    49
}
sl@0
    50
sl@0
    51
//
sl@0
    52
//
sl@0
    53
//  logger
sl@0
    54
//
sl@0
    55
//
sl@0
    56
sl@0
    57
class CLogger : public CBase
sl@0
    58
	{
sl@0
    59
public:
sl@0
    60
	virtual void Output(const TDesC& aText) = 0;
sl@0
    61
	void Output(TInt a)
sl@0
    62
		{
sl@0
    63
		TBuf<16> num(_L("<"));
sl@0
    64
		num.AppendNum(a);
sl@0
    65
		num.Append(_L(">"));
sl@0
    66
		Output(num);
sl@0
    67
		}
sl@0
    68
	};
sl@0
    69
sl@0
    70
namespace
sl@0
    71
{
sl@0
    72
CLogger& operator<<(CLogger& aLog, const TDesC& aText)
sl@0
    73
	{
sl@0
    74
	aLog.Output(aText);
sl@0
    75
	return aLog;
sl@0
    76
	}
sl@0
    77
CLogger& operator<<(CLogger& aLog, TInt aVal)
sl@0
    78
	{
sl@0
    79
	aLog.Output(aVal);
sl@0
    80
	return aLog;
sl@0
    81
	}
sl@0
    82
}
sl@0
    83
sl@0
    84
class CCheckingLogger : public CLogger
sl@0
    85
	{
sl@0
    86
	const TDesC*	iCheck;
sl@0
    87
	TInt			iPos;
sl@0
    88
	TBool			iFailed;
sl@0
    89
public:
sl@0
    90
	void SetCheckString(const TDesC& aCheck) { iCheck = &aCheck; iPos = 0; iFailed = EFalse; }
sl@0
    91
	TBool Failed() { return iFailed; }
sl@0
    92
	TBool Passed() { return !iFailed && iCheck && iCheck->Length() == iPos; }
sl@0
    93
	void Output(const TDesC& aText)
sl@0
    94
		{
sl@0
    95
		if (!iCheck || iFailed)
sl@0
    96
			return;
sl@0
    97
		TInt length = aText.Length();
sl@0
    98
		TInt maxLength = iCheck->Length() - iPos;
sl@0
    99
		TPtrC mid = iCheck->Mid(iPos, length < maxLength? length : maxLength);
sl@0
   100
		if (aText.Compare(mid) != 0)
sl@0
   101
			iFailed = ETrue;
sl@0
   102
		else
sl@0
   103
			iPos += aText.Length();
sl@0
   104
		}
sl@0
   105
	};
sl@0
   106
sl@0
   107
class CStoringLogger : public CLogger
sl@0
   108
	{
sl@0
   109
	HBufC*	iStore;
sl@0
   110
	TInt	iMaxLength;
sl@0
   111
public:
sl@0
   112
	~CStoringLogger() { delete iStore; }
sl@0
   113
	HBufC* GetStore() { HBufC* r = iStore; iStore = 0; iMaxLength = 0; return r; }
sl@0
   114
	void Output(const TDesC& aText)
sl@0
   115
		{
sl@0
   116
		if (!iStore)
sl@0
   117
			{
sl@0
   118
			iStore = HBufC::NewL(50);
sl@0
   119
			iMaxLength = 50;
sl@0
   120
			}
sl@0
   121
		while (iMaxLength < aText.Length() + iStore->Length())
sl@0
   122
			{
sl@0
   123
			iMaxLength *= 2;
sl@0
   124
			iStore = iStore->ReAllocL(iMaxLength);
sl@0
   125
			}
sl@0
   126
		iStore->Des().Append(aText);
sl@0
   127
		};
sl@0
   128
	};
sl@0
   129
sl@0
   130
//
sl@0
   131
//
sl@0
   132
//  commands
sl@0
   133
//
sl@0
   134
//
sl@0
   135
sl@0
   136
// internal commands
sl@0
   137
class CCommandOffset;
sl@0
   138
class CCommandToggle;
sl@0
   139
class CTestCommand : public CSingleCommand
sl@0
   140
	{
sl@0
   141
public:
sl@0
   142
	TUid FamilyUid() const
sl@0
   143
		{
sl@0
   144
		return TUid::Uid(12345);
sl@0
   145
		}
sl@0
   146
	virtual CCommandOffset* CastToCCommandOffset() { return 0; }
sl@0
   147
	virtual CCommandToggle* CastToCCommandToggle() { return 0; }
sl@0
   148
	};
sl@0
   149
sl@0
   150
// Offset
sl@0
   151
class CCommandOffset : public CTestCommand
sl@0
   152
	{
sl@0
   153
	TInt	iOffset;
sl@0
   154
	TInt*	iTarget;
sl@0
   155
	CLogger* iLogger;
sl@0
   156
	CCommandOffset() {}
sl@0
   157
public:
sl@0
   158
	static CCommandOffset* NewL(TInt aOffset, TInt* aTarget, CLogger* aLogger = 0)
sl@0
   159
		{
sl@0
   160
		CCommandOffset* r = new(ELeave) CCommandOffset;
sl@0
   161
		r->iOffset = aOffset;
sl@0
   162
		r->iTarget = aTarget;
sl@0
   163
		r->iLogger = aLogger;
sl@0
   164
		return r;
sl@0
   165
		}
sl@0
   166
	void SetLogger(CLogger* aLogger) { iLogger = aLogger; }
sl@0
   167
	TInt ExecuteL() const
sl@0
   168
		{
sl@0
   169
		if (iLogger)
sl@0
   170
			(*iLogger) << _L("offset") << iOffset;
sl@0
   171
		*iTarget += iOffset;
sl@0
   172
		return KErrNone;
sl@0
   173
		}
sl@0
   174
	CCommand* CreateInverseL() const
sl@0
   175
		{
sl@0
   176
		return NewL(-iOffset, iTarget, iLogger);
sl@0
   177
		}
sl@0
   178
	void Add(TInt aOffset) { iOffset += aOffset; }
sl@0
   179
	CCommandOffset* CastToCCommandOffset() { return this; }
sl@0
   180
	};
sl@0
   181
sl@0
   182
// Negate (only if iTog is ETrue!)
sl@0
   183
class CCommandToggle : public CTestCommand
sl@0
   184
	{
sl@0
   185
	TBool iTog;
sl@0
   186
	TInt* iTarget;
sl@0
   187
	CLogger* iLogger;
sl@0
   188
	CCommandToggle() {}
sl@0
   189
public:
sl@0
   190
	static CCommandToggle* NewL(TBool aTog, TInt* aTarget, CLogger* aLogger = 0)
sl@0
   191
		{
sl@0
   192
		CCommandToggle* r = new(ELeave) CCommandToggle;
sl@0
   193
		r->iTog = aTog;
sl@0
   194
		r->iTarget = aTarget;
sl@0
   195
		r->iLogger = aLogger;
sl@0
   196
		return r;
sl@0
   197
		}
sl@0
   198
	void SetLogger(CLogger* aLogger) { iLogger = aLogger; }
sl@0
   199
	TInt ExecuteL() const
sl@0
   200
		{
sl@0
   201
		if (iLogger)
sl@0
   202
			{
sl@0
   203
			(*iLogger) << _L("negate") << (iTog? 1:0);
sl@0
   204
			}
sl@0
   205
		if (iTog)
sl@0
   206
			*iTarget = -*iTarget;
sl@0
   207
		return KErrNone;
sl@0
   208
		}
sl@0
   209
	CCommand* CreateInverseL() const
sl@0
   210
		{
sl@0
   211
		return NewL(iTog, iTarget, iLogger);
sl@0
   212
		}
sl@0
   213
	void Add(TBool aTog)
sl@0
   214
		{
sl@0
   215
		if (aTog)
sl@0
   216
			iTog = !iTog;
sl@0
   217
		}
sl@0
   218
	CCommandToggle* CastToCCommandToggle() { return this; }
sl@0
   219
	};
sl@0
   220
sl@0
   221
// command prototypes
sl@0
   222
class CCommandIncProto : public CTestCommand
sl@0
   223
	{
sl@0
   224
	TInt*		iTarget;
sl@0
   225
	CLogger*	iLogger;
sl@0
   226
	CCommandIncProto() {}
sl@0
   227
public:
sl@0
   228
	static CCommandIncProto* NewL(TInt* aTarget, CLogger* aLogger = 0)
sl@0
   229
		{
sl@0
   230
		CCommandIncProto* r = new(ELeave) CCommandIncProto;
sl@0
   231
		r->iTarget = aTarget;
sl@0
   232
		r->iLogger = aLogger;
sl@0
   233
		return r;
sl@0
   234
		}
sl@0
   235
	TInt ExecuteL() const
sl@0
   236
		{
sl@0
   237
		if (iLogger)
sl@0
   238
			(*iLogger) << _L("inc<>");
sl@0
   239
		++*iTarget;
sl@0
   240
		return KErrNone;
sl@0
   241
		}
sl@0
   242
	CCommand* CreateInverseL() const
sl@0
   243
		{
sl@0
   244
		return CCommandOffset::NewL(-1, iTarget, iLogger);
sl@0
   245
		}
sl@0
   246
	TBool PrepareToAddInverseToLastL(CSingleCommand& aLastCommand) const
sl@0
   247
		{
sl@0
   248
		if (aLastCommand.FamilyUid() != TUid::Uid(12345))
sl@0
   249
			return EFalse;
sl@0
   250
		return !!static_cast<CTestCommand&>(aLastCommand).CastToCCommandOffset();
sl@0
   251
		}
sl@0
   252
	void AddInverseToLast(CSingleCommand& aLastCommand) const
sl@0
   253
		{
sl@0
   254
		CCommandOffset* c =
sl@0
   255
			static_cast<CTestCommand&>(aLastCommand).CastToCCommandOffset();
sl@0
   256
		ASSERT(c);
sl@0
   257
		c->Add(-1);
sl@0
   258
		}
sl@0
   259
	};
sl@0
   260
sl@0
   261
class CCommandDecProto : public CTestCommand
sl@0
   262
	{
sl@0
   263
	TInt*		iTarget;
sl@0
   264
	CLogger*	iLogger;
sl@0
   265
	CCommandDecProto() {}
sl@0
   266
public:
sl@0
   267
	static CCommandDecProto* NewL(TInt* aTarget, CLogger* aLogger = 0)
sl@0
   268
		{
sl@0
   269
		CCommandDecProto* r = new(ELeave) CCommandDecProto;
sl@0
   270
		r->iTarget = aTarget;
sl@0
   271
		r->iLogger = aLogger;
sl@0
   272
		return r;
sl@0
   273
		}
sl@0
   274
	TInt ExecuteL() const
sl@0
   275
		{
sl@0
   276
		if (iLogger)
sl@0
   277
			(*iLogger) << _L("dec<>");
sl@0
   278
		--*iTarget;
sl@0
   279
		return KErrNone;
sl@0
   280
		}
sl@0
   281
	CCommand* CreateInverseL() const
sl@0
   282
		{
sl@0
   283
		return CCommandOffset::NewL(1, iTarget, iLogger);
sl@0
   284
		}
sl@0
   285
	TBool PrepareToAddInverseToLastL(CSingleCommand& aLastCommand) const
sl@0
   286
		{
sl@0
   287
		if (aLastCommand.FamilyUid() != TUid::Uid(12345))
sl@0
   288
			return EFalse;
sl@0
   289
		return !!static_cast<CTestCommand&>(aLastCommand).CastToCCommandOffset();
sl@0
   290
		}
sl@0
   291
	void AddInverseToLast(CSingleCommand& aLastCommand) const
sl@0
   292
		{
sl@0
   293
		CCommandOffset* c =
sl@0
   294
			static_cast<CTestCommand&>(aLastCommand).CastToCCommandOffset();
sl@0
   295
		ASSERT(c);
sl@0
   296
		c->Add(1);
sl@0
   297
		}
sl@0
   298
	};
sl@0
   299
sl@0
   300
class CCommandNegProto : public CTestCommand
sl@0
   301
	{
sl@0
   302
	TInt*		iTarget;
sl@0
   303
	CLogger*	iLogger;
sl@0
   304
	CCommandNegProto() {}
sl@0
   305
public:
sl@0
   306
	static CCommandNegProto* NewL(TInt* aTarget, CLogger* aLogger = 0)
sl@0
   307
		{
sl@0
   308
		CCommandNegProto* r = new(ELeave) CCommandNegProto;
sl@0
   309
		r->iTarget = aTarget;
sl@0
   310
		r->iLogger = aLogger;
sl@0
   311
		return r;
sl@0
   312
		}
sl@0
   313
	TInt ExecuteL() const
sl@0
   314
		{
sl@0
   315
		if (iLogger)
sl@0
   316
			(*iLogger) << _L("neg<>");
sl@0
   317
		*iTarget = -*iTarget;
sl@0
   318
		return KErrNone;
sl@0
   319
		}
sl@0
   320
	CCommand* CreateInverseL() const
sl@0
   321
		{
sl@0
   322
		return CCommandToggle::NewL(ETrue, iTarget, iLogger);
sl@0
   323
		}
sl@0
   324
	TBool PrepareToAddInverseToLastL(CSingleCommand& aLastCommand) const
sl@0
   325
		{
sl@0
   326
		if (aLastCommand.FamilyUid() != TUid::Uid(12345))
sl@0
   327
			return EFalse;
sl@0
   328
		return !!static_cast<CTestCommand&>(aLastCommand).CastToCCommandToggle();
sl@0
   329
		}
sl@0
   330
	void AddInverseToLast(CSingleCommand& aLastCommand) const
sl@0
   331
		{
sl@0
   332
		CCommandToggle* c =
sl@0
   333
			static_cast<CTestCommand&>(aLastCommand).CastToCCommandToggle();
sl@0
   334
		ASSERT(c);
sl@0
   335
		c->Add(ETrue);
sl@0
   336
		}
sl@0
   337
	};
sl@0
   338
sl@0
   339
// command whose inverse is a batch command
sl@0
   340
class CCommandDecThenNegProto : public CTestCommand
sl@0
   341
	{
sl@0
   342
	TInt*		iTarget;
sl@0
   343
	CLogger*	iLogger;
sl@0
   344
	CCommandDecThenNegProto() {}
sl@0
   345
public:
sl@0
   346
	static CCommandDecThenNegProto* NewL(TInt* aTarget, CLogger* aLogger = 0)
sl@0
   347
		{
sl@0
   348
		CCommandDecThenNegProto* r = new(ELeave) CCommandDecThenNegProto;
sl@0
   349
		r->iTarget = aTarget;
sl@0
   350
		r->iLogger = aLogger;
sl@0
   351
		return r;
sl@0
   352
		}
sl@0
   353
	TInt ExecuteL() const
sl@0
   354
		{
sl@0
   355
		if (iLogger)
sl@0
   356
			(*iLogger) << _L("decneg<>");
sl@0
   357
		*iTarget = -(*iTarget - 1);
sl@0
   358
		return KErrNone;
sl@0
   359
		}
sl@0
   360
	CCommand* CreateInverseL() const
sl@0
   361
		{
sl@0
   362
		CBatchCommand* batch = CBatchCommand::NewLC();
sl@0
   363
		batch->PushL(CCommandOffset::NewL(1, iTarget, iLogger));
sl@0
   364
		batch->PushL(CCommandToggle::NewL(ETrue, iTarget, iLogger));
sl@0
   365
		CleanupStack::Pop(batch);
sl@0
   366
		return batch;
sl@0
   367
		}
sl@0
   368
	};
sl@0
   369
sl@0
   370
class CCommandCannotDo : public CTestCommand
sl@0
   371
	{
sl@0
   372
	CLogger*	iLogger;
sl@0
   373
public:
sl@0
   374
	static CCommandCannotDo* NewL(CLogger* aLogger)
sl@0
   375
		{
sl@0
   376
		CCommandCannotDo* r = new(ELeave) CCommandCannotDo;
sl@0
   377
		r->iLogger = aLogger;
sl@0
   378
		return r;
sl@0
   379
		}
sl@0
   380
	TInt ExecuteL() const
sl@0
   381
		{
sl@0
   382
		if (iLogger)
sl@0
   383
			(*iLogger) << _L("nodo<>");
sl@0
   384
		return KErrNotSupported;
sl@0
   385
		}
sl@0
   386
	CCommand* CreateInverseL() const
sl@0
   387
		{
sl@0
   388
		return 0;
sl@0
   389
		}
sl@0
   390
	};
sl@0
   391
sl@0
   392
class CCommandCannotInvert : public CTestCommand
sl@0
   393
	{
sl@0
   394
	CLogger*	iLogger;
sl@0
   395
public:
sl@0
   396
	static CCommandCannotInvert* NewL(CLogger* aLogger)
sl@0
   397
		{
sl@0
   398
		CCommandCannotInvert* r = new(ELeave) CCommandCannotInvert;
sl@0
   399
		r->iLogger = aLogger;
sl@0
   400
		return r;
sl@0
   401
		}
sl@0
   402
	TInt ExecuteL() const
sl@0
   403
		{
sl@0
   404
		if (iLogger)
sl@0
   405
			(*iLogger) << _L("noinv<>");
sl@0
   406
		return KErrNone;
sl@0
   407
		}
sl@0
   408
	CCommand* CreateInverseL() const
sl@0
   409
		{
sl@0
   410
		if (iLogger)
sl@0
   411
			(*iLogger) << _L("noinvfail.");
sl@0
   412
		User::Leave(KErrNotSupported);
sl@0
   413
		return 0;
sl@0
   414
		}
sl@0
   415
	};
sl@0
   416
sl@0
   417
class CCommandLeavesInvert : public CTestCommand
sl@0
   418
	{
sl@0
   419
	CLogger*	iLogger;
sl@0
   420
public:
sl@0
   421
	mutable TBool iFail;
sl@0
   422
	static CCommandLeavesInvert* NewL(CLogger* aLogger)
sl@0
   423
		{
sl@0
   424
		CCommandLeavesInvert* r = new(ELeave) CCommandLeavesInvert;
sl@0
   425
		r->iLogger = aLogger;
sl@0
   426
		r->iFail = ETrue;
sl@0
   427
		return r;
sl@0
   428
		}
sl@0
   429
	TInt ExecuteL() const
sl@0
   430
		{
sl@0
   431
		if (iLogger)
sl@0
   432
			(*iLogger) << _L("leaveinv<>");
sl@0
   433
		return KErrNone;
sl@0
   434
		}
sl@0
   435
	CCommand* CreateInverseL() const
sl@0
   436
		{
sl@0
   437
		if (iFail)
sl@0
   438
			{
sl@0
   439
			iFail = EFalse;
sl@0
   440
			if (iLogger)
sl@0
   441
				(*iLogger) << _L("noinvfail.");
sl@0
   442
			User::Leave(KErrNotFound);
sl@0
   443
			}
sl@0
   444
		return 0;
sl@0
   445
		}
sl@0
   446
	};
sl@0
   447
sl@0
   448
class CCommandNoMemory : public CTestCommand
sl@0
   449
	{
sl@0
   450
	CLogger*	iLogger;
sl@0
   451
public:
sl@0
   452
	TBool iFailInvert;
sl@0
   453
	TBool iFailAddToLast;
sl@0
   454
	TBool iFailExecute;
sl@0
   455
	mutable TBool iLogExecuteFailed;
sl@0
   456
sl@0
   457
	static CCommandNoMemory* NewL(CLogger* aLogger)
sl@0
   458
		{
sl@0
   459
		CCommandNoMemory* r = new(ELeave) CCommandNoMemory;
sl@0
   460
		r->iLogger = aLogger;
sl@0
   461
		r->iFailInvert		= ETrue;
sl@0
   462
		r->iFailAddToLast	= ETrue;
sl@0
   463
		r->iFailExecute		= ETrue;
sl@0
   464
		r->iLogExecuteFailed= ETrue;
sl@0
   465
		return r;
sl@0
   466
		}
sl@0
   467
	TInt ExecuteL() const
sl@0
   468
		{
sl@0
   469
		if (iFailExecute)
sl@0
   470
			{
sl@0
   471
			if (iLogger && iLogExecuteFailed)
sl@0
   472
				(*iLogger) << _L("nomemfailexe.");
sl@0
   473
			iLogExecuteFailed = EFalse;
sl@0
   474
			User::Leave(KErrNoMemory);
sl@0
   475
			}
sl@0
   476
		if (iLogger)
sl@0
   477
			(*iLogger) << _L("nomem<>");
sl@0
   478
		return KErrNone;
sl@0
   479
		}
sl@0
   480
	CCommand* CreateInverseL() const
sl@0
   481
		{
sl@0
   482
		if (iFailInvert)
sl@0
   483
			{
sl@0
   484
			if (iLogger)
sl@0
   485
				(*iLogger) << _L("nomemfailinv.");
sl@0
   486
			User::Leave(KErrNoMemory);
sl@0
   487
			}
sl@0
   488
		return 0;
sl@0
   489
		}
sl@0
   490
	TBool PrepareToAddInverseToLastL(CSingleCommand&) const
sl@0
   491
		{
sl@0
   492
		if (iFailAddToLast)
sl@0
   493
			{
sl@0
   494
			if (iLogger)
sl@0
   495
				(*iLogger) << _L("nomemfailadd.");
sl@0
   496
			User::Leave(KErrNoMemory);
sl@0
   497
			}
sl@0
   498
		return EFalse;
sl@0
   499
		}
sl@0
   500
	};
sl@0
   501
sl@0
   502
// this gatekeeper refuses non-undoable requests
sl@0
   503
class CRefuserGatekeeper : public CBase, public MNotUndoableGatekeeper
sl@0
   504
	{
sl@0
   505
public:
sl@0
   506
	TBool RetryOutOfMemoryL(TInt)
sl@0
   507
		{
sl@0
   508
		return EFalse;
sl@0
   509
		}
sl@0
   510
	TBool AllowNotUndoableL(TInt)
sl@0
   511
		{
sl@0
   512
		return EFalse;
sl@0
   513
		}
sl@0
   514
	};
sl@0
   515
sl@0
   516
// this gatekeeper permits all non-undoable requests
sl@0
   517
// (not just KErrNotSupported and KErrNoMemory)
sl@0
   518
class CPermitterGatekeeper : public CBase, public MNotUndoableGatekeeper
sl@0
   519
	{
sl@0
   520
public:
sl@0
   521
	TBool RetryOutOfMemoryL(TInt)
sl@0
   522
		{
sl@0
   523
		return EFalse;
sl@0
   524
		}
sl@0
   525
	TBool AllowNotUndoableL(TInt)
sl@0
   526
		{
sl@0
   527
		return ETrue;
sl@0
   528
		}
sl@0
   529
	};
sl@0
   530
sl@0
   531
// this gatekeeper makes the CCommandNoMemory fail less the more times it is called
sl@0
   532
class CMemoryReclaimGatekeeper : public CRefuserGatekeeper
sl@0
   533
	{
sl@0
   534
public:
sl@0
   535
	CCommandNoMemory* iTarget;
sl@0
   536
	CMemoryReclaimGatekeeper(CCommandNoMemory* aTarget = 0) : iTarget(aTarget) {}
sl@0
   537
	TBool RetryOutOfMemoryL(TInt aNumRetries)
sl@0
   538
		{
sl@0
   539
		if (aNumRetries == 0)
sl@0
   540
			{
sl@0
   541
			iTarget->iFailAddToLast = EFalse;
sl@0
   542
			return ETrue;
sl@0
   543
			}
sl@0
   544
		if (aNumRetries == 1)
sl@0
   545
			{
sl@0
   546
			iTarget->iFailInvert = EFalse;
sl@0
   547
			return ETrue;
sl@0
   548
			}
sl@0
   549
		if (aNumRetries == 2)
sl@0
   550
			{
sl@0
   551
			iTarget->iFailExecute = EFalse;
sl@0
   552
			return ETrue;
sl@0
   553
			}
sl@0
   554
		return EFalse;
sl@0
   555
		}
sl@0
   556
	};
sl@0
   557
sl@0
   558
sl@0
   559
//
sl@0
   560
//
sl@0
   561
//	Editor
sl@0
   562
//
sl@0
   563
//
sl@0
   564
sl@0
   565
// a cut-down set of attributes for testing purposes
sl@0
   566
class CUndoTestPicture : public CPicture
sl@0
   567
	{
sl@0
   568
	TBuf<1> iDesc;
sl@0
   569
public:
sl@0
   570
	CUndoTestPicture(TInt aChar) : iDesc(1) { iDesc[0] = static_cast<TText>(aChar); }
sl@0
   571
	void Draw(CGraphicsContext&, const TPoint&, const TRect&, MGraphicsDeviceMap*) const {}
sl@0
   572
	void ExternalizeL(RWriteStream&) const {}
sl@0
   573
	void GetOriginalSizeInTwips(TSize&) const {}
sl@0
   574
	TPtrC Description() const { return iDesc; }
sl@0
   575
	};
sl@0
   576
sl@0
   577
struct TTestAttributes
sl@0
   578
	{
sl@0
   579
	TInt8 iCharFlags;
sl@0
   580
	TInt8 iParFlags;
sl@0
   581
	TInt8 iStyle;
sl@0
   582
	TTestAttributes() : iCharFlags(0), iParFlags(0), iStyle(-1) {}
sl@0
   583
	TBool operator==(TTestAttributes& a)
sl@0
   584
		{
sl@0
   585
		return iCharFlags == a.iCharFlags && iParFlags == a.iParFlags && iStyle == a.iStyle;
sl@0
   586
		}
sl@0
   587
	};
sl@0
   588
CLogger& operator<<(CLogger& log, TTestAttributes& at)
sl@0
   589
	{
sl@0
   590
	TBuf<3> buf(_L("Aa0"));
sl@0
   591
	buf[0] = (TText)(buf[0] + (at.iCharFlags & 15));
sl@0
   592
	buf[1] = (TText)(buf[1] + (at.iParFlags & 15));
sl@0
   593
	buf[2] = (TText)(buf[2] + at.iStyle);
sl@0
   594
	return log << buf;
sl@0
   595
	}
sl@0
   596
// Test editor, badly behaved if something leaves.
sl@0
   597
// The only formats supported are bold, italic, keep together and keep with next.
sl@0
   598
class CTestEditor : public CBase, public MUnifiedEditor,
sl@0
   599
	public MUnifiedEditor::MStyleSupport,
sl@0
   600
	public MUnifiedEditor::MPictureSupport,
sl@0
   601
	public MUnifiedEditor::MClipboardSupport
sl@0
   602
	{
sl@0
   603
	TTestAttributes iBase;
sl@0
   604
	TTestAttributes iStyles[10];
sl@0
   605
	TBuf<KMaxParagraphStyleName> iStyleNames[10];
sl@0
   606
	TInt iNumStyles;
sl@0
   607
	CArrayFix<TTestAttributes>* iAttrs;
sl@0
   608
	CBufSeg* iText;
sl@0
   609
	CArrayFix<CUndoTestPicture*>* iPics;
sl@0
   610
sl@0
   611
	CTestEditor* ConstructL()
sl@0
   612
		{
sl@0
   613
		iText = CBufSeg::NewL(5 * sizeof(TText));
sl@0
   614
		iAttrs = new(ELeave) CArrayFixFlat<TTestAttributes>(5);
sl@0
   615
		iPics = new(ELeave) CArrayFixFlat<CUndoTestPicture*>(5);
sl@0
   616
		return this;
sl@0
   617
		}
sl@0
   618
	TInt Style(const TDesC& aName) const
sl@0
   619
		{
sl@0
   620
		for (int i = 0; i != iNumStyles; ++i)
sl@0
   621
			if (aName == iStyleNames[i])
sl@0
   622
				return i;
sl@0
   623
		return -1;
sl@0
   624
		}
sl@0
   625
	TInt InsertStylePos(const TDesC& aName) const
sl@0
   626
		{
sl@0
   627
		int i;
sl@0
   628
		for (i = 0; i != iNumStyles; ++i)
sl@0
   629
			if (aName.Compare(iStyleNames[i]) <= 0)
sl@0
   630
				return i;
sl@0
   631
		return i;
sl@0
   632
		}
sl@0
   633
	void ReassignStyles(TInt aFrom, TInt aTo)
sl@0
   634
		{
sl@0
   635
		ASSERT(-1 <= aTo && aTo < iNumStyles);
sl@0
   636
		ASSERT(0 <= aFrom && aFrom < iNumStyles);
sl@0
   637
		if (aTo == aFrom)
sl@0
   638
			return;
sl@0
   639
		TInt setTo	= aTo;
sl@0
   640
		if (aTo == -1)
sl@0
   641
			aTo = iNumStyles - 1;
sl@0
   642
		TInt low	= aFrom;
sl@0
   643
		TInt high	= aTo;
sl@0
   644
		TInt delta	= -1;
sl@0
   645
		if (aTo < aFrom)
sl@0
   646
			{
sl@0
   647
			low		= aTo;
sl@0
   648
			high	= aFrom;
sl@0
   649
			delta	= 1;
sl@0
   650
			}
sl@0
   651
		TInt len = DocumentLength();
sl@0
   652
sl@0
   653
		int i;
sl@0
   654
		for (i = 0; i != len; ++i)
sl@0
   655
			{
sl@0
   656
			TTestAttributes* attr = &iAttrs->At(i);
sl@0
   657
			if (aFrom == attr->iStyle)
sl@0
   658
				attr->iStyle = static_cast<TInt8>(setTo);
sl@0
   659
			else if (low <= attr->iStyle && attr->iStyle <= high)
sl@0
   660
				attr->iStyle = static_cast<TInt8>(attr->iStyle + delta);
sl@0
   661
			}
sl@0
   662
		for (i = aFrom; i != aTo; i -= delta)
sl@0
   663
			{
sl@0
   664
			iStyles[i] = iStyles[i - delta];
sl@0
   665
			iStyleNames[i] = iStyleNames[i - delta];
sl@0
   666
			}
sl@0
   667
		}
sl@0
   668
	void DoDeleteStyle(TInt aForDeletion)
sl@0
   669
		{
sl@0
   670
		ASSERT(aForDeletion < iNumStyles);
sl@0
   671
		ReassignStyles(aForDeletion, -1);
sl@0
   672
		--iNumStyles;
sl@0
   673
		}
sl@0
   674
	void DoAddStyle(const TDesC& aNewName, const TTestAttributes& aAttr)
sl@0
   675
		{
sl@0
   676
		ASSERT(iNumStyles < 10);
sl@0
   677
		TInt pos = InsertStylePos(aNewName);
sl@0
   678
		++iNumStyles;
sl@0
   679
		ReassignStyles(iNumStyles - 1, pos);
sl@0
   680
		iStyles[pos] = aAttr;
sl@0
   681
		iStyleNames[pos] = aNewName;
sl@0
   682
		}
sl@0
   683
	static void BoldToAttr(TTestAttributes& aAttr, const TTmCharFormat& aCFormat)
sl@0
   684
		{
sl@0
   685
		if (aCFormat.iFontSpec.IsBold())
sl@0
   686
			aAttr.iCharFlags |= 1;
sl@0
   687
		else
sl@0
   688
			aAttr.iCharFlags &= ~1;
sl@0
   689
		}
sl@0
   690
	static void ItalicToAttr(TTestAttributes& aAttr, const TTmCharFormat& aCFormat)
sl@0
   691
		{
sl@0
   692
		if (aCFormat.iFontSpec.IsItalic())
sl@0
   693
			aAttr.iCharFlags |= 2;
sl@0
   694
		else
sl@0
   695
			aAttr.iCharFlags &= ~2;
sl@0
   696
		}
sl@0
   697
	static void CharFormatToAttr(TTestAttributes& aAttr, const TTmCharFormat& aCFormat)
sl@0
   698
		{
sl@0
   699
		aAttr.iCharFlags = 0;
sl@0
   700
		BoldToAttr(aAttr, aCFormat);
sl@0
   701
		ItalicToAttr(aAttr, aCFormat);
sl@0
   702
		}
sl@0
   703
	static void CharLayerToAttr(TTestAttributes& aAttr, const TTmCharFormatLayer& aCLayer)
sl@0
   704
		{
sl@0
   705
		if (aCLayer.iMask.iFlags & TTmCharFormatMask::EBold)
sl@0
   706
			{
sl@0
   707
			aAttr.iCharFlags |= 4;
sl@0
   708
			BoldToAttr(aAttr, aCLayer.iFormat);
sl@0
   709
			}
sl@0
   710
		if (aCLayer.iMask.iFlags & TTmCharFormatMask::EItalic)
sl@0
   711
			{
sl@0
   712
			aAttr.iCharFlags |= 8;
sl@0
   713
			ItalicToAttr(aAttr, aCLayer.iFormat);
sl@0
   714
			}
sl@0
   715
		}
sl@0
   716
	static void KeepTogetherToAttr(TTestAttributes& aAttr, const RTmParFormat& aPFormat)
sl@0
   717
		{
sl@0
   718
		if (aPFormat.iFlags & RTmParFormat::EKeepTogether)
sl@0
   719
			aAttr.iParFlags |= 1;
sl@0
   720
		else
sl@0
   721
			aAttr.iParFlags &= ~1;
sl@0
   722
		}
sl@0
   723
	static void KeepWithNextToAttr(TTestAttributes& aAttr, const RTmParFormat& aPFormat)
sl@0
   724
		{
sl@0
   725
		if (aPFormat.iFlags & RTmParFormat::EKeepWithNext)
sl@0
   726
			aAttr.iParFlags |= 2;
sl@0
   727
		else
sl@0
   728
			aAttr.iParFlags &= ~2;
sl@0
   729
		}
sl@0
   730
	static void ParFormatToAttr(TTestAttributes& aAttr, const RTmParFormat& aPFormat)
sl@0
   731
		{
sl@0
   732
		aAttr.iParFlags = 0;
sl@0
   733
		KeepTogetherToAttr(aAttr, aPFormat);
sl@0
   734
		KeepWithNextToAttr(aAttr, aPFormat);
sl@0
   735
		}
sl@0
   736
	static void ParLayerToAttr(TTestAttributes& aAttr, const RTmParFormatLayer& aPLayer)
sl@0
   737
		{
sl@0
   738
		if (aPLayer.iMask.iFlags & TTmParFormatMask::EKeepTogether)
sl@0
   739
			{
sl@0
   740
			aAttr.iParFlags |= 4;
sl@0
   741
			KeepTogetherToAttr(aAttr, aPLayer.iFormat);
sl@0
   742
			}
sl@0
   743
		if (aPLayer.iMask.iFlags & TTmParFormatMask::EKeepWithNext)
sl@0
   744
			{
sl@0
   745
			aAttr.iParFlags |= 8;
sl@0
   746
			KeepWithNextToAttr(aAttr, aPLayer.iFormat);
sl@0
   747
			}
sl@0
   748
		}
sl@0
   749
	static void BoldAttrToCharFormat(TTmCharFormat& aCFormat, const TTestAttributes& aAttr)
sl@0
   750
		{
sl@0
   751
		if (aAttr.iCharFlags & 1)
sl@0
   752
			aCFormat.iFontSpec.SetBold(ETrue);
sl@0
   753
		}
sl@0
   754
	static void ItalicAttrToCharFormat(TTmCharFormat& aCFormat, const TTestAttributes& aAttr)
sl@0
   755
		{
sl@0
   756
		if (aAttr.iCharFlags & 2)
sl@0
   757
			aCFormat.iFontSpec.SetItalic(ETrue);
sl@0
   758
		}
sl@0
   759
	static void ResetCharFormat(TTmCharFormat& aCFormat)
sl@0
   760
		{
sl@0
   761
		TTmCharFormat c;
sl@0
   762
		aCFormat = c;
sl@0
   763
		}
sl@0
   764
	static void AttrToCharFormat(TTmCharFormat& aCFormat, const TTestAttributes& aAttr)
sl@0
   765
		{
sl@0
   766
		ResetCharFormat(aCFormat);
sl@0
   767
		BoldAttrToCharFormat(aCFormat, aAttr);
sl@0
   768
		ItalicAttrToCharFormat(aCFormat, aAttr);
sl@0
   769
		}
sl@0
   770
	static void MergeAttrToCharLayer(TTmCharFormatLayer& aCLayer, const TTestAttributes& aAttr)
sl@0
   771
		{
sl@0
   772
		if (aAttr.iCharFlags & 4)
sl@0
   773
			{
sl@0
   774
			aCLayer.iMask.iFlags |= TTmCharFormatMask::EBold;
sl@0
   775
			BoldAttrToCharFormat(aCLayer.iFormat, aAttr);
sl@0
   776
			}
sl@0
   777
		if (aAttr.iCharFlags & 8)
sl@0
   778
			{
sl@0
   779
			aCLayer.iMask.iFlags |= TTmCharFormatMask::EItalic;
sl@0
   780
			ItalicAttrToCharFormat(aCLayer.iFormat, aAttr);
sl@0
   781
			}
sl@0
   782
		}
sl@0
   783
	static void AttrToCharLayer(TTmCharFormatLayer& aCLayer, const TTestAttributes& aAttr)
sl@0
   784
		{
sl@0
   785
		ResetCharFormat(aCLayer.iFormat);
sl@0
   786
		aCLayer.iMask.iFlags = 0;
sl@0
   787
		MergeAttrToCharLayer(aCLayer, aAttr);
sl@0
   788
		}
sl@0
   789
	static void ResetParFormat(RTmParFormat& aPFormat)
sl@0
   790
		{
sl@0
   791
		RTmParFormat p;
sl@0
   792
		CleanupClosePushL(p);
sl@0
   793
		aPFormat.CopyL(p);
sl@0
   794
		CleanupStack::PopAndDestroy();
sl@0
   795
		}
sl@0
   796
	static void KeepTogetherAttrToParFormat(RTmParFormat& aPFormat, const TTestAttributes& aAttr)
sl@0
   797
		{
sl@0
   798
		if (aAttr.iParFlags & 1)
sl@0
   799
			aPFormat.iFlags |= RTmParFormat::EKeepTogether;
sl@0
   800
		}
sl@0
   801
	static void KeepWithNextAttrToParFormat(RTmParFormat& aPFormat, const TTestAttributes& aAttr)
sl@0
   802
		{
sl@0
   803
		if (aAttr.iParFlags & 2)
sl@0
   804
			aPFormat.iFlags |= RTmParFormat::EKeepWithNext;
sl@0
   805
		}
sl@0
   806
	static void AttrToParFormat(RTmParFormat& aPFormat, const TTestAttributes& aAttr)
sl@0
   807
		{
sl@0
   808
		ResetParFormat(aPFormat);
sl@0
   809
		KeepTogetherAttrToParFormat(aPFormat, aAttr);
sl@0
   810
		KeepWithNextAttrToParFormat(aPFormat, aAttr);
sl@0
   811
		}
sl@0
   812
	static void MergeAttrToParLayer(RTmParFormatLayer& aPLayer, const TTestAttributes& aAttr)
sl@0
   813
		{
sl@0
   814
		if (aAttr.iParFlags & 4)
sl@0
   815
			{
sl@0
   816
			aPLayer.iMask.iFlags |= TTmParFormatMask::EKeepTogether;
sl@0
   817
			KeepTogetherAttrToParFormat(aPLayer.iFormat, aAttr);
sl@0
   818
			}
sl@0
   819
		if (aAttr.iParFlags & 8)
sl@0
   820
			{
sl@0
   821
			aPLayer.iMask.iFlags |= TTmParFormatMask::EKeepWithNext;
sl@0
   822
			KeepWithNextAttrToParFormat(aPLayer.iFormat, aAttr);
sl@0
   823
			}
sl@0
   824
		}
sl@0
   825
	static void AttrToParLayer(RTmParFormatLayer& aPLayer, const TTestAttributes& aAttr)
sl@0
   826
		{
sl@0
   827
		ResetParFormat(aPLayer.iFormat);
sl@0
   828
		aPLayer.iMask.iFlags = 0;
sl@0
   829
		MergeAttrToParLayer(aPLayer, aAttr);
sl@0
   830
		}
sl@0
   831
public:
sl@0
   832
	~CTestEditor()
sl@0
   833
		{
sl@0
   834
		delete iAttrs;
sl@0
   835
		// workaround for CBufSeg bug
sl@0
   836
		if (0 < iText->Size())
sl@0
   837
			iText->Delete(iText->Size() - 1, 1);
sl@0
   838
		delete iText;
sl@0
   839
		delete iPics;
sl@0
   840
		}
sl@0
   841
	static CTestEditor* NewL()	{ return (new(ELeave) CTestEditor)->ConstructL(); }
sl@0
   842
	void Reset()
sl@0
   843
		{
sl@0
   844
		iAttrs->Reset();
sl@0
   845
		iText->Reset();
sl@0
   846
		iPics->Reset();
sl@0
   847
		iNumStyles = 0;
sl@0
   848
		}
sl@0
   849
	void AlterGranularityL(TInt aNewGranularity)
sl@0
   850
		{
sl@0
   851
		CBufSeg* newIText = CBufSeg::NewL(aNewGranularity * sizeof(TText));
sl@0
   852
		CleanupStack::PushL(newIText);
sl@0
   853
		TBuf8<32> transfer;
sl@0
   854
		TInt pos = 0;
sl@0
   855
		while (pos < iText->Size())
sl@0
   856
			{
sl@0
   857
			TInt length = transfer.MaxLength();
sl@0
   858
			if (iText->Size() - pos < length)
sl@0
   859
				length = iText->Size() - pos;
sl@0
   860
			iText->Read(pos, transfer, length);
sl@0
   861
			newIText->InsertL(pos, transfer, length);
sl@0
   862
			pos += transfer.Length();
sl@0
   863
			}
sl@0
   864
		CleanupStack::Pop(newIText);
sl@0
   865
		// workaround for CBufSeg bug
sl@0
   866
		if (0 < iText->Size())
sl@0
   867
			iText->Delete(iText->Size() - 1, 1);
sl@0
   868
		delete iText;
sl@0
   869
		iText = newIText;
sl@0
   870
		}
sl@0
   871
	void Print(CLogger& log)
sl@0
   872
		{
sl@0
   873
		TInt length = DocumentLength();
sl@0
   874
		int i;
sl@0
   875
		log << _L("text{");
sl@0
   876
		for (i = 0; i < length;)
sl@0
   877
			{
sl@0
   878
			TPtrC seg;
sl@0
   879
			GetText(i, seg);
sl@0
   880
			TInt picPos = seg.Locate(CEditableText::EPictureCharacter);
sl@0
   881
			if (0 < picPos)
sl@0
   882
				{
sl@0
   883
				// shorten seg to just before the picture character
sl@0
   884
				TPtrC temp(seg.Ptr(), picPos);
sl@0
   885
				seg.Set(temp);
sl@0
   886
				}
sl@0
   887
			if (0 == picPos)
sl@0
   888
				{
sl@0
   889
				CUndoTestPicture* pic = iPics->At(i);
sl@0
   890
				if (pic)
sl@0
   891
					log << _L("{pic:") << pic->Description() << _L("}");
sl@0
   892
				else
sl@0
   893
					log << _L("{nopic}");
sl@0
   894
				++i;
sl@0
   895
				}
sl@0
   896
			else
sl@0
   897
				{
sl@0
   898
				log << seg;
sl@0
   899
				i += seg.Length();
sl@0
   900
				}
sl@0
   901
			}
sl@0
   902
		log << _L("} styles{");
sl@0
   903
		for(i = 0; i != iNumStyles; ++i)
sl@0
   904
			{
sl@0
   905
			if (i)
sl@0
   906
				log << _L(", ");
sl@0
   907
			log << iStyleNames[i] << _L(":") << iStyles[i];
sl@0
   908
			}
sl@0
   909
		log << _L("} attr{");
sl@0
   910
		for (i = 0; i != length; ++i)
sl@0
   911
			log << iAttrs->At(i);
sl@0
   912
		log << _L("} ");
sl@0
   913
		}
sl@0
   914
	MTmOptionalInterface* Interface(TUint aId)
sl@0
   915
		{
sl@0
   916
		if (aId == KUidMUnifiedEditorStyleSupport)
sl@0
   917
			return static_cast<MUnifiedEditor::MStyleSupport*>(this);
sl@0
   918
		if (aId == KUidMUnifiedEditorPictureSupport)
sl@0
   919
			return static_cast<MUnifiedEditor::MPictureSupport*>(this);
sl@0
   920
		if (aId == KUidMUnifiedEditorClipboardSupport)
sl@0
   921
			return static_cast<MUnifiedEditor::MClipboardSupport*>(this);
sl@0
   922
		return 0;
sl@0
   923
		}
sl@0
   924
sl@0
   925
	void InsertTextL(TInt aPos, const TDesC& aText,
sl@0
   926
					 const TDesC* aStyle,
sl@0
   927
					 const TTmCharFormatLayer* aCharFormat,
sl@0
   928
					 const RTmParFormatLayer* aParFormat)
sl@0
   929
		{
sl@0
   930
		TTestAttributes attr;
sl@0
   931
		attr.iStyle = aStyle? (TInt8)Style(*aStyle) : (TInt8)-1;
sl@0
   932
		if (aCharFormat)
sl@0
   933
			CharLayerToAttr(attr, *aCharFormat);
sl@0
   934
		if (aParFormat)
sl@0
   935
			ParLayerToAttr(attr, *aParFormat);
sl@0
   936
		iText->InsertL(aPos * sizeof(TText), aText.Ptr(), aText.Length() * sizeof(TText));
sl@0
   937
		iAttrs->InsertL(aPos, attr, aText.Length());
sl@0
   938
		CUndoTestPicture* nullPic = 0;
sl@0
   939
		iPics->InsertL(aPos, nullPic, aText.Length());
sl@0
   940
		}
sl@0
   941
	void DeleteTextL(TInt aPos, TInt aLength)
sl@0
   942
		{
sl@0
   943
		iText->Delete(aPos * sizeof(TText), aLength * sizeof(TText));
sl@0
   944
		iAttrs->Delete(aPos, aLength);
sl@0
   945
		for (int i = aPos; i != aPos + aLength; ++i)
sl@0
   946
			delete iPics->At(i);
sl@0
   947
		iPics->Delete(aPos, aLength);
sl@0
   948
		}
sl@0
   949
	void SetBaseFormatL(const TTmCharFormat& aCharFormat,const RTmParFormat& aParFormat)
sl@0
   950
		{
sl@0
   951
		CharFormatToAttr(iBase, aCharFormat);
sl@0
   952
		ParFormatToAttr(iBase, aParFormat);
sl@0
   953
		}
sl@0
   954
	void SetCharFormatL(TInt aPos,TInt aLength,const TTmCharFormatLayer& aFormat)
sl@0
   955
		{
sl@0
   956
		TInt end = aPos + aLength;
sl@0
   957
		if (DocumentLength() < end)
sl@0
   958
			end = DocumentLength();
sl@0
   959
		for (; aPos < end; ++aPos)
sl@0
   960
			CharLayerToAttr(iAttrs->At(aPos), aFormat);
sl@0
   961
		}
sl@0
   962
	void SetParFormatL(TInt aPos,TInt aLength,const RTmParFormatLayer& aFormat)
sl@0
   963
		{
sl@0
   964
		TInt end = aPos + aLength;
sl@0
   965
		if (DocumentLength() < end)
sl@0
   966
			end = DocumentLength();
sl@0
   967
		for (; aPos < end; ++aPos)
sl@0
   968
			ParLayerToAttr(iAttrs->At(aPos), aFormat);
sl@0
   969
		}
sl@0
   970
	void DeleteCharFormatL(TInt aPos,TInt aLength)
sl@0
   971
		{
sl@0
   972
		TInt end = aPos + aLength;
sl@0
   973
		if (DocumentLength() < end)
sl@0
   974
			end = DocumentLength();
sl@0
   975
		for (; aPos < end; ++aPos)
sl@0
   976
			iAttrs->At(aPos).iCharFlags = 0;
sl@0
   977
		}
sl@0
   978
	void DeleteParFormatL(TInt aPos,TInt aLength)
sl@0
   979
		{
sl@0
   980
		TInt end = aPos + aLength;
sl@0
   981
		if (DocumentLength() < end)
sl@0
   982
			end = DocumentLength();
sl@0
   983
		for (; aPos < end; ++aPos)
sl@0
   984
			iAttrs->At(aPos).iParFlags = 0;
sl@0
   985
		}
sl@0
   986
	TInt CreateStyleL(const RTmStyle& aStyle)
sl@0
   987
		{
sl@0
   988
		TInt styleNo = Style(aStyle.iName);
sl@0
   989
		if (0 <= styleNo)
sl@0
   990
			return KErrAlreadyExists;
sl@0
   991
		TTestAttributes newAttr;
sl@0
   992
		CharLayerToAttr(newAttr, aStyle.iCharFormat);
sl@0
   993
		ParLayerToAttr(newAttr, aStyle.iParFormat);
sl@0
   994
		DoAddStyle(aStyle.iName, newAttr);
sl@0
   995
		return KErrNone;
sl@0
   996
		}
sl@0
   997
	TInt ChangeStyleL(const RTmStyle& aStyle)
sl@0
   998
		{
sl@0
   999
		TInt styleNo = Style(aStyle.iName);
sl@0
  1000
		if (styleNo < 0)
sl@0
  1001
			return KErrNotFound;
sl@0
  1002
		iStyles[styleNo] = TTestAttributes();
sl@0
  1003
		CharLayerToAttr(iStyles[styleNo], aStyle.iCharFormat);
sl@0
  1004
		ParLayerToAttr(iStyles[styleNo], aStyle.iParFormat);
sl@0
  1005
		return KErrNone;
sl@0
  1006
		}
sl@0
  1007
	TInt SetStyleL(TInt aPos, TInt aLength, const TDesC& aName)
sl@0
  1008
		{
sl@0
  1009
		TInt styleNo(-1);
sl@0
  1010
		if (aName.Length())
sl@0
  1011
			{
sl@0
  1012
			styleNo = Style(aName);
sl@0
  1013
			if (styleNo < 0)
sl@0
  1014
				return KErrNotFound;
sl@0
  1015
			}
sl@0
  1016
		TInt end = aPos + aLength;
sl@0
  1017
		for (; aPos < end; ++aPos)
sl@0
  1018
			iAttrs->At(aPos).iStyle = (TInt8)styleNo;
sl@0
  1019
		return KErrNone;
sl@0
  1020
		}
sl@0
  1021
	TInt RenameStyleL(const TDesC& aOldName, const TDesC& aNewName)
sl@0
  1022
		{
sl@0
  1023
		TInt oldNo = Style(aOldName);
sl@0
  1024
		if (oldNo < 0)
sl@0
  1025
			return KErrNotFound;
sl@0
  1026
		TTestAttributes temp = iStyles[oldNo];
sl@0
  1027
		TInt newNo = InsertStylePos(aNewName);
sl@0
  1028
		if (oldNo < newNo)
sl@0
  1029
			--newNo;
sl@0
  1030
		ReassignStyles(oldNo, newNo);
sl@0
  1031
		iStyles[newNo] = temp;
sl@0
  1032
		iStyleNames[newNo] = aNewName;
sl@0
  1033
		return KErrNone;
sl@0
  1034
		}
sl@0
  1035
	TInt DeleteStyleL(const TDesC& aName)
sl@0
  1036
		{
sl@0
  1037
		TInt n = Style(aName);
sl@0
  1038
		if (n < 0)
sl@0
  1039
			return KErrNotFound;
sl@0
  1040
		DoDeleteStyle(n);
sl@0
  1041
		return KErrNone;
sl@0
  1042
		}
sl@0
  1043
	void InsertPictureL(TInt aPos, const TPictureHeader& aPictureIn)
sl@0
  1044
		{
sl@0
  1045
		TBuf<1> picChar(1);
sl@0
  1046
		picChar[0] = CEditableText::EPictureCharacter;
sl@0
  1047
		InsertTextL(aPos, picChar, 0, 0, 0);
sl@0
  1048
		iPics->At(aPos) = static_cast<CUndoTestPicture*>(aPictureIn.iPicture.AsPtr());
sl@0
  1049
		}
sl@0
  1050
	void DropPictureL(TInt aPos)
sl@0
  1051
		{
sl@0
  1052
		TPtrC ptr;
sl@0
  1053
		GetText(aPos, ptr);
sl@0
  1054
		if (ptr[0] == CEditableText::EPictureCharacter)
sl@0
  1055
			{
sl@0
  1056
			iPics->At(aPos) = 0;
sl@0
  1057
			DeleteTextL(aPos, 1);
sl@0
  1058
			}
sl@0
  1059
		}
sl@0
  1060
	void Picture(TInt aPos, TPictureHeader& aPictureOut) const
sl@0
  1061
		{
sl@0
  1062
		CPicture* pic = iPics->At(aPos);
sl@0
  1063
		aPictureOut.iPictureType = KUidXzePictureType;
sl@0
  1064
		aPictureOut.iPicture = pic;
sl@0
  1065
		}
sl@0
  1066
	TInt DocumentLength() const
sl@0
  1067
		{
sl@0
  1068
		return iText->Size() / sizeof(TText);
sl@0
  1069
		}
sl@0
  1070
	void GetText(TInt aPos, TPtrC& aText) const
sl@0
  1071
		{
sl@0
  1072
		iText->Compress();
sl@0
  1073
		if (DocumentLength() <= aPos)
sl@0
  1074
			aPos = DocumentLength();
sl@0
  1075
		TPtr8 ptr = iText->Ptr(aPos * sizeof(TText));
sl@0
  1076
		aText.Set((TText*)ptr.Ptr(), ptr.Length()/sizeof(TText));
sl@0
  1077
		}
sl@0
  1078
	void GetBaseFormatL(TTmCharFormat& aCharFormat, RTmParFormat& aParFormat) const
sl@0
  1079
		{
sl@0
  1080
		AttrToCharFormat(aCharFormat, iBase);
sl@0
  1081
		AttrToParFormat(aParFormat, iBase);
sl@0
  1082
		}
sl@0
  1083
	void GetCharFormat(TInt aPos, TFormatLevel aLevel,
sl@0
  1084
					   TTmCharFormatLayer& aFormat, TInt& aRunLength) const
sl@0
  1085
		{
sl@0
  1086
		TInt length = DocumentLength();
sl@0
  1087
		if (length <= aPos)
sl@0
  1088
			{
sl@0
  1089
			aRunLength = 0;
sl@0
  1090
			return;
sl@0
  1091
			}
sl@0
  1092
		TTestAttributes attr = iAttrs->At(aPos);
sl@0
  1093
		if (aLevel == ESpecific)
sl@0
  1094
			{
sl@0
  1095
			AttrToCharLayer(aFormat, attr);
sl@0
  1096
			}
sl@0
  1097
		else
sl@0
  1098
			{
sl@0
  1099
			AttrToCharLayer(aFormat, iBase);
sl@0
  1100
			MergeAttrToCharLayer(aFormat, attr);
sl@0
  1101
			}
sl@0
  1102
		TInt pos = aPos + 1;
sl@0
  1103
		while (pos < length && attr == iAttrs->At(pos))
sl@0
  1104
			++pos;
sl@0
  1105
		aRunLength = pos - aPos;
sl@0
  1106
		}
sl@0
  1107
	void GetParFormatL(TInt aPos, TFormatLevel aLevel,
sl@0
  1108
					   RTmParFormatLayer& aFormat, TInt& aRunLength) const
sl@0
  1109
		{
sl@0
  1110
		TInt length = DocumentLength();
sl@0
  1111
		if (length <= aPos)
sl@0
  1112
			{
sl@0
  1113
			aRunLength = 0;
sl@0
  1114
			return;
sl@0
  1115
			}
sl@0
  1116
		TTestAttributes attr = iAttrs->At(aPos);
sl@0
  1117
		if (aLevel == ESpecific)
sl@0
  1118
			{
sl@0
  1119
			AttrToParLayer(aFormat, attr);
sl@0
  1120
			}
sl@0
  1121
		else
sl@0
  1122
			{
sl@0
  1123
			AttrToParLayer(aFormat, iBase);
sl@0
  1124
			MergeAttrToParLayer(aFormat, attr);
sl@0
  1125
			}
sl@0
  1126
		TInt pos = aPos + 1;
sl@0
  1127
		while (pos < length && attr == iAttrs->At(pos))
sl@0
  1128
			++pos;
sl@0
  1129
		aRunLength = pos - aPos;
sl@0
  1130
		}
sl@0
  1131
	TInt StyleCount() const { return iNumStyles; }
sl@0
  1132
	void GetStyle(TInt aPos, TPtrC& aName, TInt& aRunLength) const
sl@0
  1133
		{
sl@0
  1134
		TInt length = DocumentLength();
sl@0
  1135
		if (aPos < 0 || length <= aPos)
sl@0
  1136
			{
sl@0
  1137
			aName.Set(iStyleNames[0].Ptr(), 0);
sl@0
  1138
			aRunLength = 0;
sl@0
  1139
			return;
sl@0
  1140
			}
sl@0
  1141
		TInt styleNo = iAttrs->At(aPos).iStyle;
sl@0
  1142
		if (styleNo < 0)
sl@0
  1143
			aName.Set(iStyleNames[0].Ptr(), 0);
sl@0
  1144
		else
sl@0
  1145
			aName.Set(iStyleNames[styleNo]);
sl@0
  1146
		TInt pos = aPos + 1;
sl@0
  1147
		while (pos < length && iAttrs->At(pos).iStyle == styleNo)
sl@0
  1148
			++pos;
sl@0
  1149
		aRunLength = pos - aPos;
sl@0
  1150
		return;
sl@0
  1151
		}
sl@0
  1152
	TInt GetStyleByNameL(const TDesC& aName, RTmStyle& aStyle) const
sl@0
  1153
		{
sl@0
  1154
		return GetStyleByIndexL(Style(aName), aStyle);
sl@0
  1155
		}
sl@0
  1156
	TInt GetStyleByIndexL(TInt aIndex, RTmStyle& aStyle) const
sl@0
  1157
		{
sl@0
  1158
		if (aIndex < 0 || iNumStyles <= aIndex)
sl@0
  1159
			return KErrNotFound;
sl@0
  1160
		aStyle.iName = iStyleNames[aIndex];
sl@0
  1161
		AttrToParLayer(aStyle.iParFormat, iStyles[aIndex]);
sl@0
  1162
		AttrToCharLayer(aStyle.iCharFormat, iStyles[aIndex]);
sl@0
  1163
		return KErrNone;
sl@0
  1164
		}
sl@0
  1165
	void CopyToStoreL(CStreamStore& aStore, CStreamDictionary& aDictionary,
sl@0
  1166
		TInt aPos, TInt aLength) const
sl@0
  1167
		{
sl@0
  1168
		ASSERT(aPos + aLength <= DocumentLength());
sl@0
  1169
		if (aLength <= 0)
sl@0
  1170
			return;
sl@0
  1171
		RStoreWriteStream stream;
sl@0
  1172
		TStreamId id = stream.CreateLC(aStore);
sl@0
  1173
		stream.WriteInt32L(aLength);
sl@0
  1174
		RBufReadStream input_stream(*iText, aPos * sizeof(TText));
sl@0
  1175
		TMemoryStreamUnicodeSource source(input_stream);
sl@0
  1176
		TUnicodeCompressor c;
sl@0
  1177
		c.CompressL(stream, source, KMaxTInt, aLength);
sl@0
  1178
		input_stream.Close();
sl@0
  1179
		stream.CommitL();
sl@0
  1180
		aDictionary.AssignL(KClipboardUidTypePlainText, id);
sl@0
  1181
		CleanupStack::PopAndDestroy();		// close stream
sl@0
  1182
sl@0
  1183
		// now write out formatting in our own bizarre format
sl@0
  1184
		//...
sl@0
  1185
		// in actual fact this probably wouldn't test that much, so I won't
sl@0
  1186
		// bother right now.
sl@0
  1187
		}
sl@0
  1188
	void PasteFromStoreL(const CStreamStore& aStore,
sl@0
  1189
		const CStreamDictionary& aDictionary, TInt aPos)
sl@0
  1190
		{
sl@0
  1191
		ASSERT(aPos <= DocumentLength());
sl@0
  1192
		TStreamId id = aDictionary.At(KClipboardUidTypePlainText);
sl@0
  1193
		RStoreReadStream stream;
sl@0
  1194
		stream.OpenLC(aStore, id);
sl@0
  1195
		TInt length = stream.ReadInt32L();
sl@0
  1196
		RBufWriteStream bufferStream;
sl@0
  1197
		bufferStream.Insert(*iText, aPos * sizeof(TText));
sl@0
  1198
		TMemoryStreamUnicodeSink sink(bufferStream);
sl@0
  1199
		TUnicodeExpander e;
sl@0
  1200
		e.ExpandL(sink, stream, length);
sl@0
  1201
		bufferStream.CommitL();
sl@0
  1202
		bufferStream.Close();
sl@0
  1203
		CleanupStack::PopAndDestroy();	// close stream
sl@0
  1204
sl@0
  1205
		// and if we get round to adding some formatting to the copy method,
sl@0
  1206
		// then we should deal with it here also
sl@0
  1207
		//...
sl@0
  1208
		// but not today. Just add the appropriate spaces into all the structures.
sl@0
  1209
		TTestAttributes attr;
sl@0
  1210
		iAttrs->InsertL(aPos, attr, length);
sl@0
  1211
		CUndoTestPicture* nullPic = 0;
sl@0
  1212
		iPics->InsertL(aPos, nullPic, length);
sl@0
  1213
		}
sl@0
  1214
	};
sl@0
  1215
sl@0
  1216
CLogger& operator<<(CLogger& log, CTestEditor& ed) { ed.Print(log); return log; }
sl@0
  1217
sl@0
  1218
// 1 - CCommandStack test
sl@0
  1219
TInt ExecuteStackL(CCommandStack& a)
sl@0
  1220
	{
sl@0
  1221
	while (a.Top())
sl@0
  1222
		{
sl@0
  1223
		CSingleCommand* single = a.Top()->Single();
sl@0
  1224
		if (!single)
sl@0
  1225
			{
sl@0
  1226
            TESTPRINT(_L("CCommandStack : stack unexpectedly contained batches"));
sl@0
  1227
			a.Reset();
sl@0
  1228
			return 1;
sl@0
  1229
			}
sl@0
  1230
		single->ExecuteL();
sl@0
  1231
		delete single;
sl@0
  1232
		a.Pop();
sl@0
  1233
		}
sl@0
  1234
	return 0;
sl@0
  1235
	}
sl@0
  1236
TInt CheckLog(CCheckingLogger& a)
sl@0
  1237
	{
sl@0
  1238
	if (a.Passed())
sl@0
  1239
		return 0;
sl@0
  1240
	TESTPRINT(_L("CCommandStack... : log failed"));
sl@0
  1241
	return 1;
sl@0
  1242
	}
sl@0
  1243
TInt CheckTop(CCommandStack& aStack, CCommand* aTop)
sl@0
  1244
	{
sl@0
  1245
	if (aStack.Top() != aTop)
sl@0
  1246
		{
sl@0
  1247
        TESTPRINT(_L("CCommandStack : unexpected item at top of stack"));
sl@0
  1248
		return 1;
sl@0
  1249
		}
sl@0
  1250
	return 0;
sl@0
  1251
	}
sl@0
  1252
TInt CheckCount(CCommandStack& aStack, TInt aExpectedCount)
sl@0
  1253
	{
sl@0
  1254
	if (aStack.Count() != aExpectedCount)
sl@0
  1255
		{
sl@0
  1256
	    TESTPRINT(_L("CCommandStack : stack an unexpected size"));
sl@0
  1257
		return 1;
sl@0
  1258
		}
sl@0
  1259
	return 0;
sl@0
  1260
	}
sl@0
  1261
TInt CheckPop(CCommandStack& aStack)
sl@0
  1262
	{
sl@0
  1263
	CCommand* check = aStack.Top();
sl@0
  1264
	if (aStack.Pop() != check)
sl@0
  1265
		{
sl@0
  1266
        TESTPRINT(_L("CCommandStack : Pop() does not match Top()"));
sl@0
  1267
		return 1;
sl@0
  1268
		}
sl@0
  1269
	return 0;
sl@0
  1270
	}
sl@0
  1271
void AddStuffL(CCommandStack& aStack, TInt* aTarget, CLogger* aLog)
sl@0
  1272
	{
sl@0
  1273
	TInt startCount = aStack.Count();
sl@0
  1274
	CheckTop(aStack, 0);
sl@0
  1275
	aStack.PrepareToPushL(1);
sl@0
  1276
	CheckCount(aStack, startCount);
sl@0
  1277
	CheckTop(aStack, 0);
sl@0
  1278
	CheckCount(aStack, startCount);
sl@0
  1279
	CCommand* temp = CCommandIncProto::NewL(aTarget, aLog);
sl@0
  1280
	aStack.Push(temp);
sl@0
  1281
	CheckCount(aStack, startCount + 1);
sl@0
  1282
	CheckTop(aStack, temp);
sl@0
  1283
	aStack.PrepareToPushL(2);
sl@0
  1284
	CheckCount(aStack, startCount + 1);
sl@0
  1285
	CheckTop(aStack, temp);
sl@0
  1286
	CheckCount(aStack, startCount + 1);
sl@0
  1287
	CheckTop(aStack, temp);
sl@0
  1288
	aStack.PrepareToPushL(1);
sl@0
  1289
	aStack.PrepareToPushL(3);
sl@0
  1290
	CheckCount(aStack, startCount + 1);
sl@0
  1291
	CheckTop(aStack, temp);
sl@0
  1292
	temp = CCommandDecProto::NewL(aTarget, aLog);
sl@0
  1293
	CheckCount(aStack, startCount + 1);
sl@0
  1294
	aStack.Push(temp);
sl@0
  1295
	CheckCount(aStack, startCount + 2);
sl@0
  1296
	CheckTop(aStack, temp);
sl@0
  1297
	CheckTop(aStack, temp);
sl@0
  1298
	CheckCount(aStack, startCount + 2);
sl@0
  1299
	CheckTop(aStack, temp);
sl@0
  1300
	temp = CCommandIncProto::NewL(aTarget, aLog);
sl@0
  1301
	aStack.Push(temp);
sl@0
  1302
	CheckTop(aStack, temp);
sl@0
  1303
	CheckCount(aStack, startCount + 3);
sl@0
  1304
	aStack.PrepareToPushL(1);
sl@0
  1305
	CheckTop(aStack, temp);
sl@0
  1306
	aStack.PrepareToPushL(2);
sl@0
  1307
	CheckTop(aStack, temp);
sl@0
  1308
	temp = CCommandNegProto::NewL(aTarget, aLog);
sl@0
  1309
	CheckCount(aStack, startCount + 3);
sl@0
  1310
	aStack.Push(temp);
sl@0
  1311
	CheckCount(aStack, startCount + 4);
sl@0
  1312
	CheckTop(aStack, temp);
sl@0
  1313
	CheckCount(aStack, startCount + 4);
sl@0
  1314
	CheckTop(aStack, temp);
sl@0
  1315
	temp = CCommandIncProto::NewL(aTarget, aLog);
sl@0
  1316
	CheckCount(aStack, startCount + 4);
sl@0
  1317
	aStack.Push(temp);
sl@0
  1318
	CheckTop(aStack, temp);
sl@0
  1319
	CheckCount(aStack, startCount + 5);
sl@0
  1320
	}
sl@0
  1321
void TestCCommandStackL()
sl@0
  1322
	{
sl@0
  1323
	__UHEAP_MARK;
sl@0
  1324
	TInt target;
sl@0
  1325
	CCheckingLogger* log = new(ELeave) CCheckingLogger;
sl@0
  1326
sl@0
  1327
	CCommandStack* stack = CCommandStack::NewL();
sl@0
  1328
sl@0
  1329
	AddStuffL(*stack, &target, log);
sl@0
  1330
sl@0
  1331
	log->SetCheckString(_L("inc<>neg<>inc<>dec<>inc<>"));
sl@0
  1332
	ExecuteStackL(*stack);
sl@0
  1333
	CheckLog(*log);
sl@0
  1334
sl@0
  1335
	CheckCount(*stack, 0);
sl@0
  1336
	CCommand* temp = CCommandIncProto::NewL(&target, log);
sl@0
  1337
	CheckTop(*stack, 0);
sl@0
  1338
	stack->PrepareToPushL(1);
sl@0
  1339
	CheckCount(*stack, 0);
sl@0
  1340
	CheckTop(*stack, 0);
sl@0
  1341
	CheckCount(*stack, 0);
sl@0
  1342
	stack->Push(temp);
sl@0
  1343
	CheckCount(*stack, 1);
sl@0
  1344
	stack->PrepareToPushL(1);
sl@0
  1345
	CheckCount(*stack, 1);
sl@0
  1346
	CCommand* next = CCommandDecProto::NewL(&target, log);
sl@0
  1347
	stack->Push(next);
sl@0
  1348
	CheckCount(*stack, 2);
sl@0
  1349
	stack->PrepareToPushL(1);
sl@0
  1350
	CheckPop(*stack);
sl@0
  1351
	stack->PrepareToPushL(1);
sl@0
  1352
	CheckCount(*stack, 1);
sl@0
  1353
	CheckTop(*stack, temp);
sl@0
  1354
	CheckCount(*stack, 1);
sl@0
  1355
	stack->Push(next);
sl@0
  1356
	stack->PrepareToPushL(1);
sl@0
  1357
	CheckCount(*stack, 2);
sl@0
  1358
	CheckCount(*stack, 2);
sl@0
  1359
	CheckPop(*stack);
sl@0
  1360
	CheckCount(*stack, 1);
sl@0
  1361
	CheckTop(*stack, temp);
sl@0
  1362
	delete next;
sl@0
  1363
sl@0
  1364
	stack->Reset();
sl@0
  1365
	CheckCount(*stack, 0);
sl@0
  1366
sl@0
  1367
	AddStuffL(*stack, &target, log);
sl@0
  1368
	stack->PruneTo(3);
sl@0
  1369
	CheckCount(*stack, 3);
sl@0
  1370
	log->SetCheckString(_L("inc<>neg<>inc<>"));
sl@0
  1371
	ExecuteStackL(*stack);
sl@0
  1372
	CheckLog(*log);
sl@0
  1373
sl@0
  1374
	AddStuffL(*stack, &target, log);
sl@0
  1375
	stack->PrepareToPushL(1);
sl@0
  1376
	CheckCount(*stack, 5);
sl@0
  1377
	stack->PruneTo(2);
sl@0
  1378
	CheckCount(*stack, 2);
sl@0
  1379
	log->SetCheckString(_L("inc<>neg<>"));
sl@0
  1380
	ExecuteStackL(*stack);
sl@0
  1381
	CheckLog(*log);
sl@0
  1382
sl@0
  1383
	delete stack;
sl@0
  1384
	delete log;
sl@0
  1385
sl@0
  1386
	__UHEAP_MARKENDC(0);
sl@0
  1387
	}
sl@0
  1388
sl@0
  1389
// 2 - CBatchCommand test
sl@0
  1390
void ExecuteBatchL(CBatchCommand& a)
sl@0
  1391
	{
sl@0
  1392
	while (a.Top())
sl@0
  1393
		{
sl@0
  1394
		CSingleCommand* single = a.Top();
sl@0
  1395
		single->ExecuteL();
sl@0
  1396
		if (a.Pop() != single)
sl@0
  1397
			{
sl@0
  1398
            TESTPRINT(_L("CBatchCommand : Pop() didn't match Top()"));
sl@0
  1399
            TESTPOINT(0);
sl@0
  1400
			}
sl@0
  1401
		delete single;
sl@0
  1402
		}
sl@0
  1403
	TESTPOINT(1);
sl@0
  1404
	}
sl@0
  1405
void CheckTop(CBatchCommand& aBatch, CCommand* aTop)
sl@0
  1406
	{
sl@0
  1407
	if (aBatch.Top() != aTop)
sl@0
  1408
		{
sl@0
  1409
        TESTPRINT(_L("CCommandBatch : unexpected item at top of stack"));
sl@0
  1410
        TESTPOINT(0);
sl@0
  1411
		}
sl@0
  1412
	TESTPOINT(1);
sl@0
  1413
	}
sl@0
  1414
void TestCBatchCommandL()
sl@0
  1415
	{
sl@0
  1416
	__UHEAP_MARK;
sl@0
  1417
	TInt target = 0;
sl@0
  1418
	CCheckingLogger* log = new(ELeave) CCheckingLogger;
sl@0
  1419
sl@0
  1420
	CBatchCommand* batch = CBatchCommand::NewL();
sl@0
  1421
sl@0
  1422
	CBatchCommand* b1 = CBatchCommand::NewL();
sl@0
  1423
	CBatchCommand* b2 = CBatchCommand::NewL();
sl@0
  1424
	CBatchCommand* b3 = CBatchCommand::NewL();
sl@0
  1425
sl@0
  1426
	CCommand* s1 = CCommandIncProto::NewL(&target, log);
sl@0
  1427
	CCommand* s2 = CCommandDecProto::NewL(&target, log);
sl@0
  1428
	CCommand* s3 = CCommandNegProto::NewL(&target, log);
sl@0
  1429
	CCommand* s4 = CCommandIncProto::NewL(&target, log);
sl@0
  1430
	CCommand* s5 = CCommandDecProto::NewL(&target, log);
sl@0
  1431
	CCommand* s6 = CCommandNegProto::NewL(&target, log);
sl@0
  1432
	CCommand* s7 = CCommandIncProto::NewL(&target, log);
sl@0
  1433
	CCommand* s8 = CCommandDecProto::NewL(&target, log);
sl@0
  1434
	CCommand* s9 = CCommandNegProto::NewL(&target, log);
sl@0
  1435
sl@0
  1436
	b2->PrepareToPushL(s4);
sl@0
  1437
	b2->Push(s4);
sl@0
  1438
	b2->PrepareToPushL(s8);
sl@0
  1439
	b2->Push(s8);
sl@0
  1440
	b2->PrepareToPushL(s2);
sl@0
  1441
	b2->PrepareToPushL(s2);
sl@0
  1442
	b2->Push(s2);
sl@0
  1443
sl@0
  1444
	b3->PrepareToPushL(s3);
sl@0
  1445
	b3->PrepareToPushL(s9);
sl@0
  1446
	b3->Push(s9);
sl@0
  1447
	b3->PrepareToPushL(s3);
sl@0
  1448
	b3->Push(s3);
sl@0
  1449
	b3->PrepareToPushL(s7);
sl@0
  1450
	b3->Push(s7);
sl@0
  1451
sl@0
  1452
	b1->PrepareToPushL(s6);
sl@0
  1453
	b1->Push(s6);
sl@0
  1454
	b1->PrepareToPushL(s5);
sl@0
  1455
	b1->Push(s5);
sl@0
  1456
	b1->PrepareToPushL(b3);
sl@0
  1457
	b1->Push(b3);
sl@0
  1458
	b1->PrepareToPushL(b1);
sl@0
  1459
	b1->PrepareToPushL(s1);
sl@0
  1460
	b1->PrepareToPushL(s1);
sl@0
  1461
	b1->PrepareToPushL(b2);
sl@0
  1462
sl@0
  1463
	batch->PrepareToPushL(b2);
sl@0
  1464
	batch->Push(b2);
sl@0
  1465
	batch->PrepareToPushL(s1);
sl@0
  1466
	batch->PrepareToPushL(s1);
sl@0
  1467
	batch->PrepareToPushL(b1);
sl@0
  1468
	batch->Push(b1);
sl@0
  1469
	batch->PrepareToPushL(s1);
sl@0
  1470
	batch->Push(s1);
sl@0
  1471
sl@0
  1472
	CheckTop(*batch, s1);
sl@0
  1473
	batch->Pop();
sl@0
  1474
	CheckTop(*batch, s7);
sl@0
  1475
	batch->PrepareToPushL(s1);
sl@0
  1476
	CheckTop(*batch, s7);
sl@0
  1477
	batch->Push(s1);
sl@0
  1478
	CheckTop(*batch, s1);
sl@0
  1479
	batch->PrepareToPushL(s1);
sl@0
  1480
	CheckTop(*batch, s1);
sl@0
  1481
	batch->Pop();
sl@0
  1482
	CheckTop(*batch, s7);
sl@0
  1483
	batch->Pop();
sl@0
  1484
	CheckTop(*batch, s3);
sl@0
  1485
	batch->Pop();
sl@0
  1486
	CheckTop(*batch, s9);
sl@0
  1487
	batch->Pop();
sl@0
  1488
	CheckTop(*batch, s5);
sl@0
  1489
	batch->Pop();
sl@0
  1490
	CheckTop(*batch, s6);
sl@0
  1491
	batch->PrepareToPushL(s5);
sl@0
  1492
	CheckTop(*batch, s6);
sl@0
  1493
	batch->Push(s5);
sl@0
  1494
	CheckTop(*batch, s5);
sl@0
  1495
	b3 = CBatchCommand::NewL();
sl@0
  1496
	b3->PrepareToPushL(s9);
sl@0
  1497
	CheckTop(*b3, 0);
sl@0
  1498
	b3->Push(s9);
sl@0
  1499
	CheckTop(*b3, s9);
sl@0
  1500
	b3->PrepareToPushL(s3);
sl@0
  1501
	CheckTop(*b3, s9);
sl@0
  1502
	b3->Push(s3);
sl@0
  1503
	CheckTop(*b3, s3);
sl@0
  1504
	b3->PrepareToPushL(s7);
sl@0
  1505
	CheckTop(*b3, s3);
sl@0
  1506
	b3->Push(s7);
sl@0
  1507
	CheckTop(*b3, s7);
sl@0
  1508
	batch->PrepareToPushL(b3);
sl@0
  1509
	CheckTop(*batch, s5);
sl@0
  1510
	batch->Push(b3);
sl@0
  1511
	CheckTop(*batch, s7);
sl@0
  1512
	batch->PrepareToPushL(s1);
sl@0
  1513
	batch->Push(s1);
sl@0
  1514
sl@0
  1515
	log->SetCheckString(_L("inc<>inc<>neg<>neg<>dec<>neg<>dec<>dec<>inc<>"));
sl@0
  1516
	ExecuteBatchL(*batch);
sl@0
  1517
	CheckLog(*log);
sl@0
  1518
sl@0
  1519
	delete log;
sl@0
  1520
	delete batch;
sl@0
  1521
sl@0
  1522
	__UHEAP_MARKENDC(0);
sl@0
  1523
	}
sl@0
  1524
sl@0
  1525
// 3 - CCommandHistory test
sl@0
  1526
void ExecuteHistoryL(CCommandHistory& aHistory, CLogger& aLog)
sl@0
  1527
	{
sl@0
  1528
	while (aHistory.Top())
sl@0
  1529
		{
sl@0
  1530
		if (aHistory.Top()->Single())
sl@0
  1531
			{
sl@0
  1532
			aHistory.Top()->Single()->ExecuteL();
sl@0
  1533
			}
sl@0
  1534
		else
sl@0
  1535
			{
sl@0
  1536
			CBatchCommand* batch = aHistory.Top()->Batch();
sl@0
  1537
			TESTPOINT(batch != 0);
sl@0
  1538
			aLog << _L("batch{");
sl@0
  1539
			ExecuteBatchL(*batch);
sl@0
  1540
			aLog << _L("}");
sl@0
  1541
			}
sl@0
  1542
		delete aHistory.Pop();
sl@0
  1543
		}
sl@0
  1544
	}
sl@0
  1545
void TestCCommandHistoryL()
sl@0
  1546
	{
sl@0
  1547
	__UHEAP_MARK;
sl@0
  1548
sl@0
  1549
	CCommandHistory* history = CCommandHistory::NewL();
sl@0
  1550
	CCheckingLogger* log = new(ELeave) CCheckingLogger;
sl@0
  1551
	TInt target;
sl@0
  1552
sl@0
  1553
	CCommand* p;
sl@0
  1554
	history->SetMaxItems(5);
sl@0
  1555
	p = CCommandDecProto::NewL(&target, log);
sl@0
  1556
	history->PrepareToAddCommandL(p);
sl@0
  1557
	history->AddCommand(p);
sl@0
  1558
	p = CCommandIncProto::NewL(&target, log);
sl@0
  1559
	history->PrepareToAddCommandL(p);
sl@0
  1560
	history->AddCommand(p);
sl@0
  1561
	p = CCommandDecProto::NewL(&target, log);
sl@0
  1562
	history->PrepareToAddCommandL(p);
sl@0
  1563
	history->AddCommand(p);
sl@0
  1564
	p = CCommandNegProto::NewL(&target, log);
sl@0
  1565
	history->PrepareToAddCommandL(p);
sl@0
  1566
	history->AddCommand(p);
sl@0
  1567
	history->BeginBatchLC();
sl@0
  1568
	p = CCommandIncProto::NewL(&target, log);
sl@0
  1569
	history->PrepareToAddCommandL(p);
sl@0
  1570
	history->AddCommand(p);
sl@0
  1571
	p = CCommandDecProto::NewL(&target, log);
sl@0
  1572
	history->PrepareToAddCommandL(p);
sl@0
  1573
	history->AddCommand(p);
sl@0
  1574
	p = CCommandNegProto::NewL(&target, log);
sl@0
  1575
	history->PrepareToAddCommandL(p);
sl@0
  1576
	history->AddCommand(p);
sl@0
  1577
	CleanupStack::PopAndDestroy();
sl@0
  1578
	p = CCommandDecProto::NewL(&target, log);
sl@0
  1579
	history->PrepareToAddCommandL(p);
sl@0
  1580
	history->AddCommand(p);
sl@0
  1581
	CBatchCommand* batch = CBatchCommand::NewL();
sl@0
  1582
	p = CCommandDecProto::NewL(&target, log);
sl@0
  1583
	batch->PrepareToPushL(p);
sl@0
  1584
	batch->Push(p);
sl@0
  1585
	p = CCommandNegProto::NewL(&target, log);
sl@0
  1586
	batch->PrepareToPushL(p);
sl@0
  1587
	batch->Push(p);
sl@0
  1588
	p = CCommandIncProto::NewL(&target, log);
sl@0
  1589
	batch->PrepareToPushL(p);
sl@0
  1590
	batch->Push(p);
sl@0
  1591
	history->PrepareToAddCommandL(batch);
sl@0
  1592
	history->AddCommand(batch);
sl@0
  1593
	p = CCommandNegProto::NewL(&target, log);
sl@0
  1594
	history->PrepareToAddCommandL(p);
sl@0
  1595
	history->AddCommand(p);
sl@0
  1596
sl@0
  1597
	log->SetCheckString(_L("neg<>batch{inc<>neg<>dec<>}dec<>batch{neg<>dec<>inc<>}neg<>"));
sl@0
  1598
	ExecuteHistoryL(*history, *log);
sl@0
  1599
	CheckLog(*log);
sl@0
  1600
sl@0
  1601
	delete log;
sl@0
  1602
	delete history;
sl@0
  1603
sl@0
  1604
	__UHEAP_MARKENDC(0);
sl@0
  1605
	}
sl@0
  1606
sl@0
  1607
// 4 - CCommandManager test
sl@0
  1608
void TestCanUndo(const CCommandManager& aMan)
sl@0
  1609
	{
sl@0
  1610
	if (aMan.CanUndo())
sl@0
  1611
		{
sl@0
  1612
        TESTPOINT(1);
sl@0
  1613
		return;
sl@0
  1614
		}
sl@0
  1615
	TESTPRINT(_L("CCommandManager : unexpectedly could not undo"));
sl@0
  1616
	TESTPOINT(0);
sl@0
  1617
	}
sl@0
  1618
void TestCanRedo(const CCommandManager& aMan)
sl@0
  1619
	{
sl@0
  1620
	if (aMan.CanRedo())
sl@0
  1621
		{
sl@0
  1622
        TESTPOINT(1);
sl@0
  1623
		return;
sl@0
  1624
		}
sl@0
  1625
	TESTPRINT(_L("CCommandManager : unexpectedly could not redo"));
sl@0
  1626
	TESTPOINT(0);
sl@0
  1627
	}
sl@0
  1628
void TestCannotUndo(const CCommandManager& aMan)
sl@0
  1629
	{
sl@0
  1630
	if (!aMan.CanUndo())
sl@0
  1631
		{
sl@0
  1632
        TESTPOINT(1);
sl@0
  1633
		return;
sl@0
  1634
		}
sl@0
  1635
	TESTPRINT(_L("CCommandManager : unexpectedly could undo"));
sl@0
  1636
	TESTPOINT(0);
sl@0
  1637
	}
sl@0
  1638
void TestCannotRedo(const CCommandManager& aMan)
sl@0
  1639
	{
sl@0
  1640
	if (!aMan.CanRedo())
sl@0
  1641
		{
sl@0
  1642
        TESTPOINT(1);
sl@0
  1643
		return;
sl@0
  1644
		}
sl@0
  1645
	TESTPRINT(_L("CCommandManager : unexpectedly could undo"));
sl@0
  1646
	TESTPOINT(0);
sl@0
  1647
	}
sl@0
  1648
void SetUpTestL(CCommandManager& aMan, CSingleCommand& aCommand, TInt* aTarget, CLogger* aLogger)
sl@0
  1649
	{
sl@0
  1650
	CCommandIncProto* inc = CCommandIncProto::NewL(aTarget, aLogger);
sl@0
  1651
	CleanupStack::PushL(inc);
sl@0
  1652
	CCommandNegProto* neg = CCommandNegProto::NewL(aTarget, aLogger);
sl@0
  1653
	CleanupStack::PushL(neg);
sl@0
  1654
	CCommandDecProto* dec = CCommandDecProto::NewL(aTarget, aLogger);
sl@0
  1655
	CleanupStack::PushL(dec);
sl@0
  1656
sl@0
  1657
	aMan.ExecuteL(*inc);
sl@0
  1658
	aMan.BeginBatchLC();
sl@0
  1659
	aMan.ExecuteL(*neg);
sl@0
  1660
	aMan.ExecuteL(aCommand);
sl@0
  1661
	aMan.ExecuteL(*dec);
sl@0
  1662
	CleanupStack::PopAndDestroy();		// close batch
sl@0
  1663
	aMan.ExecuteL(*neg);
sl@0
  1664
	aMan.UndoL();
sl@0
  1665
sl@0
  1666
	CleanupStack::PopAndDestroy(dec);
sl@0
  1667
	CleanupStack::PopAndDestroy(neg);
sl@0
  1668
	CleanupStack::PopAndDestroy(inc);
sl@0
  1669
	}
sl@0
  1670
TInt CheckErrorCode(TInt aErr, TInt aExpected)
sl@0
  1671
	{
sl@0
  1672
	if (aErr == aExpected)
sl@0
  1673
		return 0;
sl@0
  1674
	if (aErr == KErrNone)
sl@0
  1675
	    TESTPRINT(_L("CCommandManager : no leave where one was expected"));
sl@0
  1676
	else
sl@0
  1677
	    TESTPRINT(_L("CCommandManager : unexpected leave code"));
sl@0
  1678
	return 1;
sl@0
  1679
	}
sl@0
  1680
void TestCCommandManagerL()
sl@0
  1681
	{
sl@0
  1682
	__UHEAP_MARK;
sl@0
  1683
sl@0
  1684
	CCommandManager* manager = CCommandManager::NewL();
sl@0
  1685
	CCheckingLogger* log = new(ELeave) CCheckingLogger;
sl@0
  1686
	TInt target = 0;
sl@0
  1687
	CRefuserGatekeeper* refuser = new(ELeave) CRefuserGatekeeper;
sl@0
  1688
	CPermitterGatekeeper* permitter = new(ELeave) CPermitterGatekeeper;
sl@0
  1689
	CMemoryReclaimGatekeeper* reclaimer = new(ELeave) CMemoryReclaimGatekeeper;
sl@0
  1690
sl@0
  1691
	TestCannotUndo(*manager);
sl@0
  1692
	TestCannotRedo(*manager);
sl@0
  1693
sl@0
  1694
	CCommandIncProto* inc = CCommandIncProto::NewL(&target, log);
sl@0
  1695
	CCommandDecProto* dec = CCommandDecProto::NewL(&target, log);
sl@0
  1696
	CCommandNegProto* neg = CCommandNegProto::NewL(&target, log);
sl@0
  1697
sl@0
  1698
	log->SetCheckString(_L("inc<>neg<>inc<>dec<>neg<>negate<1>"));
sl@0
  1699
	SetUpTestL(*manager, *inc, &target, log);
sl@0
  1700
	CheckLog(*log);
sl@0
  1701
	TestCanUndo(*manager);
sl@0
  1702
	TestCanRedo(*manager);
sl@0
  1703
	log->SetCheckString(_L("offset<0>negate<1>"));
sl@0
  1704
	manager->UndoL();
sl@0
  1705
	CheckLog(*log);
sl@0
  1706
	TestCanUndo(*manager);
sl@0
  1707
	TestCanRedo(*manager);
sl@0
  1708
	log->SetCheckString(_L("offset<-1>"));
sl@0
  1709
	manager->UndoL();
sl@0
  1710
	CheckLog(*log);
sl@0
  1711
	TestCannotUndo(*manager);
sl@0
  1712
	TestCanRedo(*manager);
sl@0
  1713
	log->SetCheckString(_L("offset<1>"));
sl@0
  1714
	manager->RedoL();
sl@0
  1715
	CheckLog(*log);
sl@0
  1716
	TestCanUndo(*manager);
sl@0
  1717
	TestCanRedo(*manager);
sl@0
  1718
	log->SetCheckString(_L("negate<1>offset<0>"));
sl@0
  1719
	manager->RedoL();
sl@0
  1720
	CheckLog(*log);
sl@0
  1721
	TestCanUndo(*manager);
sl@0
  1722
	TestCanRedo(*manager);
sl@0
  1723
	log->SetCheckString(_L("negate<1>"));
sl@0
  1724
	manager->RedoL();
sl@0
  1725
	CheckLog(*log);
sl@0
  1726
	TestCanUndo(*manager);
sl@0
  1727
	TestCannotRedo(*manager);
sl@0
  1728
	log->SetCheckString(_L("negate<1>"));
sl@0
  1729
	manager->UndoL();
sl@0
  1730
	CheckLog(*log);
sl@0
  1731
	TestCanUndo(*manager);
sl@0
  1732
	TestCanRedo(*manager);
sl@0
  1733
	log->SetCheckString(_L("inc<>"));
sl@0
  1734
	manager->ExecuteL(*inc);
sl@0
  1735
	CheckLog(*log);
sl@0
  1736
	TestCanUndo(*manager);
sl@0
  1737
	TestCannotRedo(*manager);
sl@0
  1738
	log->SetCheckString(_L("offset<-1>negate<1>"));
sl@0
  1739
	manager->UndoL();
sl@0
  1740
	CheckLog(*log);
sl@0
  1741
	TestCanUndo(*manager);
sl@0
  1742
	TestCanRedo(*manager);
sl@0
  1743
	log->SetCheckString(_L("negate<1>offset<1>"));
sl@0
  1744
	manager->RedoL();
sl@0
  1745
	CheckLog(*log);
sl@0
  1746
	TestCanUndo(*manager);
sl@0
  1747
	TestCannotRedo(*manager);
sl@0
  1748
sl@0
  1749
	manager->ResetUndo();
sl@0
  1750
	TestCannotUndo(*manager);
sl@0
  1751
	TestCannotRedo(*manager);
sl@0
  1752
sl@0
  1753
	// test coalescence
sl@0
  1754
sl@0
  1755
	log->SetCheckString(_L("inc<>inc<>inc<>inc<>inc<>inc<>"));
sl@0
  1756
sl@0
  1757
	manager->ExecuteL(*inc);
sl@0
  1758
	manager->ExecuteL(*inc);
sl@0
  1759
	manager->BeginBatchLC();
sl@0
  1760
	manager->ExecuteL(*inc);
sl@0
  1761
	manager->ExecuteL(*inc);
sl@0
  1762
	CleanupStack::PopAndDestroy();		// close batch
sl@0
  1763
	manager->ExecuteL(*inc);
sl@0
  1764
	manager->ExecuteL(*inc);
sl@0
  1765
	CheckLog(*log);
sl@0
  1766
sl@0
  1767
	log->SetCheckString(_L("offset<-4>offset<-2>"));
sl@0
  1768
	manager->UndoL();
sl@0
  1769
	manager->UndoL();
sl@0
  1770
	CheckLog(*log);
sl@0
  1771
sl@0
  1772
	log->SetCheckString(_L("offset<2>offset<4>"));
sl@0
  1773
	manager->RedoL();
sl@0
  1774
	manager->RedoL();
sl@0
  1775
	TestCannotRedo(*manager);
sl@0
  1776
	CheckLog(*log);
sl@0
  1777
sl@0
  1778
	manager->ResetUndo();
sl@0
  1779
	TestCannotUndo(*manager);
sl@0
  1780
	TestCannotRedo(*manager);
sl@0
  1781
sl@0
  1782
	// test command with batch inverse
sl@0
  1783
	log->SetCheckString(_L("inc<>decneg<>inc<>"));
sl@0
  1784
	CCommandDecThenNegProto* dnp = CCommandDecThenNegProto::NewL(&target, log);
sl@0
  1785
	manager->ExecuteL(*inc);
sl@0
  1786
	manager->ExecuteL(*dnp);
sl@0
  1787
	manager->ExecuteL(*inc);
sl@0
  1788
	CheckLog(*log);
sl@0
  1789
	delete dnp;
sl@0
  1790
	log->SetCheckString(_L("offset<-1>"));
sl@0
  1791
	manager->UndoL();
sl@0
  1792
	CheckLog(*log);
sl@0
  1793
	log->SetCheckString(_L("negate<1>offset<1>"));
sl@0
  1794
	manager->UndoL();
sl@0
  1795
	CheckLog(*log);
sl@0
  1796
	log->SetCheckString(_L("offset<-1>"));
sl@0
  1797
	manager->UndoL();
sl@0
  1798
	CheckLog(*log);
sl@0
  1799
	manager->ResetUndo();
sl@0
  1800
sl@0
  1801
	// Test case when undo is not supported
sl@0
  1802
	// 1. execution is permitted
sl@0
  1803
	log->SetCheckString(_L("inc<>neg<>noinvfail.noinv<>dec<>neg<>negate<1>"));
sl@0
  1804
	CCommandCannotInvert* noInv = CCommandCannotInvert::NewL(log);
sl@0
  1805
	SetUpTestL(*manager, *noInv, &target, log);
sl@0
  1806
	CheckLog(*log);
sl@0
  1807
	TestCannotUndo(*manager);
sl@0
  1808
	log->SetCheckString(_L("negate<1>"));
sl@0
  1809
	manager->RedoL();
sl@0
  1810
	CheckLog(*log);
sl@0
  1811
	TestCannotRedo(*manager);
sl@0
  1812
	manager->ResetUndo();
sl@0
  1813
sl@0
  1814
	//2. execution is supressed
sl@0
  1815
	manager->SetGatekeeper(refuser);
sl@0
  1816
	log->SetCheckString(_L("inc<>neg<>noinvfail.dec<>neg<>negate<1>"));
sl@0
  1817
	SetUpTestL(*manager, *noInv, &target, log);
sl@0
  1818
	CheckLog(*log);
sl@0
  1819
	delete noInv;
sl@0
  1820
	log->SetCheckString(_L("offset<1>negate<1>"));
sl@0
  1821
	manager->UndoL();
sl@0
  1822
	CheckLog(*log);
sl@0
  1823
	log->SetCheckString(_L("offset<-1>"));
sl@0
  1824
	manager->UndoL();
sl@0
  1825
	CheckLog(*log);
sl@0
  1826
	TestCannotUndo(*manager);
sl@0
  1827
	manager->ResetUndo();
sl@0
  1828
	manager->SetGatekeeper(0);
sl@0
  1829
sl@0
  1830
	// Test case when execution fails (with returned error code)
sl@0
  1831
	CCommandCannotDo* noDo = CCommandCannotDo::NewL(log);
sl@0
  1832
	log->SetCheckString(_L("inc<>neg<>nodo<>dec<>neg<>negate<1>"));
sl@0
  1833
	SetUpTestL(*manager, *noDo, &target, log);
sl@0
  1834
	delete noDo;
sl@0
  1835
	log->SetCheckString(_L("offset<1>negate<1>"));
sl@0
  1836
	manager->UndoL();
sl@0
  1837
	CheckLog(*log);
sl@0
  1838
	log->SetCheckString(_L("offset<-1>"));
sl@0
  1839
	manager->UndoL();
sl@0
  1840
	CheckLog(*log);
sl@0
  1841
	TestCannotUndo(*manager);
sl@0
  1842
	manager->ResetUndo();
sl@0
  1843
sl@0
  1844
	// Test case when inversion fails (not inversion is reported as impossible)
sl@0
  1845
	// 1. when execution is permitted
sl@0
  1846
	manager->SetGatekeeper(permitter);
sl@0
  1847
	log->SetCheckString(_L("inc<>neg<>noinvfail.leaveinv<>dec<>neg<>negate<1>"));
sl@0
  1848
	CCommandLeavesInvert* leaveInv = CCommandLeavesInvert::NewL(log);
sl@0
  1849
	SetUpTestL(*manager, *leaveInv, &target, log);
sl@0
  1850
	CheckLog(*log);
sl@0
  1851
	TestCannotUndo(*manager);
sl@0
  1852
	log->SetCheckString(_L("negate<1>"));
sl@0
  1853
	manager->RedoL();
sl@0
  1854
	CheckLog(*log);
sl@0
  1855
	TestCannotRedo(*manager);
sl@0
  1856
	manager->ResetUndo();
sl@0
  1857
sl@0
  1858
	// 2. when execution is supressed
sl@0
  1859
	manager->SetGatekeeper(refuser);
sl@0
  1860
	log->SetCheckString(_L("inc<>neg<>noinvfail.dec<>neg<>negate<1>"));
sl@0
  1861
	leaveInv->iFail = ETrue;
sl@0
  1862
	TRAPD(err, SetUpTestL(*manager, *leaveInv, &target, log));
sl@0
  1863
	CheckErrorCode(err, KErrNone);
sl@0
  1864
	CheckLog(*log);
sl@0
  1865
	log->SetCheckString(_L("offset<1>negate<1>"));
sl@0
  1866
	manager->UndoL();
sl@0
  1867
	CheckLog(*log);
sl@0
  1868
	log->SetCheckString(_L("offset<-1>"));
sl@0
  1869
	manager->UndoL();
sl@0
  1870
	CheckLog(*log);
sl@0
  1871
	TestCannotUndo(*manager);
sl@0
  1872
	manager->ResetUndo();
sl@0
  1873
sl@0
  1874
	// 3. when execution is terminated by leaving
sl@0
  1875
	manager->SetGatekeeper(0);
sl@0
  1876
	log->SetCheckString(_L("inc<>neg<>noinvfail."));
sl@0
  1877
	leaveInv->iFail = ETrue;
sl@0
  1878
	TRAP(err, SetUpTestL(*manager, *leaveInv, &target, log));
sl@0
  1879
	CheckErrorCode(err, KErrNotFound);
sl@0
  1880
	CheckLog(*log);
sl@0
  1881
	delete leaveInv;
sl@0
  1882
	log->SetCheckString(_L("negate<1>"));
sl@0
  1883
	manager->UndoL();
sl@0
  1884
	CheckLog(*log);
sl@0
  1885
	log->SetCheckString(_L("offset<-1>"));
sl@0
  1886
	manager->UndoL();
sl@0
  1887
	CheckLog(*log);
sl@0
  1888
	TestCannotUndo(*manager);
sl@0
  1889
	manager->ResetUndo();
sl@0
  1890
sl@0
  1891
	// Test case when inversion runs out of memory
sl@0
  1892
	// 1. when execution is permitted with no undo
sl@0
  1893
	manager->SetGatekeeper(permitter);
sl@0
  1894
	log->SetCheckString(_L("inc<>neg<>nomemfailadd.nomem<>dec<>neg<>negate<1>"));
sl@0
  1895
	CCommandNoMemory* noMem = CCommandNoMemory::NewL(log);
sl@0
  1896
	noMem->iFailExecute = EFalse;
sl@0
  1897
	SetUpTestL(*manager, *noMem, &target, log);
sl@0
  1898
	CheckLog(*log);
sl@0
  1899
	TestCannotUndo(*manager);
sl@0
  1900
	log->SetCheckString(_L("negate<1>"));
sl@0
  1901
	manager->RedoL();
sl@0
  1902
	CheckLog(*log);
sl@0
  1903
	TestCannotRedo(*manager);
sl@0
  1904
	manager->ResetUndo();
sl@0
  1905
sl@0
  1906
	// 2. when execution is supressed
sl@0
  1907
	manager->SetGatekeeper(refuser);
sl@0
  1908
	log->SetCheckString(_L("inc<>neg<>nomemfailadd.dec<>neg<>negate<1>"));
sl@0
  1909
	TRAP(err, SetUpTestL(*manager, *noMem, &target, log));
sl@0
  1910
	CheckErrorCode(err, KErrNone);
sl@0
  1911
	CheckLog(*log);
sl@0
  1912
	log->SetCheckString(_L("offset<1>negate<1>"));
sl@0
  1913
	manager->UndoL();
sl@0
  1914
	CheckLog(*log);
sl@0
  1915
	log->SetCheckString(_L("offset<-1>"));
sl@0
  1916
	manager->UndoL();
sl@0
  1917
	CheckLog(*log);
sl@0
  1918
	TestCannotUndo(*manager);
sl@0
  1919
	manager->ResetUndo();
sl@0
  1920
	manager->SetGatekeeper(0);
sl@0
  1921
sl@0
  1922
	// 3. when memory is reclaimed
sl@0
  1923
	reclaimer->iTarget = noMem;
sl@0
  1924
	manager->SetGatekeeper(reclaimer);
sl@0
  1925
	log->SetCheckString(_L("inc<>neg<>nomemfailadd.nomemfailinv.nomem<>dec<>neg<>negate<1>"));
sl@0
  1926
	TRAP(err, SetUpTestL(*manager, *noMem, &target, log));
sl@0
  1927
	CheckErrorCode(err, KErrNone);
sl@0
  1928
	CheckLog(*log);
sl@0
  1929
	log->SetCheckString(_L("offset<1>negate<1>"));
sl@0
  1930
	manager->UndoL();
sl@0
  1931
	CheckLog(*log);
sl@0
  1932
	log->SetCheckString(_L("offset<-1>"));
sl@0
  1933
	manager->UndoL();
sl@0
  1934
	CheckLog(*log);
sl@0
  1935
	TestCannotUndo(*manager);
sl@0
  1936
	manager->ResetUndo();
sl@0
  1937
	manager->SetGatekeeper(0);
sl@0
  1938
sl@0
  1939
	// Test when execution runs out of memory
sl@0
  1940
	// 1. with no reclaimation
sl@0
  1941
	noMem->iFailAddToLast	= EFalse;
sl@0
  1942
	noMem->iFailInvert		= EFalse;
sl@0
  1943
	noMem->iFailExecute		= ETrue;
sl@0
  1944
	noMem->iLogExecuteFailed= ETrue;
sl@0
  1945
	log->SetCheckString(_L("inc<>neg<>nomemfailexe."));
sl@0
  1946
	TRAP(err, SetUpTestL(*manager, *noMem, &target, log));
sl@0
  1947
	CheckErrorCode(err, KErrNoMemory);
sl@0
  1948
	CheckLog(*log);
sl@0
  1949
	TestCannotRedo(*manager);
sl@0
  1950
	log->SetCheckString(_L("negate<1>"));
sl@0
  1951
	manager->UndoL();
sl@0
  1952
	CheckLog(*log);
sl@0
  1953
	log->SetCheckString(_L("offset<-1>"));
sl@0
  1954
	manager->UndoL();
sl@0
  1955
	CheckLog(*log);
sl@0
  1956
	TestCannotUndo(*manager);
sl@0
  1957
	manager->ResetUndo();
sl@0
  1958
	// 2. with reclaimation
sl@0
  1959
	noMem->iFailAddToLast	= EFalse;
sl@0
  1960
	noMem->iFailInvert		= EFalse;
sl@0
  1961
	noMem->iFailExecute		= ETrue;
sl@0
  1962
	noMem->iLogExecuteFailed= ETrue;
sl@0
  1963
	reclaimer->iTarget = noMem;
sl@0
  1964
	manager->SetGatekeeper(reclaimer);
sl@0
  1965
	log->SetCheckString(_L("inc<>neg<>nomemfailexe.nomem<>dec<>neg<>negate<1>"));
sl@0
  1966
	TRAP(err, SetUpTestL(*manager, *noMem, &target, log));
sl@0
  1967
	CheckErrorCode(err, KErrNone);
sl@0
  1968
	CheckLog(*log);
sl@0
  1969
	log->SetCheckString(_L("offset<1>negate<1>"));
sl@0
  1970
	manager->UndoL();
sl@0
  1971
	CheckLog(*log);
sl@0
  1972
	log->SetCheckString(_L("offset<-1>"));
sl@0
  1973
	manager->UndoL();
sl@0
  1974
	CheckLog(*log);
sl@0
  1975
	TestCannotUndo(*manager);
sl@0
  1976
	manager->ResetUndo();
sl@0
  1977
	manager->SetGatekeeper(0);
sl@0
  1978
	delete noMem;
sl@0
  1979
sl@0
  1980
	delete inc;
sl@0
  1981
	delete dec;
sl@0
  1982
	delete neg;
sl@0
  1983
	delete reclaimer;
sl@0
  1984
	delete refuser;
sl@0
  1985
	delete permitter;
sl@0
  1986
	delete log;
sl@0
  1987
	manager->Release();
sl@0
  1988
sl@0
  1989
	__UHEAP_MARKENDC(0);
sl@0
  1990
	}
sl@0
  1991
sl@0
  1992
//
sl@0
  1993
//
sl@0
  1994
//	Tests involving CTestEditor
sl@0
  1995
//
sl@0
  1996
//
sl@0
  1997
sl@0
  1998
void CheckEditorLog(CCheckingLogger& a)
sl@0
  1999
	{
sl@0
  2000
	if (a.Passed())
sl@0
  2001
		{
sl@0
  2002
	    TESTPOINT(1);
sl@0
  2003
		return;
sl@0
  2004
		}
sl@0
  2005
	TESTPRINT(_L("EditorUndo : log failed"));
sl@0
  2006
	TESTPOINT(0);
sl@0
  2007
	}
sl@0
  2008
sl@0
  2009
void TestPlainText(CTestEditor& aTestEditor, MUnifiedEditor& aUndoEditor,
sl@0
  2010
				   CCommandManager& aCommandManager)
sl@0
  2011
	{
sl@0
  2012
	CCheckingLogger* check = new(ELeave) CCheckingLogger;
sl@0
  2013
	CStoringLogger* log = new(ELeave) CStoringLogger;
sl@0
  2014
sl@0
  2015
	//
sl@0
  2016
	// general inserting and deleting text
sl@0
  2017
	//
sl@0
  2018
	aUndoEditor.InsertTextL(0, _L("Hello world!"), 0, 0, 0);
sl@0
  2019
sl@0
  2020
	aCommandManager.ResetUndo();
sl@0
  2021
sl@0
  2022
	aTestEditor.Print(*log);
sl@0
  2023
	HBufC* helloWorldLog = log->GetStore();
sl@0
  2024
sl@0
  2025
	check->SetCheckString(*helloWorldLog);
sl@0
  2026
	aTestEditor.Print(*check);
sl@0
  2027
	CheckEditorLog(*check);
sl@0
  2028
	aUndoEditor.InsertTextL(5, _L(" lovely"), 0, 0, 0);
sl@0
  2029
	aTestEditor.Print(*log);
sl@0
  2030
	HBufC* helloLovelyWorldLog = log->GetStore();
sl@0
  2031
	aUndoEditor.DeleteTextL(10, 8);
sl@0
  2032
	aTestEditor.Print(*log);
sl@0
  2033
	HBufC* helloLoveLog = log->GetStore();
sl@0
  2034
	aCommandManager.UndoL();
sl@0
  2035
	check->SetCheckString(*helloLovelyWorldLog);
sl@0
  2036
	aTestEditor.Print(*check);
sl@0
  2037
	CheckEditorLog(*check);
sl@0
  2038
	aCommandManager.UndoL();
sl@0
  2039
	check->SetCheckString(*helloWorldLog);
sl@0
  2040
	aTestEditor.Print(*check);
sl@0
  2041
	CheckEditorLog(*check);
sl@0
  2042
	aCommandManager.RedoL();
sl@0
  2043
	check->SetCheckString(*helloLovelyWorldLog);
sl@0
  2044
	aTestEditor.Print(*check);
sl@0
  2045
	CheckEditorLog(*check);
sl@0
  2046
	aCommandManager.RedoL();
sl@0
  2047
	check->SetCheckString(*helloLoveLog);
sl@0
  2048
	aTestEditor.Print(*check);
sl@0
  2049
	CheckEditorLog(*check);
sl@0
  2050
	aCommandManager.UndoL();
sl@0
  2051
	check->SetCheckString(*helloLovelyWorldLog);
sl@0
  2052
	aTestEditor.Print(*check);
sl@0
  2053
	CheckEditorLog(*check);
sl@0
  2054
	aCommandManager.UndoL();
sl@0
  2055
	check->SetCheckString(*helloWorldLog);
sl@0
  2056
	aTestEditor.Print(*check);
sl@0
  2057
	CheckEditorLog(*check);
sl@0
  2058
sl@0
  2059
	aUndoEditor.InsertTextL(6, _L("w"), 0, 0, 0);
sl@0
  2060
	aUndoEditor.InsertTextL(7, _L("h"), 0, 0, 0);
sl@0
  2061
	aUndoEditor.InsertTextL(8, _L("at's"), 0, 0, 0);
sl@0
  2062
	aUndoEditor.InsertTextL(12, _L(" "), 0, 0, 0);
sl@0
  2063
	aUndoEditor.InsertTextL(13, _L("w"), 0, 0, 0);
sl@0
  2064
	aUndoEditor.InsertTextL(14, _L("i"), 0, 0, 0);
sl@0
  2065
	aUndoEditor.InsertTextL(6, _L("there "), 0, 0, 0);
sl@0
  2066
	aUndoEditor.InsertTextL(21, _L("t"), 0, 0, 0);
sl@0
  2067
	aUndoEditor.InsertTextL(22, _L("h"), 0, 0, 0);
sl@0
  2068
	aUndoEditor.InsertTextL(23, _L(" "), 0, 0, 0);
sl@0
  2069
	aTestEditor.Print(*log);
sl@0
  2070
	HBufC* textLog0 = log->GetStore();
sl@0
  2071
	aUndoEditor.InsertTextL(24, _L("the"), 0, 0, 0);	// first of next
sl@0
  2072
	aUndoEditor.InsertTextL(27, _L(" "), 0, 0, 0);
sl@0
  2073
	aUndoEditor.InsertTextL(28, _L("d "), 0, 0, 0);
sl@0
  2074
	aUndoEditor.InsertTextL(28, _L("ol"), 0, 0, 0);
sl@0
  2075
	aTestEditor.Print(*log);
sl@0
  2076
	HBufC* textLog1 = log->GetStore();
sl@0
  2077
sl@0
  2078
	aCommandManager.UndoL();
sl@0
  2079
	check->SetCheckString(*textLog0);
sl@0
  2080
	aTestEditor.Print(*check);
sl@0
  2081
	CheckEditorLog(*check);
sl@0
  2082
sl@0
  2083
	aCommandManager.UndoL();
sl@0
  2084
	check->SetCheckString(*helloWorldLog);
sl@0
  2085
	aTestEditor.Print(*check);
sl@0
  2086
	CheckEditorLog(*check);
sl@0
  2087
sl@0
  2088
	aCommandManager.RedoL();
sl@0
  2089
	check->SetCheckString(*textLog0);
sl@0
  2090
	aTestEditor.Print(*check);
sl@0
  2091
	CheckEditorLog(*check);
sl@0
  2092
sl@0
  2093
	aCommandManager.RedoL();
sl@0
  2094
	check->SetCheckString(*textLog1);
sl@0
  2095
	aTestEditor.Print(*check);
sl@0
  2096
	CheckEditorLog(*check);
sl@0
  2097
sl@0
  2098
	// check coalescence of insertions
sl@0
  2099
	aTestEditor.AlterGranularityL(5);
sl@0
  2100
	aUndoEditor.DeleteTextL(22, 1);
sl@0
  2101
	aUndoEditor.DeleteTextL(21, 1);
sl@0
  2102
	aUndoEditor.DeleteTextL(20, 1);
sl@0
  2103
	aUndoEditor.DeleteTextL(19, 1);
sl@0
  2104
	aUndoEditor.DeleteTextL(18, 1);
sl@0
  2105
	aUndoEditor.DeleteTextL(18, 1);
sl@0
  2106
	aUndoEditor.DeleteTextL(15, 3);		// this will coalesce
sl@0
  2107
	aUndoEditor.DeleteTextL(6, 9);		// this won't, as it does not fit in one command
sl@0
  2108
	aTestEditor.Print(*log);
sl@0
  2109
	HBufC* delLog0 = log->GetStore();
sl@0
  2110
	aUndoEditor.DeleteTextL(4, 1);
sl@0
  2111
	aTestEditor.Print(*log);
sl@0
  2112
	HBufC* delLog1 = log->GetStore();
sl@0
  2113
	aUndoEditor.DeleteTextL(8, 2);
sl@0
  2114
	aUndoEditor.DeleteTextL(8, 1);	// should coalesce
sl@0
  2115
	aUndoEditor.DeleteTextL(8, 1);	// should coalesce
sl@0
  2116
	aTestEditor.Print(*log);
sl@0
  2117
	HBufC* delLog3 = log->GetStore();
sl@0
  2118
sl@0
  2119
	aCommandManager.UndoL();
sl@0
  2120
	check->SetCheckString(*delLog1);
sl@0
  2121
	aTestEditor.Print(*check);
sl@0
  2122
	CheckEditorLog(*check);
sl@0
  2123
sl@0
  2124
	aCommandManager.UndoL();
sl@0
  2125
	check->SetCheckString(*delLog0);
sl@0
  2126
	aTestEditor.Print(*check);
sl@0
  2127
	CheckEditorLog(*check);
sl@0
  2128
sl@0
  2129
	aCommandManager.UndoL();
sl@0
  2130
	aCommandManager.UndoL();
sl@0
  2131
	check->SetCheckString(*textLog1);
sl@0
  2132
	aTestEditor.Print(*check);
sl@0
  2133
	CheckEditorLog(*check);
sl@0
  2134
sl@0
  2135
	aCommandManager.RedoL();
sl@0
  2136
	aCommandManager.RedoL();
sl@0
  2137
	check->SetCheckString(*delLog0);
sl@0
  2138
	aTestEditor.Print(*check);
sl@0
  2139
	CheckEditorLog(*check);
sl@0
  2140
sl@0
  2141
	aCommandManager.RedoL();
sl@0
  2142
	check->SetCheckString(*delLog1);
sl@0
  2143
	aTestEditor.Print(*check);
sl@0
  2144
	CheckEditorLog(*check);
sl@0
  2145
sl@0
  2146
	aCommandManager.RedoL();
sl@0
  2147
	check->SetCheckString(*delLog3);
sl@0
  2148
	aTestEditor.Print(*check);
sl@0
  2149
	CheckEditorLog(*check);
sl@0
  2150
sl@0
  2151
	aCommandManager.UndoL();
sl@0
  2152
	check->SetCheckString(*delLog1);
sl@0
  2153
	aTestEditor.Print(*check);
sl@0
  2154
	CheckEditorLog(*check);
sl@0
  2155
sl@0
  2156
	aCommandManager.UndoL();
sl@0
  2157
	check->SetCheckString(*delLog0);
sl@0
  2158
	aTestEditor.Print(*check);
sl@0
  2159
	CheckEditorLog(*check);
sl@0
  2160
sl@0
  2161
	aCommandManager.UndoL();
sl@0
  2162
	aCommandManager.UndoL();
sl@0
  2163
	check->SetCheckString(*textLog1);
sl@0
  2164
	aTestEditor.Print(*check);
sl@0
  2165
	CheckEditorLog(*check);
sl@0
  2166
sl@0
  2167
	aCommandManager.UndoL();
sl@0
  2168
	aCommandManager.UndoL();
sl@0
  2169
	check->SetCheckString(*helloWorldLog);
sl@0
  2170
	aTestEditor.Print(*check);
sl@0
  2171
	CheckEditorLog(*check);
sl@0
  2172
sl@0
  2173
	aCommandManager.ResetUndo();
sl@0
  2174
	delete delLog0;
sl@0
  2175
	delete delLog1;
sl@0
  2176
	delete delLog3;
sl@0
  2177
sl@0
  2178
	// Check adding large amounts of text
sl@0
  2179
	aTestEditor.AlterGranularityL(32);
sl@0
  2180
	aUndoEditor.InsertTextL(0, _L("123456789"), 0, 0, 0);
sl@0
  2181
	aUndoEditor.InsertTextL(0, _L("223456789"), 0, 0, 0);
sl@0
  2182
	aTestEditor.Print(*log);
sl@0
  2183
	HBufC* largeLog0 = log->GetStore();
sl@0
  2184
	aUndoEditor.InsertTextL(0, _L("3234567890"), 0, 0, 0);
sl@0
  2185
	aUndoEditor.InsertTextL(0, _L("4234567890"), 0, 0, 0);
sl@0
  2186
	aTestEditor.Print(*log);
sl@0
  2187
	HBufC* largeLog1 = log->GetStore();
sl@0
  2188
	aUndoEditor.InsertTextL(0, _L("523456789"), 0, 0, 0);
sl@0
  2189
	aTestEditor.Print(*log);
sl@0
  2190
	HBufC* largeLog2 = log->GetStore();
sl@0
  2191
sl@0
  2192
	aCommandManager.UndoL();
sl@0
  2193
	check->SetCheckString(*largeLog1);
sl@0
  2194
	aTestEditor.Print(*check);
sl@0
  2195
	CheckEditorLog(*check);
sl@0
  2196
sl@0
  2197
	aCommandManager.UndoL();
sl@0
  2198
	check->SetCheckString(*largeLog0);
sl@0
  2199
	aTestEditor.Print(*check);
sl@0
  2200
	CheckEditorLog(*check);
sl@0
  2201
sl@0
  2202
	aCommandManager.UndoL();
sl@0
  2203
	check->SetCheckString(*helloWorldLog);
sl@0
  2204
	aTestEditor.Print(*check);
sl@0
  2205
	CheckEditorLog(*check);
sl@0
  2206
sl@0
  2207
	aCommandManager.RedoL();
sl@0
  2208
	check->SetCheckString(*largeLog0);
sl@0
  2209
	aTestEditor.Print(*check);
sl@0
  2210
	CheckEditorLog(*check);
sl@0
  2211
sl@0
  2212
	aCommandManager.RedoL();
sl@0
  2213
	check->SetCheckString(*largeLog1);
sl@0
  2214
	aTestEditor.Print(*check);
sl@0
  2215
	CheckEditorLog(*check);
sl@0
  2216
sl@0
  2217
	aCommandManager.RedoL();
sl@0
  2218
	check->SetCheckString(*largeLog2);
sl@0
  2219
	aTestEditor.Print(*check);
sl@0
  2220
	CheckEditorLog(*check);
sl@0
  2221
sl@0
  2222
	aCommandManager.UndoL();
sl@0
  2223
	check->SetCheckString(*largeLog1);
sl@0
  2224
	aTestEditor.Print(*check);
sl@0
  2225
	CheckEditorLog(*check);
sl@0
  2226
sl@0
  2227
	aCommandManager.UndoL();
sl@0
  2228
	check->SetCheckString(*largeLog0);
sl@0
  2229
	aTestEditor.Print(*check);
sl@0
  2230
	CheckEditorLog(*check);
sl@0
  2231
sl@0
  2232
	aCommandManager.UndoL();
sl@0
  2233
	check->SetCheckString(*helloWorldLog);
sl@0
  2234
 	aTestEditor.Print(*check);
sl@0
  2235
	CheckEditorLog(*check);
sl@0
  2236
sl@0
  2237
	aCommandManager.RedoL();
sl@0
  2238
	aCommandManager.RedoL();
sl@0
  2239
	aCommandManager.RedoL();
sl@0
  2240
sl@0
  2241
	// test copy and paste
sl@0
  2242
	MUnifiedEditor::MClipboardSupport* ci = aUndoEditor.ClipboardSupport();
sl@0
  2243
	ASSERT(ci);
sl@0
  2244
sl@0
  2245
	CBufStore* clipboardBuffer = CBufStore::NewL(100);
sl@0
  2246
	CStreamDictionary* clipboardDictionary = CStreamDictionary::NewL();
sl@0
  2247
sl@0
  2248
	ci->CopyToStoreL(*clipboardBuffer, *clipboardDictionary, 5, 40);
sl@0
  2249
	aTestEditor.Print(*log);
sl@0
  2250
	HBufC* clipLog0 = log->GetStore();
sl@0
  2251
	ci->PasteFromStoreL(*clipboardBuffer, *clipboardDictionary, 2);
sl@0
  2252
	aTestEditor.Print(*log);
sl@0
  2253
	HBufC* clipLog1 = log->GetStore();
sl@0
  2254
	ci->PasteFromStoreL(*clipboardBuffer, *clipboardDictionary, 55);
sl@0
  2255
	aTestEditor.Print(*log);
sl@0
  2256
	HBufC* clipLog2 = log->GetStore();
sl@0
  2257
	ci->PasteFromStoreL(*clipboardBuffer, *clipboardDictionary, 23);
sl@0
  2258
	aTestEditor.Print(*log);
sl@0
  2259
	HBufC* clipLog3 = log->GetStore();
sl@0
  2260
sl@0
  2261
	aCommandManager.UndoL();
sl@0
  2262
	check->SetCheckString(*clipLog2);
sl@0
  2263
	aTestEditor.Print(*check);
sl@0
  2264
	CheckEditorLog(*check);
sl@0
  2265
sl@0
  2266
	aCommandManager.UndoL();
sl@0
  2267
	check->SetCheckString(*clipLog1);
sl@0
  2268
	aTestEditor.Print(*check);
sl@0
  2269
	CheckEditorLog(*check);
sl@0
  2270
sl@0
  2271
	aCommandManager.UndoL();
sl@0
  2272
	check->SetCheckString(*clipLog0);
sl@0
  2273
	aTestEditor.Print(*check);
sl@0
  2274
	CheckEditorLog(*check);
sl@0
  2275
sl@0
  2276
	aCommandManager.RedoL();
sl@0
  2277
	check->SetCheckString(*clipLog1);
sl@0
  2278
	aTestEditor.Print(*check);
sl@0
  2279
	CheckEditorLog(*check);
sl@0
  2280
sl@0
  2281
	aCommandManager.RedoL();
sl@0
  2282
	check->SetCheckString(*clipLog2);
sl@0
  2283
	aTestEditor.Print(*check);
sl@0
  2284
	CheckEditorLog(*check);
sl@0
  2285
sl@0
  2286
	aCommandManager.RedoL();
sl@0
  2287
	check->SetCheckString(*clipLog3);
sl@0
  2288
	aTestEditor.Print(*check);
sl@0
  2289
	CheckEditorLog(*check);
sl@0
  2290
sl@0
  2291
	aCommandManager.UndoL();
sl@0
  2292
	check->SetCheckString(*clipLog2);
sl@0
  2293
	aTestEditor.Print(*check);
sl@0
  2294
	CheckEditorLog(*check);
sl@0
  2295
sl@0
  2296
	aCommandManager.UndoL();
sl@0
  2297
	check->SetCheckString(*clipLog1);
sl@0
  2298
	aTestEditor.Print(*check);
sl@0
  2299
	CheckEditorLog(*check);
sl@0
  2300
sl@0
  2301
	aCommandManager.UndoL();
sl@0
  2302
	check->SetCheckString(*clipLog0);
sl@0
  2303
	aTestEditor.Print(*check);
sl@0
  2304
	CheckEditorLog(*check);
sl@0
  2305
sl@0
  2306
	delete clipLog0;
sl@0
  2307
	delete clipLog1;
sl@0
  2308
	delete clipLog2;
sl@0
  2309
	delete clipLog3;
sl@0
  2310
	delete clipboardDictionary;
sl@0
  2311
	delete clipboardBuffer;
sl@0
  2312
sl@0
  2313
	delete textLog0;
sl@0
  2314
	delete textLog1;
sl@0
  2315
sl@0
  2316
	delete largeLog0;
sl@0
  2317
	delete largeLog1;
sl@0
  2318
	delete largeLog2;
sl@0
  2319
sl@0
  2320
	delete helloWorldLog;
sl@0
  2321
	delete helloLovelyWorldLog;
sl@0
  2322
	delete helloLoveLog;
sl@0
  2323
	delete log;
sl@0
  2324
	delete check;
sl@0
  2325
	}
sl@0
  2326
sl@0
  2327
// This class merely splits the test function into little functions
sl@0
  2328
// to help out the MW compiler
sl@0
  2329
class TestEditorUndo
sl@0
  2330
	{
sl@0
  2331
	CCheckingLogger* check;
sl@0
  2332
	CStoringLogger* log;
sl@0
  2333
	CTestEditor* testEd;
sl@0
  2334
	CCommandManager* manager;
sl@0
  2335
	CEditorPlainTextWithUndo* plainEd;
sl@0
  2336
	CEditorWithUndo* ed;
sl@0
  2337
	TTmCharFormatMask charBMask;
sl@0
  2338
	TTmCharFormatMask charIMask;
sl@0
  2339
	TTmCharFormatMask charBIMask;
sl@0
  2340
	TOpenFontFaceAttribBase attrib;
sl@0
  2341
	TTmCharFormat charB;
sl@0
  2342
	TTmCharFormat charIB;
sl@0
  2343
	TTmCharFormat charI;
sl@0
  2344
	TTmParFormatMask parTMask;
sl@0
  2345
	TTmParFormatMask parNMask;
sl@0
  2346
	TTmParFormatMask parTNMask;
sl@0
  2347
	RTmParFormat par0;
sl@0
  2348
	RTmParFormat parT;
sl@0
  2349
	RTmParFormat parN;
sl@0
  2350
	RTmParFormat parTN;
sl@0
  2351
	TTmCharFormatLayer charLayer;
sl@0
  2352
	RTmParFormatLayer parLayer;
sl@0
  2353
	RTmStyle style1;
sl@0
  2354
	RTmStyle style2;
sl@0
  2355
	HBufC* charLog0;
sl@0
  2356
	HBufC* charLog1;
sl@0
  2357
	HBufC* charLog2;
sl@0
  2358
	HBufC* charLog3;
sl@0
  2359
	HBufC* textLog0;
sl@0
  2360
	HBufC* textLog1;
sl@0
  2361
	HBufC* textLog2;
sl@0
  2362
	HBufC* textLog3;
sl@0
  2363
	HBufC* parLog0;
sl@0
  2364
	HBufC* parLog1;
sl@0
  2365
	HBufC* parLog2;
sl@0
  2366
	HBufC* parLog3;
sl@0
  2367
	HBufC* delLog0;
sl@0
  2368
	HBufC* delLog1;
sl@0
  2369
	HBufC* delLog2;
sl@0
  2370
	HBufC* delLog3;
sl@0
  2371
	HBufC* styleLog1;
sl@0
  2372
	HBufC* styleLog2;
sl@0
  2373
	HBufC* styleLog3;
sl@0
  2374
	HBufC* styleLog4;
sl@0
  2375
	HBufC* styleLog5;
sl@0
  2376
	HBufC* styleLog6;
sl@0
  2377
	HBufC* styleLog7;
sl@0
  2378
	HBufC* styleLog8;
sl@0
  2379
	HBufC* styleLog9;
sl@0
  2380
	HBufC* styleLog10;
sl@0
  2381
	HBufC* styleLog11;
sl@0
  2382
	HBufC* styleLog12;
sl@0
  2383
	HBufC* styleLog13;
sl@0
  2384
	HBufC* picLog0;
sl@0
  2385
	HBufC* picLog1;
sl@0
  2386
	HBufC* picLog2;
sl@0
  2387
	HBufC* picLog3;
sl@0
  2388
	HBufC* picLog4;
sl@0
  2389
	HBufC* picLog5;
sl@0
  2390
	HBufC* bookMarkLog0;
sl@0
  2391
	HBufC* bookMarkLog1;
sl@0
  2392
	HBufC* bookMarkLog2;
sl@0
  2393
	HBufC* bookMarkLog3;
sl@0
  2394
	HBufC* bookMarkLog4;
sl@0
  2395
	HBufC* bookMarkLog5;
sl@0
  2396
public:
sl@0
  2397
	void Test1L();
sl@0
  2398
	void Test2L();
sl@0
  2399
	void Test3L();
sl@0
  2400
	void Test4L();
sl@0
  2401
	void Test5L();
sl@0
  2402
	void Test6L();
sl@0
  2403
	void Test7L();
sl@0
  2404
	void Test8L();
sl@0
  2405
	};
sl@0
  2406
sl@0
  2407
void TestEditorUndo::Test1L()
sl@0
  2408
	{
sl@0
  2409
	check = new(ELeave) CCheckingLogger;
sl@0
  2410
	log = new(ELeave) CStoringLogger;
sl@0
  2411
	testEd = CTestEditor::NewL();
sl@0
  2412
	manager = CCommandManager::NewL();
sl@0
  2413
	plainEd = CEditorPlainTextWithUndo::NewL(*testEd, manager);
sl@0
  2414
sl@0
  2415
	TestPlainText(*testEd, *plainEd, *manager);
sl@0
  2416
	ed = CEditorWithUndo::NewL(*testEd, manager);
sl@0
  2417
	testEd->DeleteTextL(0, testEd->DocumentLength());
sl@0
  2418
	manager->ResetUndo();
sl@0
  2419
sl@0
  2420
	delete plainEd;
sl@0
  2421
	plainEd = 0;
sl@0
  2422
sl@0
  2423
	TestPlainText(*testEd, *ed, *manager);
sl@0
  2424
	manager->Release();
sl@0
  2425
	}
sl@0
  2426
sl@0
  2427
void TestEditorUndo::Test2L()
sl@0
  2428
	{
sl@0
  2429
	// char and par formats
sl@0
  2430
	charBMask.iFlags = TTmCharFormatMask::EBold;
sl@0
  2431
	charIMask.iFlags = TTmCharFormatMask::EItalic;
sl@0
  2432
	charBIMask.iFlags = TTmCharFormatMask::EItalic | TTmCharFormatMask::EBold;
sl@0
  2433
	attrib.SetBold(ETrue);
sl@0
  2434
	charB.iFontSpec.SetAttrib(attrib);
sl@0
  2435
	attrib.SetItalic(ETrue);
sl@0
  2436
	charIB.iFontSpec.SetAttrib(attrib);
sl@0
  2437
	attrib.SetBold(EFalse);
sl@0
  2438
	charI.iFontSpec.SetAttrib(attrib);
sl@0
  2439
sl@0
  2440
	parTMask.iFlags = TTmParFormatMask::EKeepTogether;
sl@0
  2441
	parNMask.iFlags = TTmParFormatMask::EKeepWithNext;
sl@0
  2442
	parTNMask.iFlags = TTmParFormatMask::EKeepTogether | TTmParFormatMask::EKeepWithNext;
sl@0
  2443
	parT.iFlags = RTmParFormat::EKeepTogether;
sl@0
  2444
	parN.iFlags = RTmParFormat::EKeepWithNext;
sl@0
  2445
	parTN.iFlags = RTmParFormat::EKeepWithNext | RTmParFormat::EKeepTogether;
sl@0
  2446
sl@0
  2447
	charLayer.iFormat = charB;
sl@0
  2448
	charLayer.iMask = charBMask;
sl@0
  2449
	ed->SetCharFormatL(0, 5, charLayer);
sl@0
  2450
	testEd->Print(*log);
sl@0
  2451
	charLog0 = log->GetStore();
sl@0
  2452
sl@0
  2453
	charLayer.iFormat = charI;
sl@0
  2454
	charLayer.iMask = charIMask;
sl@0
  2455
	ed->SetCharFormatL(3, 9, charLayer);
sl@0
  2456
	testEd->Print(*log);
sl@0
  2457
	charLog1 = log->GetStore();
sl@0
  2458
sl@0
  2459
	charLayer.iFormat = charB;
sl@0
  2460
	charLayer.iMask = charBIMask;
sl@0
  2461
	ed->SetCharFormatL(2, 5, charLayer);
sl@0
  2462
	testEd->Print(*log);
sl@0
  2463
	charLog2 = log->GetStore();
sl@0
  2464
sl@0
  2465
	ed->DeleteCharFormatL(1, 10);
sl@0
  2466
	testEd->Print(*log);
sl@0
  2467
	charLog3 = log->GetStore();
sl@0
  2468
sl@0
  2469
	ed->UndoL();
sl@0
  2470
	check->SetCheckString(*charLog2);
sl@0
  2471
	testEd->Print(*check);
sl@0
  2472
	CheckEditorLog(*check);
sl@0
  2473
sl@0
  2474
	ed->UndoL();
sl@0
  2475
	check->SetCheckString(*charLog1);
sl@0
  2476
	testEd->Print(*check);
sl@0
  2477
	CheckEditorLog(*check);
sl@0
  2478
sl@0
  2479
	ed->UndoL();
sl@0
  2480
	check->SetCheckString(*charLog0);
sl@0
  2481
	testEd->Print(*check);
sl@0
  2482
	CheckEditorLog(*check);
sl@0
  2483
sl@0
  2484
	ed->RedoL();
sl@0
  2485
	check->SetCheckString(*charLog1);
sl@0
  2486
	testEd->Print(*check);
sl@0
  2487
	CheckEditorLog(*check);
sl@0
  2488
sl@0
  2489
	ed->RedoL();
sl@0
  2490
	check->SetCheckString(*charLog2);
sl@0
  2491
	testEd->Print(*check);
sl@0
  2492
	CheckEditorLog(*check);
sl@0
  2493
sl@0
  2494
	ed->RedoL();
sl@0
  2495
	check->SetCheckString(*charLog3);
sl@0
  2496
	testEd->Print(*check);
sl@0
  2497
	CheckEditorLog(*check);
sl@0
  2498
sl@0
  2499
	parLayer.iMask = parTMask;
sl@0
  2500
	parLayer.iFormat.CopyL(parT);
sl@0
  2501
	ed->SetParFormatL(5, 7, parLayer);
sl@0
  2502
	testEd->Print(*log);
sl@0
  2503
	parLog0 = log->GetStore();
sl@0
  2504
sl@0
  2505
	parLayer.iMask = parTNMask;
sl@0
  2506
	parLayer.iFormat.CopyL(parN);
sl@0
  2507
	ed->SetParFormatL(0, 7, parLayer);
sl@0
  2508
	testEd->Print(*log);
sl@0
  2509
	parLog1 = log->GetStore();
sl@0
  2510
sl@0
  2511
	ed->DeleteParFormatL(4, 4);
sl@0
  2512
	testEd->Print(*log);
sl@0
  2513
	parLog2 = log->GetStore();
sl@0
  2514
sl@0
  2515
	parLayer.iMask = parNMask;
sl@0
  2516
	parLayer.iFormat.CopyL(parN);
sl@0
  2517
	ed->SetParFormatL(3, 6, parLayer);
sl@0
  2518
	testEd->Print(*log);
sl@0
  2519
	parLog3 = log->GetStore();
sl@0
  2520
sl@0
  2521
	ed->UndoL();
sl@0
  2522
	check->SetCheckString(*parLog2);
sl@0
  2523
	testEd->Print(*check);
sl@0
  2524
	CheckEditorLog(*check);
sl@0
  2525
sl@0
  2526
	ed->UndoL();
sl@0
  2527
	check->SetCheckString(*parLog1);
sl@0
  2528
	testEd->Print(*check);
sl@0
  2529
	CheckEditorLog(*check);
sl@0
  2530
sl@0
  2531
	ed->UndoL();
sl@0
  2532
	check->SetCheckString(*parLog0);
sl@0
  2533
	testEd->Print(*check);
sl@0
  2534
	CheckEditorLog(*check);
sl@0
  2535
sl@0
  2536
	ed->UndoL();
sl@0
  2537
	check->SetCheckString(*charLog3);
sl@0
  2538
	testEd->Print(*check);
sl@0
  2539
	CheckEditorLog(*check);
sl@0
  2540
sl@0
  2541
	ed->RedoL();
sl@0
  2542
	check->SetCheckString(*parLog0);
sl@0
  2543
	testEd->Print(*check);
sl@0
  2544
	CheckEditorLog(*check);
sl@0
  2545
sl@0
  2546
	ed->RedoL();
sl@0
  2547
	check->SetCheckString(*parLog1);
sl@0
  2548
	testEd->Print(*check);
sl@0
  2549
	CheckEditorLog(*check);
sl@0
  2550
sl@0
  2551
	ed->RedoL();
sl@0
  2552
	check->SetCheckString(*parLog2);
sl@0
  2553
	testEd->Print(*check);
sl@0
  2554
	CheckEditorLog(*check);
sl@0
  2555
sl@0
  2556
	ed->RedoL();
sl@0
  2557
	check->SetCheckString(*parLog3);
sl@0
  2558
	testEd->Print(*check);
sl@0
  2559
	CheckEditorLog(*check);
sl@0
  2560
	}
sl@0
  2561
sl@0
  2562
void TestEditorUndo::Test3L()
sl@0
  2563
	{
sl@0
  2564
	// check coalescence of deletions
sl@0
  2565
	charLayer.iMask = charIMask;
sl@0
  2566
	charLayer.iFormat = charI;
sl@0
  2567
	parLayer.iMask = parNMask;
sl@0
  2568
	parLayer.iFormat.CopyL(parN);
sl@0
  2569
	ed->InsertTextL(6, _L("w"), 0, &charLayer, &parLayer);
sl@0
  2570
	ed->InsertTextL(7, _L("h"), 0, &charLayer, &parLayer);
sl@0
  2571
	ed->InsertTextL(8, _L("at's"), 0, &charLayer, &parLayer);
sl@0
  2572
	ed->InsertTextL(12, _L(" "), 0, &charLayer, &parLayer);
sl@0
  2573
	ed->InsertTextL(13, _L("w"), 0, &charLayer, &parLayer);
sl@0
  2574
	ed->InsertTextL(14, _L("i"), 0, &charLayer, &parLayer);
sl@0
  2575
	ed->InsertTextL(6, _L("there "), 0, &charLayer, &parLayer);
sl@0
  2576
	ed->InsertTextL(21, _L("t"), 0, &charLayer, &parLayer);
sl@0
  2577
	ed->InsertTextL(22, _L("h"), 0, &charLayer, &parLayer);
sl@0
  2578
	ed->InsertTextL(23, _L(" "), 0, &charLayer, &parLayer);
sl@0
  2579
	testEd->Print(*log);
sl@0
  2580
	textLog0 = log->GetStore();
sl@0
  2581
	ed->InsertTextL(24, _L("the"), 0, &charLayer, &parLayer);	// first of next?
sl@0
  2582
	ed->InsertTextL(27, _L(" "), 0, &charLayer, &parLayer);
sl@0
  2583
	testEd->Print(*log);
sl@0
  2584
	textLog1 = log->GetStore();
sl@0
  2585
	charLayer.iMask = charBIMask;
sl@0
  2586
	ed->InsertTextL(28, _L("ol"), 0, &charLayer, &parLayer);
sl@0
  2587
	testEd->Print(*log);
sl@0
  2588
	textLog2 = log->GetStore();
sl@0
  2589
	parLayer.iMask = parTNMask;
sl@0
  2590
	ed->InsertTextL(30, _L("d "), 0, &charLayer, &parLayer);
sl@0
  2591
	testEd->Print(*log);
sl@0
  2592
	textLog3 = log->GetStore();
sl@0
  2593
sl@0
  2594
	ed->UndoL();
sl@0
  2595
	check->SetCheckString(*textLog0);
sl@0
  2596
	testEd->Print(*check);
sl@0
  2597
	CheckEditorLog(*check);
sl@0
  2598
sl@0
  2599
	ed->UndoL();
sl@0
  2600
	check->SetCheckString(*parLog3);
sl@0
  2601
	testEd->Print(*check);
sl@0
  2602
	CheckEditorLog(*check);
sl@0
  2603
sl@0
  2604
	ed->RedoL();
sl@0
  2605
	check->SetCheckString(*textLog0);
sl@0
  2606
	testEd->Print(*check);
sl@0
  2607
	CheckEditorLog(*check);
sl@0
  2608
sl@0
  2609
	ed->RedoL();
sl@0
  2610
	check->SetCheckString(*textLog3);
sl@0
  2611
	testEd->Print(*check);
sl@0
  2612
	CheckEditorLog(*check);
sl@0
  2613
	ed->ResetUndo();
sl@0
  2614
	}
sl@0
  2615
sl@0
  2616
void TestEditorUndo::Test4L()
sl@0
  2617
	{
sl@0
  2618
	// check coalescence of insertions
sl@0
  2619
	testEd->AlterGranularityL(5);
sl@0
  2620
	ed->DeleteTextL(22, 1);
sl@0
  2621
	ed->DeleteTextL(21, 1);
sl@0
  2622
	ed->DeleteTextL(20, 1);
sl@0
  2623
	ed->DeleteTextL(19, 1);
sl@0
  2624
	ed->DeleteTextL(18, 1);
sl@0
  2625
	ed->DeleteTextL(18, 1);
sl@0
  2626
	ed->DeleteTextL(15, 3);		// this will coalesce
sl@0
  2627
	ed->DeleteTextL(6, 9);		// this won't, as it does not fit in one command
sl@0
  2628
	testEd->Print(*log);
sl@0
  2629
	delLog0 = log->GetStore();
sl@0
  2630
	ed->DeleteTextL(4, 1);
sl@0
  2631
	testEd->Print(*log);
sl@0
  2632
	delLog1 = log->GetStore();
sl@0
  2633
	ed->DeleteTextL(8, 2);
sl@0
  2634
	ed->DeleteTextL(8, 1);	// should coalesce
sl@0
  2635
	testEd->Print(*log);
sl@0
  2636
	delLog2 = log->GetStore();
sl@0
  2637
	ed->DeleteTextL(8, 1);	// should fail to coalesce
sl@0
  2638
	testEd->Print(*log);
sl@0
  2639
	delLog3 = log->GetStore();
sl@0
  2640
sl@0
  2641
	ed->UndoL();
sl@0
  2642
	check->SetCheckString(*delLog2);
sl@0
  2643
	testEd->Print(*check);
sl@0
  2644
	CheckEditorLog(*check);
sl@0
  2645
sl@0
  2646
	ed->UndoL();
sl@0
  2647
	check->SetCheckString(*delLog1);
sl@0
  2648
	testEd->Print(*check);
sl@0
  2649
	CheckEditorLog(*check);
sl@0
  2650
sl@0
  2651
	ed->UndoL();
sl@0
  2652
	check->SetCheckString(*delLog0);
sl@0
  2653
	testEd->Print(*check);
sl@0
  2654
	CheckEditorLog(*check);
sl@0
  2655
sl@0
  2656
	ed->UndoL();
sl@0
  2657
	ed->UndoL();
sl@0
  2658
	check->SetCheckString(*textLog3);
sl@0
  2659
	testEd->Print(*check);
sl@0
  2660
	CheckEditorLog(*check);
sl@0
  2661
sl@0
  2662
	ed->RedoL();
sl@0
  2663
	ed->RedoL();
sl@0
  2664
	check->SetCheckString(*delLog0);
sl@0
  2665
	testEd->Print(*check);
sl@0
  2666
	CheckEditorLog(*check);
sl@0
  2667
sl@0
  2668
	ed->RedoL();
sl@0
  2669
	check->SetCheckString(*delLog1);
sl@0
  2670
	testEd->Print(*check);
sl@0
  2671
	CheckEditorLog(*check);
sl@0
  2672
sl@0
  2673
	ed->RedoL();
sl@0
  2674
	check->SetCheckString(*delLog2);
sl@0
  2675
	testEd->Print(*check);
sl@0
  2676
	CheckEditorLog(*check);
sl@0
  2677
sl@0
  2678
	ed->RedoL();
sl@0
  2679
	check->SetCheckString(*delLog3);
sl@0
  2680
	testEd->Print(*check);
sl@0
  2681
	CheckEditorLog(*check);
sl@0
  2682
sl@0
  2683
	ed->UndoL();
sl@0
  2684
	check->SetCheckString(*delLog2);
sl@0
  2685
	testEd->Print(*check);
sl@0
  2686
	CheckEditorLog(*check);
sl@0
  2687
sl@0
  2688
	ed->UndoL();
sl@0
  2689
	check->SetCheckString(*delLog1);
sl@0
  2690
	testEd->Print(*check);
sl@0
  2691
	CheckEditorLog(*check);
sl@0
  2692
sl@0
  2693
	ed->UndoL();
sl@0
  2694
	check->SetCheckString(*delLog0);
sl@0
  2695
	testEd->Print(*check);
sl@0
  2696
	CheckEditorLog(*check);
sl@0
  2697
sl@0
  2698
	ed->UndoL();
sl@0
  2699
	ed->UndoL();
sl@0
  2700
	check->SetCheckString(*textLog3);
sl@0
  2701
	testEd->Print(*check);
sl@0
  2702
	CheckEditorLog(*check);
sl@0
  2703
	ed->ResetUndo();
sl@0
  2704
	delete delLog0;
sl@0
  2705
	delete delLog1;
sl@0
  2706
	delete delLog2;
sl@0
  2707
	delete delLog3;
sl@0
  2708
	}
sl@0
  2709
sl@0
  2710
void TestEditorUndo::Test5L()
sl@0
  2711
	{
sl@0
  2712
	// Check adding large amounts of text
sl@0
  2713
	testEd->AlterGranularityL(32);
sl@0
  2714
	ed->InsertTextL(0, _L("123456789"), 0, 0, 0);
sl@0
  2715
	ed->InsertTextL(0, _L("223456789"), 0, 0, 0);
sl@0
  2716
	testEd->Print(*log);
sl@0
  2717
	delete textLog0;
sl@0
  2718
	textLog0 = log->GetStore();
sl@0
  2719
	ed->InsertTextL(0, _L("3234567890"), 0, 0, 0);
sl@0
  2720
	ed->InsertTextL(0, _L("4234567890"), 0, 0, 0);
sl@0
  2721
	testEd->Print(*log);
sl@0
  2722
	delete textLog1;
sl@0
  2723
	textLog1 = log->GetStore();
sl@0
  2724
	ed->InsertTextL(0, _L("523456789"), 0, 0, 0);
sl@0
  2725
	testEd->Print(*log);
sl@0
  2726
	delete textLog2;
sl@0
  2727
	textLog2 = log->GetStore();
sl@0
  2728
sl@0
  2729
	ed->UndoL();
sl@0
  2730
	check->SetCheckString(*textLog1);
sl@0
  2731
	testEd->Print(*check);
sl@0
  2732
	CheckEditorLog(*check);
sl@0
  2733
sl@0
  2734
	ed->UndoL();
sl@0
  2735
	check->SetCheckString(*textLog0);
sl@0
  2736
	testEd->Print(*check);
sl@0
  2737
	CheckEditorLog(*check);
sl@0
  2738
sl@0
  2739
	ed->UndoL();
sl@0
  2740
	check->SetCheckString(*textLog3);
sl@0
  2741
	testEd->Print(*check);
sl@0
  2742
	CheckEditorLog(*check);
sl@0
  2743
sl@0
  2744
	ed->RedoL();
sl@0
  2745
	check->SetCheckString(*textLog0);
sl@0
  2746
	testEd->Print(*check);
sl@0
  2747
	CheckEditorLog(*check);
sl@0
  2748
sl@0
  2749
	ed->RedoL();
sl@0
  2750
	check->SetCheckString(*textLog1);
sl@0
  2751
	testEd->Print(*check);
sl@0
  2752
	CheckEditorLog(*check);
sl@0
  2753
sl@0
  2754
	ed->RedoL();
sl@0
  2755
	check->SetCheckString(*textLog2);
sl@0
  2756
	testEd->Print(*check);
sl@0
  2757
	CheckEditorLog(*check);
sl@0
  2758
sl@0
  2759
	ed->UndoL();
sl@0
  2760
	check->SetCheckString(*textLog1);
sl@0
  2761
	testEd->Print(*check);
sl@0
  2762
	CheckEditorLog(*check);
sl@0
  2763
sl@0
  2764
	ed->UndoL();
sl@0
  2765
	check->SetCheckString(*textLog0);
sl@0
  2766
	testEd->Print(*check);
sl@0
  2767
	CheckEditorLog(*check);
sl@0
  2768
sl@0
  2769
	ed->UndoL();
sl@0
  2770
	check->SetCheckString(*textLog3);
sl@0
  2771
	testEd->Print(*check);
sl@0
  2772
	CheckEditorLog(*check);
sl@0
  2773
	}
sl@0
  2774
sl@0
  2775
void TestEditorUndo::Test6L()
sl@0
  2776
	{
sl@0
  2777
	// test style manipulation
sl@0
  2778
	style1.iName = _L("author");
sl@0
  2779
	style2.iName = _L("title");
sl@0
  2780
	style2.iNextStyleName = _L("author");
sl@0
  2781
	style1.iCharFormat.iFormat = charI;
sl@0
  2782
	style1.iCharFormat.iMask = charIMask;
sl@0
  2783
	style1.iParFormat.iFormat.CopyL(parT);
sl@0
  2784
	style1.iParFormat.iMask = parTNMask;
sl@0
  2785
	style2.iCharFormat.iFormat = charB;
sl@0
  2786
	style2.iCharFormat.iMask = charBIMask;
sl@0
  2787
	style2.iParFormat.iFormat.CopyL(parN);
sl@0
  2788
	style2.iParFormat.iMask = parNMask;
sl@0
  2789
sl@0
  2790
	ed->StyleSupport()->CreateStyleL(style1);
sl@0
  2791
	testEd->Print(*log);
sl@0
  2792
	styleLog1 = log->GetStore();
sl@0
  2793
	TInt retval = ed->StyleSupport()->SetStyleL(1, 3, _L("author"));
sl@0
  2794
	testEd->Print(*log);
sl@0
  2795
	styleLog2 = log->GetStore();
sl@0
  2796
	if (retval != KErrNone)
sl@0
  2797
		{
sl@0
  2798
        TESTPRINT(_L("EditorUndo : apply style failed"));
sl@0
  2799
        TESTPOINT(0);
sl@0
  2800
		}
sl@0
  2801
	TPtrC testStyleName;
sl@0
  2802
	TInt testStyleRunLength;
sl@0
  2803
	ed->StyleSupport()->GetStyle(1, testStyleName, testStyleRunLength);
sl@0
  2804
	if (testStyleRunLength != 3 || testStyleName != style1.iName)
sl@0
  2805
		{
sl@0
  2806
        TESTPRINT(_L("EditorUndo : apply style failed"));
sl@0
  2807
		TESTPOINT(0);
sl@0
  2808
		}
sl@0
  2809
	ed->InsertTextL(5, _L(","), &style1.iName, 0, 0);
sl@0
  2810
	testEd->Print(*log);
sl@0
  2811
	styleLog3 = log->GetStore();
sl@0
  2812
	ed->StyleSupport()->CreateStyleL(style2);
sl@0
  2813
	testEd->Print(*log);
sl@0
  2814
	styleLog4 = log->GetStore();
sl@0
  2815
	ed->StyleSupport()->SetStyleL(2, 7, _L("title"));
sl@0
  2816
	testEd->Print(*log);
sl@0
  2817
	styleLog5 = log->GetStore();
sl@0
  2818
	ed->StyleSupport()->SetStyleL(10, 4, _L("title"));
sl@0
  2819
	testEd->Print(*log);
sl@0
  2820
	styleLog6 = log->GetStore();
sl@0
  2821
	ed->StyleSupport()->SetStyleL(8, 4, _L("author"));
sl@0
  2822
	testEd->Print(*log);
sl@0
  2823
	styleLog7 = log->GetStore();
sl@0
  2824
	style1.iCharFormat.iFormat = charB;
sl@0
  2825
	style1.iCharFormat.iMask = charBMask;
sl@0
  2826
	ed->StyleSupport()->ChangeStyleL(style1);
sl@0
  2827
	testEd->Print(*log);
sl@0
  2828
	styleLog8 = log->GetStore();
sl@0
  2829
 	ed->StyleSupport()->RenameStyleL(_L("author"), _L("version"));
sl@0
  2830
	style1.iName = _L("version");
sl@0
  2831
	testEd->Print(*log);
sl@0
  2832
	styleLog9 = log->GetStore();
sl@0
  2833
	retval = ed->StyleSupport()->SetStyleL(10, 1, _L("version"));
sl@0
  2834
	testEd->Print(*log);
sl@0
  2835
	styleLog10 = log->GetStore();
sl@0
  2836
	if (retval != KErrNone)
sl@0
  2837
		{
sl@0
  2838
        TESTPRINT(_L("EditorUndo : rename style failed"));
sl@0
  2839
		TESTPOINT(0);
sl@0
  2840
		}
sl@0
  2841
	ed->StyleSupport()->GetStyle(1, testStyleName, testStyleRunLength);
sl@0
  2842
	if (testStyleRunLength != 1 || testStyleName != style1.iName)
sl@0
  2843
		{
sl@0
  2844
        TESTPRINT(_L("EditorUndo : rename or apply style failed"));
sl@0
  2845
		TESTPOINT(0);
sl@0
  2846
		}
sl@0
  2847
	ed->StyleSupport()->RenameStyleL(_L("title"), _L("zip"));
sl@0
  2848
	style2.iName = _L("zip");
sl@0
  2849
	testEd->Print(*log);
sl@0
  2850
	styleLog11 = log->GetStore();
sl@0
  2851
	ed->StyleSupport()->SetStyleL(0, 6, _L("zip"));
sl@0
  2852
	testEd->Print(*log);
sl@0
  2853
	styleLog12 = log->GetStore();
sl@0
  2854
	ed->StyleSupport()->DeleteStyleL(_L("zip"));
sl@0
  2855
	testEd->Print(*log);
sl@0
  2856
	styleLog13 = log->GetStore();
sl@0
  2857
	ed->InsertTextL(0, _L("Well "), &style1.iName, 0, 0);
sl@0
  2858
sl@0
  2859
	ed->UndoL();
sl@0
  2860
	check->SetCheckString(*styleLog13);
sl@0
  2861
	testEd->Print(*check);
sl@0
  2862
	CheckEditorLog(*check);
sl@0
  2863
sl@0
  2864
	ed->UndoL();
sl@0
  2865
	check->SetCheckString(*styleLog12);
sl@0
  2866
	testEd->Print(*check);
sl@0
  2867
	CheckEditorLog(*check);
sl@0
  2868
sl@0
  2869
	ed->UndoL();
sl@0
  2870
	check->SetCheckString(*styleLog11);
sl@0
  2871
	testEd->Print(*check);
sl@0
  2872
	CheckEditorLog(*check);
sl@0
  2873
sl@0
  2874
	ed->UndoL();
sl@0
  2875
	check->SetCheckString(*styleLog10);
sl@0
  2876
	testEd->Print(*check);
sl@0
  2877
	CheckEditorLog(*check);
sl@0
  2878
sl@0
  2879
	ed->UndoL();
sl@0
  2880
	check->SetCheckString(*styleLog9);
sl@0
  2881
	testEd->Print(*check);
sl@0
  2882
	CheckEditorLog(*check);
sl@0
  2883
sl@0
  2884
	ed->UndoL();
sl@0
  2885
	check->SetCheckString(*styleLog8);
sl@0
  2886
	testEd->Print(*check);
sl@0
  2887
	CheckEditorLog(*check);
sl@0
  2888
sl@0
  2889
	ed->UndoL();
sl@0
  2890
	check->SetCheckString(*styleLog7);
sl@0
  2891
	testEd->Print(*check);
sl@0
  2892
	CheckEditorLog(*check);
sl@0
  2893
sl@0
  2894
	ed->UndoL();
sl@0
  2895
	check->SetCheckString(*styleLog6);
sl@0
  2896
	testEd->Print(*check);
sl@0
  2897
	CheckEditorLog(*check);
sl@0
  2898
sl@0
  2899
	ed->UndoL();
sl@0
  2900
	check->SetCheckString(*styleLog5);
sl@0
  2901
	testEd->Print(*check);
sl@0
  2902
	CheckEditorLog(*check);
sl@0
  2903
sl@0
  2904
	ed->UndoL();
sl@0
  2905
	check->SetCheckString(*styleLog4);
sl@0
  2906
	testEd->Print(*check);
sl@0
  2907
	CheckEditorLog(*check);
sl@0
  2908
sl@0
  2909
	ed->UndoL();
sl@0
  2910
	check->SetCheckString(*styleLog3);
sl@0
  2911
	testEd->Print(*check);
sl@0
  2912
	CheckEditorLog(*check);
sl@0
  2913
sl@0
  2914
	ed->UndoL();
sl@0
  2915
	check->SetCheckString(*styleLog2);
sl@0
  2916
	testEd->Print(*check);
sl@0
  2917
	CheckEditorLog(*check);
sl@0
  2918
sl@0
  2919
	ed->UndoL();
sl@0
  2920
	check->SetCheckString(*styleLog1);
sl@0
  2921
	testEd->Print(*check);
sl@0
  2922
	CheckEditorLog(*check);
sl@0
  2923
sl@0
  2924
	ed->UndoL();
sl@0
  2925
	check->SetCheckString(*textLog3);
sl@0
  2926
	testEd->Print(*check);
sl@0
  2927
	CheckEditorLog(*check);
sl@0
  2928
sl@0
  2929
	ed->RedoL();
sl@0
  2930
	check->SetCheckString(*styleLog1);
sl@0
  2931
	testEd->Print(*check);
sl@0
  2932
	CheckEditorLog(*check);
sl@0
  2933
sl@0
  2934
	ed->RedoL();
sl@0
  2935
	check->SetCheckString(*styleLog2);
sl@0
  2936
	testEd->Print(*check);
sl@0
  2937
	CheckEditorLog(*check);
sl@0
  2938
sl@0
  2939
	ed->RedoL();
sl@0
  2940
	check->SetCheckString(*styleLog3);
sl@0
  2941
	testEd->Print(*check);
sl@0
  2942
	CheckEditorLog(*check);
sl@0
  2943
sl@0
  2944
	ed->RedoL();
sl@0
  2945
	check->SetCheckString(*styleLog4);
sl@0
  2946
	testEd->Print(*check);
sl@0
  2947
	CheckEditorLog(*check);
sl@0
  2948
sl@0
  2949
	ed->RedoL();
sl@0
  2950
	check->SetCheckString(*styleLog5);
sl@0
  2951
	testEd->Print(*check);
sl@0
  2952
	CheckEditorLog(*check);
sl@0
  2953
sl@0
  2954
	ed->RedoL();
sl@0
  2955
	check->SetCheckString(*styleLog6);
sl@0
  2956
	testEd->Print(*check);
sl@0
  2957
	CheckEditorLog(*check);
sl@0
  2958
sl@0
  2959
	ed->RedoL();
sl@0
  2960
	check->SetCheckString(*styleLog7);
sl@0
  2961
	testEd->Print(*check);
sl@0
  2962
	CheckEditorLog(*check);
sl@0
  2963
sl@0
  2964
	ed->RedoL();
sl@0
  2965
	check->SetCheckString(*styleLog8);
sl@0
  2966
	testEd->Print(*check);
sl@0
  2967
	CheckEditorLog(*check);
sl@0
  2968
sl@0
  2969
	ed->RedoL();
sl@0
  2970
	check->SetCheckString(*styleLog9);
sl@0
  2971
	testEd->Print(*check);
sl@0
  2972
	CheckEditorLog(*check);
sl@0
  2973
sl@0
  2974
	ed->RedoL();
sl@0
  2975
	check->SetCheckString(*styleLog10);
sl@0
  2976
	testEd->Print(*check);
sl@0
  2977
	CheckEditorLog(*check);
sl@0
  2978
sl@0
  2979
	ed->RedoL();
sl@0
  2980
	check->SetCheckString(*styleLog11);
sl@0
  2981
	testEd->Print(*check);
sl@0
  2982
	CheckEditorLog(*check);
sl@0
  2983
sl@0
  2984
	ed->RedoL();
sl@0
  2985
	check->SetCheckString(*styleLog12);
sl@0
  2986
	testEd->Print(*check);
sl@0
  2987
	CheckEditorLog(*check);
sl@0
  2988
sl@0
  2989
	ed->RedoL();
sl@0
  2990
	check->SetCheckString(*styleLog13);
sl@0
  2991
	testEd->Print(*check);
sl@0
  2992
	CheckEditorLog(*check);
sl@0
  2993
sl@0
  2994
	// probably need some more style tests that test the full range of
sl@0
  2995
	// attributes that a style may have.
sl@0
  2996
	//...
sl@0
  2997
sl@0
  2998
	delete textLog0;
sl@0
  2999
	delete textLog1;
sl@0
  3000
	delete textLog2;
sl@0
  3001
	delete parLog0;
sl@0
  3002
	delete parLog1;
sl@0
  3003
	delete parLog2;
sl@0
  3004
	delete parLog3;
sl@0
  3005
	delete charLog0;
sl@0
  3006
	delete charLog1;
sl@0
  3007
	delete charLog2;
sl@0
  3008
	delete charLog3;
sl@0
  3009
	delete styleLog1;
sl@0
  3010
	delete styleLog2;
sl@0
  3011
	delete styleLog3;
sl@0
  3012
	delete styleLog4;
sl@0
  3013
	delete styleLog5;
sl@0
  3014
	delete styleLog6;
sl@0
  3015
	delete styleLog7;
sl@0
  3016
	delete styleLog8;
sl@0
  3017
	delete styleLog9;
sl@0
  3018
	delete styleLog10;
sl@0
  3019
	delete styleLog11;
sl@0
  3020
	delete styleLog12;
sl@0
  3021
	delete styleLog13;
sl@0
  3022
sl@0
  3023
	delete textLog3;
sl@0
  3024
	}
sl@0
  3025
sl@0
  3026
void TestEditorUndo::Test7L()
sl@0
  3027
	{
sl@0
  3028
	// test picture manipulation
sl@0
  3029
	TPictureHeader pic;
sl@0
  3030
	pic.iPictureType = KUidXzePictureType;
sl@0
  3031
	testEd->Print(*log);
sl@0
  3032
	picLog0 = log->GetStore();
sl@0
  3033
	pic.iPicture = new (ELeave) CUndoTestPicture('A');
sl@0
  3034
	ed->PictureSupport()->InsertPictureL(5, pic);
sl@0
  3035
	testEd->Print(*log);
sl@0
  3036
	picLog1 = log->GetStore();
sl@0
  3037
	pic.iPicture = new (ELeave) CUndoTestPicture('B');
sl@0
  3038
	ed->PictureSupport()->InsertPictureL(8, pic);
sl@0
  3039
	testEd->Print(*log);
sl@0
  3040
	picLog2 = log->GetStore();
sl@0
  3041
	pic.iPicture = new (ELeave) CUndoTestPicture('C');
sl@0
  3042
	ed->PictureSupport()->InsertPictureL(9, pic);
sl@0
  3043
	testEd->Print(*log);
sl@0
  3044
	picLog3 = log->GetStore();
sl@0
  3045
	pic.iPicture = new (ELeave) CUndoTestPicture('D');
sl@0
  3046
	ed->PictureSupport()->InsertPictureL(12, pic);
sl@0
  3047
	ed->StyleSupport()->SetStyleL(6, 2, style1.iName);
sl@0
  3048
	ed->SetCharFormatL(8, 3, charLayer);
sl@0
  3049
	ed->SetParFormatL(7, 7, parLayer);
sl@0
  3050
	testEd->Print(*log);
sl@0
  3051
	picLog4 = log->GetStore();
sl@0
  3052
	ed->DeleteTextL(5, 8);
sl@0
  3053
	testEd->Print(*log);
sl@0
  3054
	picLog5 = log->GetStore();
sl@0
  3055
sl@0
  3056
	ed->UndoL();
sl@0
  3057
	check->SetCheckString(*picLog4);
sl@0
  3058
	testEd->Print(*check);
sl@0
  3059
	CheckEditorLog(*check);
sl@0
  3060
sl@0
  3061
	ed->UndoL();
sl@0
  3062
	ed->UndoL();
sl@0
  3063
	ed->UndoL();
sl@0
  3064
	ed->UndoL();
sl@0
  3065
	check->SetCheckString(*picLog3);
sl@0
  3066
	testEd->Print(*check);
sl@0
  3067
	CheckEditorLog(*check);
sl@0
  3068
sl@0
  3069
	ed->UndoL();
sl@0
  3070
	check->SetCheckString(*picLog2);
sl@0
  3071
	testEd->Print(*check);
sl@0
  3072
	CheckEditorLog(*check);
sl@0
  3073
sl@0
  3074
	ed->UndoL();
sl@0
  3075
	check->SetCheckString(*picLog1);
sl@0
  3076
	testEd->Print(*check);
sl@0
  3077
	CheckEditorLog(*check);
sl@0
  3078
sl@0
  3079
	ed->UndoL();
sl@0
  3080
	check->SetCheckString(*picLog0);
sl@0
  3081
	testEd->Print(*check);
sl@0
  3082
	CheckEditorLog(*check);
sl@0
  3083
sl@0
  3084
	ed->RedoL();
sl@0
  3085
	check->SetCheckString(*picLog1);
sl@0
  3086
	testEd->Print(*check);
sl@0
  3087
	CheckEditorLog(*check);
sl@0
  3088
sl@0
  3089
	ed->RedoL();
sl@0
  3090
	check->SetCheckString(*picLog2);
sl@0
  3091
	testEd->Print(*check);
sl@0
  3092
	CheckEditorLog(*check);
sl@0
  3093
sl@0
  3094
	ed->RedoL();
sl@0
  3095
	check->SetCheckString(*picLog3);
sl@0
  3096
	testEd->Print(*check);
sl@0
  3097
	CheckEditorLog(*check);
sl@0
  3098
sl@0
  3099
	ed->RedoL();
sl@0
  3100
	ed->RedoL();
sl@0
  3101
	ed->RedoL();
sl@0
  3102
	ed->RedoL();
sl@0
  3103
	check->SetCheckString(*picLog4);
sl@0
  3104
	testEd->Print(*check);
sl@0
  3105
	CheckEditorLog(*check);
sl@0
  3106
sl@0
  3107
	ed->RedoL();
sl@0
  3108
	check->SetCheckString(*picLog5);
sl@0
  3109
	testEd->Print(*check);
sl@0
  3110
	CheckEditorLog(*check);
sl@0
  3111
sl@0
  3112
	style1.Close();
sl@0
  3113
	style2.Close();
sl@0
  3114
	parLayer.Close();
sl@0
  3115
	par0.Close();
sl@0
  3116
	parT.Close();
sl@0
  3117
	parN.Close();
sl@0
  3118
	parTN.Close();
sl@0
  3119
	delete picLog0;
sl@0
  3120
	delete picLog1;
sl@0
  3121
	delete picLog2;
sl@0
  3122
	delete picLog3;
sl@0
  3123
	delete picLog4;
sl@0
  3124
	delete picLog5;
sl@0
  3125
	}
sl@0
  3126
sl@0
  3127
void TestEditorUndo::Test8L()
sl@0
  3128
	{
sl@0
  3129
	// test bookmarking
sl@0
  3130
	for (TInt i = 0; i != 7; ++i)
sl@0
  3131
		{
sl@0
  3132
		testEd->Reset();
sl@0
  3133
		ed->ResetUndo();
sl@0
  3134
		if (i == 0)
sl@0
  3135
			manager->SetBookmark();
sl@0
  3136
		testEd->Print(*log);
sl@0
  3137
		bookMarkLog0 = log->GetStore();
sl@0
  3138
		ed->InsertTextL(0, _L("Hallo"), 0, 0, 0);	// hallo
sl@0
  3139
		if (i == 1)
sl@0
  3140
			manager->SetBookmark();
sl@0
  3141
		testEd->Print(*log);
sl@0
  3142
		bookMarkLog1 = log->GetStore();
sl@0
  3143
		ed->DeleteTextL(2, 1);	// halo
sl@0
  3144
		if (i == 2)
sl@0
  3145
			manager->SetBookmark();
sl@0
  3146
		testEd->Print(*log);
sl@0
  3147
		bookMarkLog2 = log->GetStore();
sl@0
  3148
		manager->BeginBatchLC();
sl@0
  3149
		ed->DeleteTextL(3, 1);	// hal
sl@0
  3150
		ed->InsertTextL(3, _L("t, who goes there?"), 0, 0, 0);	// halt, who goes there?
sl@0
  3151
		if (i == 3)
sl@0
  3152
			manager->SetBookmark();		// should not get set
sl@0
  3153
		ed->DeleteTextL(9, 5);		// halt, who there?
sl@0
  3154
		CleanupStack::PopAndDestroy();
sl@0
  3155
		if (i == 4)
sl@0
  3156
			manager->SetBookmark();
sl@0
  3157
		testEd->Print(*log);
sl@0
  3158
		bookMarkLog3 = log->GetStore();
sl@0
  3159
		ed->InsertTextL(0, _L("Oi"), 0, 0, 0);
sl@0
  3160
		if (i == 5)
sl@0
  3161
			manager->SetBookmark();
sl@0
  3162
		testEd->Print(*log);
sl@0
  3163
		bookMarkLog4 = log->GetStore();
sl@0
  3164
		ed->InsertTextL(2, _L("! "), 0, 0, 0);
sl@0
  3165
		testEd->Print(*log);
sl@0
  3166
		bookMarkLog5 = log->GetStore();
sl@0
  3167
		if (i == 6)
sl@0
  3168
			manager->SetBookmark();
sl@0
  3169
sl@0
  3170
		ed->UndoL();
sl@0
  3171
		// coalescence should have happenned unless there is a bookmark
sl@0
  3172
		// in the way.
sl@0
  3173
		if (i == 5)
sl@0
  3174
			{
sl@0
  3175
            TESTPOINT(manager->IsAtBookmark());
sl@0
  3176
			check->SetCheckString(*bookMarkLog4);
sl@0
  3177
			testEd->Print(*check);
sl@0
  3178
			CheckEditorLog(*check);
sl@0
  3179
			ed->UndoL();
sl@0
  3180
			}
sl@0
  3181
		if (i == 4)
sl@0
  3182
		    TESTPOINT(manager->IsAtBookmark());
sl@0
  3183
		else
sl@0
  3184
		    TESTPOINT(!manager->IsAtBookmark());
sl@0
  3185
		check->SetCheckString(*bookMarkLog3);
sl@0
  3186
		testEd->Print(*check);
sl@0
  3187
		CheckEditorLog(*check);
sl@0
  3188
		ed->UndoL();
sl@0
  3189
		if (i == 2)
sl@0
  3190
		    TESTPOINT(manager->IsAtBookmark());
sl@0
  3191
		else
sl@0
  3192
		    TESTPOINT(!manager->IsAtBookmark());
sl@0
  3193
		check->SetCheckString(*bookMarkLog2);
sl@0
  3194
		testEd->Print(*check);
sl@0
  3195
		CheckEditorLog(*check);
sl@0
  3196
		ed->UndoL();
sl@0
  3197
		if (i == 1)
sl@0
  3198
		    TESTPOINT(manager->IsAtBookmark());
sl@0
  3199
		else
sl@0
  3200
		    TESTPOINT(!manager->IsAtBookmark());
sl@0
  3201
		check->SetCheckString(*bookMarkLog1);
sl@0
  3202
		testEd->Print(*check);
sl@0
  3203
		CheckEditorLog(*check);
sl@0
  3204
		ed->UndoL();
sl@0
  3205
		if (i == 0)
sl@0
  3206
		    TESTPOINT(manager->IsAtBookmark());
sl@0
  3207
		else
sl@0
  3208
		    TESTPOINT(!manager->IsAtBookmark());
sl@0
  3209
		check->SetCheckString(*bookMarkLog0);
sl@0
  3210
		testEd->Print(*check);
sl@0
  3211
		CheckEditorLog(*check);
sl@0
  3212
		TESTPOINT(!ed->CanUndo());
sl@0
  3213
		ed->RedoL();
sl@0
  3214
		if (i == 1)
sl@0
  3215
		    TESTPOINT(manager->IsAtBookmark());
sl@0
  3216
		else
sl@0
  3217
		    TESTPOINT(!manager->IsAtBookmark());
sl@0
  3218
		check->SetCheckString(*bookMarkLog1);
sl@0
  3219
		testEd->Print(*check);
sl@0
  3220
		CheckEditorLog(*check);
sl@0
  3221
		ed->RedoL();
sl@0
  3222
		if (i == 2)
sl@0
  3223
		    TESTPOINT(manager->IsAtBookmark());
sl@0
  3224
		else
sl@0
  3225
		    TESTPOINT(!manager->IsAtBookmark());
sl@0
  3226
		check->SetCheckString(*bookMarkLog2);
sl@0
  3227
		testEd->Print(*check);
sl@0
  3228
		CheckEditorLog(*check);
sl@0
  3229
		ed->RedoL();
sl@0
  3230
		if (i == 4)
sl@0
  3231
		    TESTPOINT(manager->IsAtBookmark());
sl@0
  3232
		else
sl@0
  3233
		    TESTPOINT(!manager->IsAtBookmark());
sl@0
  3234
		check->SetCheckString(*bookMarkLog3);
sl@0
  3235
		testEd->Print(*check);
sl@0
  3236
		CheckEditorLog(*check);
sl@0
  3237
		ed->RedoL();
sl@0
  3238
		if (i == 5)
sl@0
  3239
			{
sl@0
  3240
            TESTPOINT(manager->IsAtBookmark());
sl@0
  3241
			check->SetCheckString(*bookMarkLog4);
sl@0
  3242
			testEd->Print(*check);
sl@0
  3243
			CheckEditorLog(*check);
sl@0
  3244
			ed->RedoL();
sl@0
  3245
			}
sl@0
  3246
		TESTPOINT(!ed->CanRedo());
sl@0
  3247
		if (i == 6)
sl@0
  3248
		    TESTPOINT(manager->IsAtBookmark());
sl@0
  3249
		else
sl@0
  3250
		    TESTPOINT(!manager->IsAtBookmark());
sl@0
  3251
sl@0
  3252
		delete bookMarkLog0;
sl@0
  3253
		delete bookMarkLog1;
sl@0
  3254
		delete bookMarkLog2;
sl@0
  3255
		delete bookMarkLog3;
sl@0
  3256
		delete bookMarkLog4;
sl@0
  3257
		delete bookMarkLog5;
sl@0
  3258
		}
sl@0
  3259
sl@0
  3260
	delete ed;
sl@0
  3261
	delete testEd;
sl@0
  3262
	delete log;
sl@0
  3263
	delete check;
sl@0
  3264
	}
sl@0
  3265
sl@0
  3266
void TestEditorUndoL()
sl@0
  3267
	{
sl@0
  3268
	__UHEAP_MARK;
sl@0
  3269
sl@0
  3270
	TestEditorUndo t;
sl@0
  3271
	t.Test1L();
sl@0
  3272
	t.Test2L();
sl@0
  3273
	t.Test3L();
sl@0
  3274
	t.Test4L();
sl@0
  3275
	t.Test5L();
sl@0
  3276
	t.Test6L();
sl@0
  3277
	t.Test7L();
sl@0
  3278
	t.Test8L();
sl@0
  3279
sl@0
  3280
	__UHEAP_MARKENDC(0);
sl@0
  3281
	}
sl@0
  3282
// integration of command manager with multiple editors
sl@0
  3283
void TestMultipleEditorsL()
sl@0
  3284
	{
sl@0
  3285
	__UHEAP_MARK;
sl@0
  3286
sl@0
  3287
	CCheckingLogger* check = new(ELeave) CCheckingLogger;
sl@0
  3288
	CStoringLogger* log = new(ELeave) CStoringLogger;
sl@0
  3289
sl@0
  3290
	CTestEditor* testEd0 = CTestEditor::NewL();
sl@0
  3291
	CTestEditor* testEd1 = CTestEditor::NewL();
sl@0
  3292
	CTestEditor* testEd2 = CTestEditor::NewL();
sl@0
  3293
	CTestEditor* testEd3 = CTestEditor::NewL();
sl@0
  3294
	CCommandManager* manager = CCommandManager::NewL();
sl@0
  3295
sl@0
  3296
	CEditorPlainTextWithUndo* ed0 =
sl@0
  3297
		CEditorPlainTextWithUndo::NewL(*testEd0, manager);
sl@0
  3298
	CEditorWithUndo* ed1 = CEditorWithUndo::NewL(*testEd1, manager);
sl@0
  3299
	CEditorPlainTextWithUndo* ed2 =
sl@0
  3300
		CEditorPlainTextWithUndo::NewL(*testEd2, manager);
sl@0
  3301
	CEditorWithUndo* ed3 = CEditorWithUndo::NewL(*testEd3, manager);
sl@0
  3302
	manager->Release();
sl@0
  3303
sl@0
  3304
	// Testing the API's of CEditorPlainTextWithUndo
sl@0
  3305
	TTmCharFormatMask charBIMask;
sl@0
  3306
	charBIMask.iFlags = TTmCharFormatMask::EItalic | TTmCharFormatMask::EBold;
sl@0
  3307
	TOpenFontFaceAttribBase attrib;
sl@0
  3308
	TTmCharFormat charB;
sl@0
  3309
	attrib.SetBold(ETrue);
sl@0
  3310
	charB.iFontSpec.SetAttrib(attrib);
sl@0
  3311
	TTmCharFormatLayer charLayer;
sl@0
  3312
	charLayer.iFormat = charB;
sl@0
  3313
	charLayer.iMask = charBIMask;
sl@0
  3314
	TTmParFormatMask parTMask;
sl@0
  3315
	parTMask.iFlags = TTmParFormatMask::EKeepTogether;
sl@0
  3316
	RTmParFormat parT;
sl@0
  3317
	parT.iFlags = RTmParFormat::EKeepTogether;
sl@0
  3318
	RTmParFormatLayer parLayer;
sl@0
  3319
	parLayer.iMask = parTMask;
sl@0
  3320
sl@0
  3321
	//Setting the base, character and paragraph format and then inserting the text
sl@0
  3322
	ed0->SetBaseFormatL(charB,parT);
sl@0
  3323
	ed0->SetCharFormatL(0, 1, charLayer);
sl@0
  3324
	ed0->SetParFormatL(0, 1, parLayer);
sl@0
  3325
sl@0
  3326
	// The main thing to check is that no commands coalesce that have
sl@0
  3327
	// different targets which would if their targets matched. The
sl@0
  3328
	// commands that can coalesce are Delete Text, Delete Plain Text,
sl@0
  3329
	// Insert Text, Insert Plain Text, Delete Character Format, Delete
sl@0
  3330
	// Paragraph Format.
sl@0
  3331
	ed0->InsertTextL(0, _L("ab"), 0, 0, 0);
sl@0
  3332
	testEd0->Print(*log);
sl@0
  3333
	HBufC* log00 = log->GetStore();
sl@0
  3334
	ed2->InsertTextL(0, _L("cd"), 0, 0, 0);
sl@0
  3335
	testEd2->Print(*log);
sl@0
  3336
	HBufC* log20 = log->GetStore();
sl@0
  3337
	ed1->InsertTextL(0, _L("ef"), 0, 0, 0);
sl@0
  3338
	testEd1->Print(*log);
sl@0
  3339
	HBufC* log10 = log->GetStore();
sl@0
  3340
	ed3->InsertTextL(0, _L("gh"), 0, 0, 0);
sl@0
  3341
	testEd3->Print(*log);
sl@0
  3342
	HBufC* log30 = log->GetStore();
sl@0
  3343
sl@0
  3344
	manager->UndoL();
sl@0
  3345
	check->SetCheckString(*log10);
sl@0
  3346
	testEd1->Print(*check);
sl@0
  3347
	CheckEditorLog(*check);
sl@0
  3348
sl@0
  3349
	manager->UndoL();
sl@0
  3350
	check->SetCheckString(*log20);
sl@0
  3351
	testEd2->Print(*check);
sl@0
  3352
	CheckEditorLog(*check);
sl@0
  3353
sl@0
  3354
	manager->UndoL();
sl@0
  3355
	check->SetCheckString(*log00);
sl@0
  3356
	testEd0->Print(*check);
sl@0
  3357
	CheckEditorLog(*check);
sl@0
  3358
sl@0
  3359
	manager->UndoL();
sl@0
  3360
	TestCannotUndo(*manager);
sl@0
  3361
sl@0
  3362
	manager->RedoL();
sl@0
  3363
	check->SetCheckString(*log00);
sl@0
  3364
	testEd0->Print(*check);
sl@0
  3365
	CheckEditorLog(*check);
sl@0
  3366
sl@0
  3367
	manager->RedoL();
sl@0
  3368
	check->SetCheckString(*log20);
sl@0
  3369
	testEd2->Print(*check);
sl@0
  3370
	CheckEditorLog(*check);
sl@0
  3371
sl@0
  3372
	manager->RedoL();
sl@0
  3373
	check->SetCheckString(*log10);
sl@0
  3374
	testEd1->Print(*check);
sl@0
  3375
	CheckEditorLog(*check);
sl@0
  3376
sl@0
  3377
	manager->RedoL();
sl@0
  3378
	check->SetCheckString(*log30);
sl@0
  3379
	testEd3->Print(*check);
sl@0
  3380
	CheckEditorLog(*check);
sl@0
  3381
	TestCannotRedo(*manager);
sl@0
  3382
sl@0
  3383
	ed0->DeleteTextL(1, 1);
sl@0
  3384
	testEd0->Print(*log);
sl@0
  3385
	HBufC* log01 = log->GetStore();
sl@0
  3386
	ed2->DeleteTextL(0, 1);
sl@0
  3387
	testEd2->Print(*log);
sl@0
  3388
	HBufC* log21 = log->GetStore();
sl@0
  3389
	ed3->DeleteTextL(0, 1);
sl@0
  3390
	testEd3->Print(*log);
sl@0
  3391
	HBufC* log31 = log->GetStore();
sl@0
  3392
	ed1->DeleteTextL(0, 1);
sl@0
  3393
	testEd1->Print(*log);
sl@0
  3394
	HBufC* log11 = log->GetStore();
sl@0
  3395
sl@0
  3396
	manager->UndoL();
sl@0
  3397
	check->SetCheckString(*log31);
sl@0
  3398
	testEd3->Print(*check);
sl@0
  3399
	CheckEditorLog(*check);
sl@0
  3400
sl@0
  3401
	manager->UndoL();
sl@0
  3402
	check->SetCheckString(*log21);
sl@0
  3403
	testEd2->Print(*check);
sl@0
  3404
	CheckEditorLog(*check);
sl@0
  3405
sl@0
  3406
	manager->UndoL();
sl@0
  3407
	check->SetCheckString(*log01);
sl@0
  3408
	testEd0->Print(*check);
sl@0
  3409
	CheckEditorLog(*check);
sl@0
  3410
sl@0
  3411
	manager->UndoL();
sl@0
  3412
	check->SetCheckString(*log30);
sl@0
  3413
	testEd3->Print(*check);
sl@0
  3414
	CheckEditorLog(*check);
sl@0
  3415
sl@0
  3416
	manager->RedoL();
sl@0
  3417
	check->SetCheckString(*log01);
sl@0
  3418
	testEd0->Print(*check);
sl@0
  3419
	CheckEditorLog(*check);
sl@0
  3420
sl@0
  3421
	manager->RedoL();
sl@0
  3422
	check->SetCheckString(*log21);
sl@0
  3423
	testEd2->Print(*check);
sl@0
  3424
	CheckEditorLog(*check);
sl@0
  3425
sl@0
  3426
	manager->RedoL();
sl@0
  3427
	check->SetCheckString(*log31);
sl@0
  3428
	testEd3->Print(*check);
sl@0
  3429
	CheckEditorLog(*check);
sl@0
  3430
sl@0
  3431
	manager->RedoL();
sl@0
  3432
	check->SetCheckString(*log11);
sl@0
  3433
	testEd1->Print(*check);
sl@0
  3434
	CheckEditorLog(*check);
sl@0
  3435
	TestCannotRedo(*manager);
sl@0
  3436
sl@0
  3437
	parLayer.iFormat.CopyL(parT);
sl@0
  3438
sl@0
  3439
	//Getting the base format to check if it is set accordingly
sl@0
  3440
	TTmCharFormat charB1;
sl@0
  3441
	RTmParFormat parT1;
sl@0
  3442
	ed0->GetBaseFormatL(charB1,parT1);
sl@0
  3443
	TESTPOINT(charB1==charB);
sl@0
  3444
	TESTPOINT(parT1==parT);
sl@0
  3445
sl@0
  3446
	//Getting the character format
sl@0
  3447
	TTmCharFormatLayer charLayer1;
sl@0
  3448
	MUnifiedEditor::TFormatLevel level=MUnifiedEditor::EEffective;
sl@0
  3449
	TInt runLen=10;
sl@0
  3450
	ed0->GetCharFormat(0,level,charLayer1,runLen);
sl@0
  3451
sl@0
  3452
	//Getting the paragraph format
sl@0
  3453
	RTmParFormatLayer parLayer1;
sl@0
  3454
	ed0->GetParFormatL(0,level,parLayer1,runLen);
sl@0
  3455
sl@0
  3456
	//Getting the text
sl@0
  3457
	TPtrC text;
sl@0
  3458
	ed0->GetText(0,text);
sl@0
  3459
	TESTPOINT(text==_L("a"));
sl@0
  3460
sl@0
  3461
	//Deleting the formating
sl@0
  3462
	ed0->DeleteCharFormatL(0,1);
sl@0
  3463
	ed0->DeleteParFormatL(0,1);
sl@0
  3464
sl@0
  3465
	// To test CEditorCommandSetBaseFormat class
sl@0
  3466
	// SetBaseFormatL calls CEditorCommandSetBaseFormatProto::CreateInverseL() which in turn calls CEditorCommandSetBaseFormat::NewL().
sl@0
  3467
	ed1->SetBaseFormatL(charB,parT);
sl@0
  3468
	ed1->SetCharFormatL(0, 1, charLayer);
sl@0
  3469
sl@0
  3470
	testEd1->Print(*log);
sl@0
  3471
	HBufC* log12 = log->GetStore();
sl@0
  3472
	ed3->SetCharFormatL(0, 1 ,charLayer);
sl@0
  3473
	testEd3->Print(*log);
sl@0
  3474
	HBufC* log32 = log->GetStore();
sl@0
  3475
	ed3->SetParFormatL(0, 1, parLayer);
sl@0
  3476
	testEd3->Print(*log);
sl@0
  3477
	HBufC* log33 = log->GetStore();
sl@0
  3478
	ed1->SetParFormatL(0, 1, parLayer);
sl@0
  3479
	testEd1->Print(*log);
sl@0
  3480
	HBufC* log13 = log->GetStore();
sl@0
  3481
sl@0
  3482
	manager->UndoL();
sl@0
  3483
	check->SetCheckString(*log33);
sl@0
  3484
	testEd3->Print(*check);
sl@0
  3485
	CheckEditorLog(*check);
sl@0
  3486
sl@0
  3487
	manager->UndoL();
sl@0
  3488
	check->SetCheckString(*log32);
sl@0
  3489
	testEd3->Print(*check);
sl@0
  3490
	CheckEditorLog(*check);
sl@0
  3491
sl@0
  3492
	manager->UndoL();
sl@0
  3493
	check->SetCheckString(*log12);
sl@0
  3494
	testEd1->Print(*check);
sl@0
  3495
	CheckEditorLog(*check);
sl@0
  3496
sl@0
  3497
	manager->RedoL();
sl@0
  3498
	check->SetCheckString(*log32);
sl@0
  3499
	testEd3->Print(*check);
sl@0
  3500
	CheckEditorLog(*check);
sl@0
  3501
sl@0
  3502
	manager->RedoL();
sl@0
  3503
	check->SetCheckString(*log33);
sl@0
  3504
	testEd3->Print(*check);
sl@0
  3505
	CheckEditorLog(*check);
sl@0
  3506
sl@0
  3507
	manager->RedoL();
sl@0
  3508
	check->SetCheckString(*log13);
sl@0
  3509
	testEd1->Print(*check);
sl@0
  3510
	CheckEditorLog(*check);
sl@0
  3511
sl@0
  3512
	parLayer.Close();
sl@0
  3513
	parT.Close();
sl@0
  3514
	delete log00;
sl@0
  3515
	delete log10;
sl@0
  3516
	delete log20;
sl@0
  3517
	delete log30;
sl@0
  3518
	delete log01;
sl@0
  3519
	delete log11;
sl@0
  3520
	delete log21;
sl@0
  3521
	delete log31;
sl@0
  3522
	delete log12;
sl@0
  3523
	delete log13;
sl@0
  3524
	delete log32;
sl@0
  3525
	delete log33;
sl@0
  3526
	manager->ResetUndo();
sl@0
  3527
	delete ed0;
sl@0
  3528
	delete ed1;
sl@0
  3529
	delete ed2;
sl@0
  3530
	delete ed3;
sl@0
  3531
	delete testEd0;
sl@0
  3532
	delete testEd1;
sl@0
  3533
	delete testEd2;
sl@0
  3534
	delete testEd3;
sl@0
  3535
	delete log;
sl@0
  3536
	delete check;
sl@0
  3537
sl@0
  3538
	__UHEAP_MARKENDC(0);
sl@0
  3539
	}
sl@0
  3540
sl@0
  3541
//
sl@0
  3542
//
sl@0
  3543
//  Main
sl@0
  3544
//
sl@0
  3545
//
sl@0
  3546
sl@0
  3547
TVerdict CTUndoStep::doTestStepL()
sl@0
  3548
	{
sl@0
  3549
    SetTestStepResult(EPass);
sl@0
  3550
    TestStep = this;
sl@0
  3551
    TESTPRINT(_L("TUndo - Undo system"));
sl@0
  3552
    
sl@0
  3553
    __UHEAP_MARK;
sl@0
  3554
    TESTPRINT(_L("@SYMTestCaseID:SYSLIB-FORM-LEGACY-UNDO-0001 Undo System Tests: "));
sl@0
  3555
	
sl@0
  3556
	// test of general undo system components
sl@0
  3557
	TestCCommandStackL();
sl@0
  3558
	TestCBatchCommandL();
sl@0
  3559
	TestCCommandHistoryL();
sl@0
  3560
	TestCCommandManagerL();
sl@0
  3561
sl@0
  3562
	// test of editor undo components
sl@0
  3563
	TestEditorUndoL();
sl@0
  3564
sl@0
  3565
	// test that command manager and multiple editors integrate correctly
sl@0
  3566
	TestMultipleEditorsL();
sl@0
  3567
sl@0
  3568
	__UHEAP_MARKENDC(0);
sl@0
  3569
	
sl@0
  3570
	return TestStepResult();
sl@0
  3571
	}
sl@0
  3572