os/textandloc/textrendering/textformatting/undo/EditorPlainTextCommands.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2000-2009 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
*
sl@0
    16
*/
sl@0
    17
sl@0
    18
sl@0
    19
#include "EditorPlainTextCommands.h"
sl@0
    20
#include "AssertFileAndLine.h"
sl@0
    21
#include <txtetext.h>
sl@0
    22
#include <txtclipboard.h>
sl@0
    23
sl@0
    24
#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
sl@0
    25
#include "txtfmlyr_internal.h"
sl@0
    26
#endif
sl@0
    27
using namespace UndoSystem;
sl@0
    28
sl@0
    29
/////////////////////////
sl@0
    30
//					   //
sl@0
    31
//	Internal Commands  //
sl@0
    32
//					   //
sl@0
    33
/////////////////////////
sl@0
    34
sl@0
    35
TUid CEditorCommand::FamilyUid() const { return TUid::Uid(KUndoDllUid); }
sl@0
    36
sl@0
    37
CEditorCommandInsertTextAndFormat*
sl@0
    38
	CEditorCommand::CastToCEditorCommandInsertTextAndFormat() { return 0; }
sl@0
    39
CEditorCommandDeleteText*
sl@0
    40
	CEditorCommand::CastToCEditorCommandDeleteText() { return 0; }
sl@0
    41
CEditorCommandInsertPlainText*
sl@0
    42
	CEditorCommand::CastToCEditorCommandInsertPlainText() { return 0; }
sl@0
    43
CEditorCommandDeletePlainText*
sl@0
    44
	CEditorCommand::CastToCEditorCommandDeletePlainText() { return 0; }
sl@0
    45
CEditorCommandDeleteCharFormat*
sl@0
    46
	CEditorCommand::CastToCEditorCommandDeleteCharFormat() { return 0; }
sl@0
    47
CEditorCommandDeleteParFormat*
sl@0
    48
	CEditorCommand::CastToCEditorCommandDeleteParFormat() { return 0; }
sl@0
    49
sl@0
    50
/////////////////////////////////
sl@0
    51
//							   //
sl@0
    52
//	Command coalesce function  //
sl@0
    53
//							   //
sl@0
    54
/////////////////////////////////
sl@0
    55
sl@0
    56
CCommand* UndoSystem::CoalesceL(CCommand* aLeft, CCommand* aRight)
sl@0
    57
	{
sl@0
    58
	if (!aRight)
sl@0
    59
		return aLeft;
sl@0
    60
	if (!aLeft)
sl@0
    61
		return aRight;
sl@0
    62
sl@0
    63
	CleanupStack::PushL(aRight);
sl@0
    64
	CBatchCommand* batch = aLeft->Batch();
sl@0
    65
	if (batch)
sl@0
    66
		{
sl@0
    67
		batch->PrepareToPushL(aRight);
sl@0
    68
		batch->Push(aRight);
sl@0
    69
		CleanupStack::Pop(aRight);
sl@0
    70
		return batch;
sl@0
    71
		}
sl@0
    72
	ASSERT(aLeft->Single());
sl@0
    73
	batch = CBatchCommand::NewL();
sl@0
    74
	CleanupStack::PushL(batch);
sl@0
    75
	batch->PrepareToPushL(aLeft);
sl@0
    76
	batch->Push(aLeft);
sl@0
    77
	batch->PrepareToPushL(aRight);
sl@0
    78
	batch->Push(aRight);
sl@0
    79
	CleanupStack::Pop(batch);
sl@0
    80
	CleanupStack::Pop(aRight);
sl@0
    81
	return batch;
sl@0
    82
	}
sl@0
    83
sl@0
    84
/**
sl@0
    85
 * Command for deleting plain text.
sl@0
    86
 *
sl@0
    87
 * @internalComponent
sl@0
    88
 * @since App-frameworks6.1
sl@0
    89
 */
sl@0
    90
NONSHARABLE_CLASS(CEditorCommandDeletePlainText) : public CEditorCommand
sl@0
    91
	{
sl@0
    92
	TEditorDeletePlainTextImpl iImpl;
sl@0
    93
sl@0
    94
	CEditorCommandDeletePlainText*
sl@0
    95
		CastToCEditorCommandDeletePlainText() { return this; }
sl@0
    96
sl@0
    97
	CEditorCommandDeletePlainText(MUnifiedEditor& aTarget,
sl@0
    98
		TInt aPos, TInt aLength)
sl@0
    99
		: iImpl(aTarget, aPos, aLength) {}
sl@0
   100
public:
sl@0
   101
	static CEditorCommandDeletePlainText* NewL(TInt aPos,
sl@0
   102
		TInt aLength, MUnifiedEditor& aTarget)
sl@0
   103
		{
sl@0
   104
		return new(ELeave) CEditorCommandDeletePlainText(aTarget, aPos, aLength);
sl@0
   105
		}
sl@0
   106
sl@0
   107
	CCommand* CreateInverseL() const;
sl@0
   108
sl@0
   109
	TInt ExecuteL() const
sl@0
   110
		{
sl@0
   111
		return iImpl.ExecuteL();
sl@0
   112
		}
sl@0
   113
sl@0
   114
	// This command can be coalesced with others of the same type
sl@0
   115
	TBool CanAdd(TInt aPos, TInt aLength, MUnifiedEditor& aTarget) const
sl@0
   116
		{
sl@0
   117
		return iImpl.CanAdd(aPos, aLength, aTarget);
sl@0
   118
		}
sl@0
   119
sl@0
   120
	void Add(TInt aLength)
sl@0
   121
		{
sl@0
   122
		iImpl.Add(aLength);
sl@0
   123
		}
sl@0
   124
	};
sl@0
   125
sl@0
   126
/**
sl@0
   127
 * Command for inserting text in a specified style and format.
sl@0
   128
 *
sl@0
   129
 * @internalComponent
sl@0
   130
 * @since App-frameworks6.1
sl@0
   131
 */
sl@0
   132
NONSHARABLE_CLASS(CEditorCommandInsertPlainText) : public CEditorCommand
sl@0
   133
	{
sl@0
   134
	TEditorInsertPlainTextImpl iImpl;
sl@0
   135
sl@0
   136
	CEditorCommandInsertPlainText*
sl@0
   137
		CastToCEditorCommandInsertPlainText() { return this; }
sl@0
   138
	CEditorCommandInsertPlainText(MUnifiedEditor& aTarget, TInt aPos, const TDesC& aText)
sl@0
   139
		: iImpl(aTarget, aPos, aText) {}
sl@0
   140
public:
sl@0
   141
	static CEditorCommandInsertPlainText* NewL(TInt aPos, const TDesC& aText,
sl@0
   142
		MUnifiedEditor& aTarget)
sl@0
   143
		{
sl@0
   144
		return new(ELeave) CEditorCommandInsertPlainText(aTarget, aPos, aText);
sl@0
   145
		}
sl@0
   146
	/**
sl@0
   147
	 * Gets the length specified, but this might entail the use of more than
sl@0
   148
	 * one CCommand object.
sl@0
   149
	 */
sl@0
   150
	static CCommand* NewBatchL(TInt aPos, TInt aLength, MUnifiedEditor& aTarget);
sl@0
   151
sl@0
   152
	CCommand* CreateInverseL() const;
sl@0
   153
sl@0
   154
	TInt ExecuteL() const
sl@0
   155
		{
sl@0
   156
		return iImpl.ExecuteL();
sl@0
   157
		}
sl@0
   158
sl@0
   159
	TBool CanAdd(TInt aPos, const TDesC& aText, MUnifiedEditor& aTarget) const
sl@0
   160
		{
sl@0
   161
		return iImpl.CanAdd(aPos, aText, aTarget);
sl@0
   162
		}
sl@0
   163
sl@0
   164
	void Add(TInt aPos, const TDesC& aText)
sl@0
   165
		{
sl@0
   166
		iImpl.Add(aPos, aText);
sl@0
   167
		}
sl@0
   168
	};
sl@0
   169
sl@0
   170
CCommand* CEditorCommandInsertPlainText::NewBatchL(TInt aPos,
sl@0
   171
	TInt aLength, MUnifiedEditor& aTarget)
sl@0
   172
	{
sl@0
   173
	CCommand* command = 0;
sl@0
   174
	TInt end = aPos + aLength;
sl@0
   175
	while (aLength)
sl@0
   176
		{
sl@0
   177
		TPtrC textSegment;
sl@0
   178
		aTarget.GetText(end - aLength, textSegment);
sl@0
   179
		TInt segLength = textSegment.Length();
sl@0
   180
		if (aLength < segLength)
sl@0
   181
			segLength = aLength;
sl@0
   182
		if (KMaxCharsInSingleCommand < segLength)
sl@0
   183
			segLength = KMaxCharsInSingleCommand;
sl@0
   184
		CleanupStack::PushL(command);
sl@0
   185
		// coverity[double_free]
sl@0
   186
		command = CoalesceL(command, CEditorCommandInsertPlainText::NewL(aPos,
sl@0
   187
			textSegment.Left(segLength), aTarget));
sl@0
   188
		CleanupStack::Pop();
sl@0
   189
		aLength -= segLength;
sl@0
   190
		}
sl@0
   191
	return command;
sl@0
   192
	}
sl@0
   193
sl@0
   194
CCommand* CEditorCommandInsertPlainText::CreateInverseL() const
sl@0
   195
	{
sl@0
   196
	return CEditorCommandDeletePlainText::NewL(iImpl.Pos(), iImpl.Text().Length(),
sl@0
   197
		iImpl.Target());
sl@0
   198
	}
sl@0
   199
sl@0
   200
sl@0
   201
CCommand* CEditorCommandDeletePlainText::CreateInverseL() const
sl@0
   202
	{
sl@0
   203
	return CEditorCommandInsertPlainText::NewBatchL(iImpl.Pos(), iImpl.Length(),
sl@0
   204
		iImpl.Target());
sl@0
   205
	}
sl@0
   206
sl@0
   207
//////////////////////////////////////////
sl@0
   208
//										//
sl@0
   209
//	CEditorCommandInsertPlainTextProto  //
sl@0
   210
//										//
sl@0
   211
//////////////////////////////////////////
sl@0
   212
sl@0
   213
void CEditorCommandInsertPlainTextProto::Set(TInt aPos, const TDesC& aText)
sl@0
   214
	{
sl@0
   215
	iPos = aPos;
sl@0
   216
	iText = &aText;
sl@0
   217
	}
sl@0
   218
sl@0
   219
UndoSystem::CCommand* CEditorCommandInsertPlainTextProto::CreateInverseL() const
sl@0
   220
	{
sl@0
   221
	return CEditorCommandDeletePlainText::NewL(iPos, iText->Length(), iTarget);
sl@0
   222
	}
sl@0
   223
sl@0
   224
TInt CEditorCommandInsertPlainTextProto::ExecuteL() const
sl@0
   225
	{
sl@0
   226
	iTarget.InsertTextL(iPos, *iText);
sl@0
   227
	return KErrNone;
sl@0
   228
	}
sl@0
   229
sl@0
   230
TBool CEditorCommandInsertPlainTextProto::PrepareToAddInverseToLastL(
sl@0
   231
	CSingleCommand& aLastCommand) const
sl@0
   232
	{
sl@0
   233
	if (aLastCommand.FamilyUid() != TUid::Uid(KUndoDllUid))
sl@0
   234
		return EFalse;
sl@0
   235
	CEditorCommandDeletePlainText* last =
sl@0
   236
		static_cast<CEditorCommand&>(aLastCommand).CastToCEditorCommandDeletePlainText();
sl@0
   237
	if (!last)
sl@0
   238
		return EFalse;
sl@0
   239
	return last->CanAdd(iPos, iText->Length(), iTarget);
sl@0
   240
	}
sl@0
   241
sl@0
   242
void CEditorCommandInsertPlainTextProto::AddInverseToLast(CSingleCommand& aLastCommand) const
sl@0
   243
	{
sl@0
   244
	ASSERT(aLastCommand.FamilyUid() == TUid::Uid(KUndoDllUid));
sl@0
   245
	CEditorCommandDeletePlainText* last =
sl@0
   246
		static_cast<CEditorCommand&>(aLastCommand).CastToCEditorCommandDeletePlainText();
sl@0
   247
	ASSERT(last);
sl@0
   248
	last->Add(iText->Length());
sl@0
   249
	}
sl@0
   250
sl@0
   251
//////////////////////////////////////////
sl@0
   252
//										//
sl@0
   253
//	CEditorCommandDeletePlainTextProto  //
sl@0
   254
//										//
sl@0
   255
//////////////////////////////////////////
sl@0
   256
sl@0
   257
void CEditorCommandDeletePlainTextProto::Set(TInt aPos, TInt aLength)
sl@0
   258
	{
sl@0
   259
	iPos = aPos;
sl@0
   260
	iLength = aLength;
sl@0
   261
	}
sl@0
   262
sl@0
   263
CCommand* CEditorCommandDeletePlainTextProto::CreateInverseL() const
sl@0
   264
	{
sl@0
   265
	return CEditorCommandInsertPlainText::NewBatchL(iPos, iLength, iTarget);
sl@0
   266
	}
sl@0
   267
sl@0
   268
TInt CEditorCommandDeletePlainTextProto::ExecuteL() const
sl@0
   269
	{
sl@0
   270
	iTarget.DeleteTextL(iPos, iLength);
sl@0
   271
	return KErrNone;
sl@0
   272
	}
sl@0
   273
sl@0
   274
TBool CEditorCommandDeletePlainTextProto::PrepareToAddInverseToLastL(
sl@0
   275
	CSingleCommand& aLastCommand) const
sl@0
   276
	{
sl@0
   277
	if (iDeletedText.MaxLength() < iLength)
sl@0
   278
		return EFalse;
sl@0
   279
	if (aLastCommand.FamilyUid() != TUid::Uid(KUndoDllUid))
sl@0
   280
		return EFalse;
sl@0
   281
	CEditorCommandInsertPlainText* last =
sl@0
   282
		static_cast<CEditorCommand&>(aLastCommand).CastToCEditorCommandInsertPlainText();
sl@0
   283
	if (!last)
sl@0
   284
		return EFalse;
sl@0
   285
	TBool result = EFalse;
sl@0
   286
	TPtrC textSegment;
sl@0
   287
	iTarget.GetText(iPos, textSegment);
sl@0
   288
	if (iLength <= textSegment.Length())
sl@0
   289
		{
sl@0
   290
		result = last->CanAdd(iPos, textSegment.Left(iLength), iTarget);
sl@0
   291
		if (result)
sl@0
   292
			iDeletedText = textSegment.Left(iLength);
sl@0
   293
		}
sl@0
   294
	return result;
sl@0
   295
	}
sl@0
   296
sl@0
   297
void CEditorCommandDeletePlainTextProto::AddInverseToLast(CSingleCommand& aLastCommand) const
sl@0
   298
	{
sl@0
   299
	ASSERT(aLastCommand.FamilyUid() == TUid::Uid(KUndoDllUid));
sl@0
   300
	CEditorCommandInsertPlainText* last =
sl@0
   301
		static_cast<CEditorCommand&>(aLastCommand).CastToCEditorCommandInsertPlainText();
sl@0
   302
	ASSERT(last);
sl@0
   303
	last->Add(iPos, iDeletedText);
sl@0
   304
	}
sl@0
   305
sl@0
   306
//////////////////////////////////
sl@0
   307
//								//
sl@0
   308
//	TEditorInsertPlainTextImpl  //
sl@0
   309
//								//
sl@0
   310
//////////////////////////////////
sl@0
   311
sl@0
   312
TInt TEditorInsertPlainTextImpl::ExecuteL(const TDesC* aStyle,
sl@0
   313
	const TTmCharFormatLayer* aChar,
sl@0
   314
	const RTmParFormatLayer* aPar) const
sl@0
   315
	{
sl@0
   316
	iTarget.InsertTextL(iPos, iText, aStyle, aChar, aPar);
sl@0
   317
	return KErrNone;
sl@0
   318
	}
sl@0
   319
sl@0
   320
TInt TEditorInsertPlainTextImpl::ExecuteL() const
sl@0
   321
	{
sl@0
   322
	return ExecuteL(0, 0, 0);
sl@0
   323
	}
sl@0
   324
sl@0
   325
TInt TEditorInsertPlainTextImpl::CanAdd(TInt aPos, const TDesC& aText, MUnifiedEditor& aTarget) const
sl@0
   326
	{
sl@0
   327
	if (&aTarget != &iTarget)
sl@0
   328
		return EFalse;
sl@0
   329
	TInt length = aText.Length();
sl@0
   330
	if (KMaxCharsInSingleCommand <= iText.Length() + length)
sl@0
   331
		return EFalse;
sl@0
   332
	return aPos <= iPos && iPos <= aPos + length;
sl@0
   333
	}
sl@0
   334
sl@0
   335
void TEditorInsertPlainTextImpl::Add(TInt aPos, const TDesC& aText)
sl@0
   336
	{
sl@0
   337
	TPtrC left = aText.Left(iPos - aPos);
sl@0
   338
	TPtrC right = aText.Mid(iPos - aPos);
sl@0
   339
	iText.Insert(0, left);
sl@0
   340
	iText.Append(right);
sl@0
   341
	iPos = aPos;
sl@0
   342
	}
sl@0
   343
sl@0
   344
//////////////////////////////////
sl@0
   345
//								//
sl@0
   346
//	TEditorDeletePlainTextImpl  //
sl@0
   347
//								//
sl@0
   348
//////////////////////////////////
sl@0
   349
sl@0
   350
TInt TEditorDeletePlainTextImpl::ExecuteL() const
sl@0
   351
	{
sl@0
   352
	iTarget.DeleteTextL(iPos, iLength);
sl@0
   353
	return KErrNone;
sl@0
   354
	}
sl@0
   355
sl@0
   356
TBool TEditorDeletePlainTextImpl::CanAdd(TInt aPos, TInt aLength, MUnifiedEditor& aTarget) const
sl@0
   357
	{
sl@0
   358
	return &aTarget == &iTarget && iPos <= aPos && aPos <= iLength + iPos
sl@0
   359
		&& aLength + iLength <= KMaxCharsInSingleCommand;
sl@0
   360
	}
sl@0
   361
sl@0
   362
void TEditorDeletePlainTextImpl::Add(TInt aLength)
sl@0
   363
	{
sl@0
   364
	iLength += aLength;
sl@0
   365
	}
sl@0
   366
sl@0
   367
/////////////////////////////
sl@0
   368
//						   //
sl@0
   369
//  TEditorPasteProtoImpl  //
sl@0
   370
//						   //
sl@0
   371
/////////////////////////////
sl@0
   372
sl@0
   373
void TEditorPasteProtoImpl::Set(const CStreamStore& aStore,
sl@0
   374
								const CStreamDictionary& aDict,
sl@0
   375
								TInt aPos)
sl@0
   376
	{
sl@0
   377
	iStore = &aStore;
sl@0
   378
	iStreamDictionary = &aDict;
sl@0
   379
	iPos = aPos;
sl@0
   380
	}
sl@0
   381
sl@0
   382
void TEditorPasteProtoImpl::OpenPlainTextStreamLC(RStoreReadStream& aStream) const
sl@0
   383
	{
sl@0
   384
	TStreamId plainTextStream = iStreamDictionary->At(KClipboardUidTypePlainText);
sl@0
   385
	if (plainTextStream == KNullStreamId)
sl@0
   386
		User::Leave(KErrNotSupported);		// don't know how to undo this
sl@0
   387
	aStream.OpenLC(*iStore, plainTextStream);
sl@0
   388
	}
sl@0
   389
sl@0
   390
TInt TEditorPasteProtoImpl::LengthL() const
sl@0
   391
	{
sl@0
   392
	RStoreReadStream stream;
sl@0
   393
	OpenPlainTextStreamLC(stream);
sl@0
   394
	TInt length = stream.ReadInt32L();
sl@0
   395
	CleanupStack::PopAndDestroy();
sl@0
   396
	return length;
sl@0
   397
	}
sl@0
   398
sl@0
   399
TInt TEditorPasteProtoImpl::ExecuteL() const
sl@0
   400
	{
sl@0
   401
	MUnifiedEditor::MClipboardSupport* ci = iTarget.ClipboardSupport();
sl@0
   402
	ASSERT(ci);
sl@0
   403
	ci->PasteFromStoreL(*iStore, *iStreamDictionary, iPos);
sl@0
   404
	return KErrNone;
sl@0
   405
	}
sl@0
   406
sl@0
   407
/////////////////////////////////////////
sl@0
   408
//									   //
sl@0
   409
//	CEditorCommandPastePlainTextProto  //
sl@0
   410
//									   //
sl@0
   411
/////////////////////////////////////////
sl@0
   412
sl@0
   413
void CEditorCommandPastePlainTextProto::Set(const CStreamStore& aStore,
sl@0
   414
	const CStreamDictionary& aStreamDictionary,
sl@0
   415
	TInt aPos)
sl@0
   416
	{
sl@0
   417
	iImpl.Set(aStore, aStreamDictionary, aPos);
sl@0
   418
	}
sl@0
   419
sl@0
   420
UndoSystem::CCommand* CEditorCommandPastePlainTextProto::CreateInverseL() const
sl@0
   421
	{
sl@0
   422
	return CEditorCommandDeletePlainText::NewL(iImpl.Pos(), iImpl.LengthL(), iImpl.Target());
sl@0
   423
	}
sl@0
   424
sl@0
   425
TInt CEditorCommandPastePlainTextProto::ExecuteL() const
sl@0
   426
	{
sl@0
   427
	return iImpl.ExecuteL();
sl@0
   428
	}