os/persistentdata/loggingservices/eventlogger/LogCli/src/LogViewWindow.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200 (2014-06-10)
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include "LogViewWindow.h"
sl@0
    17
sl@0
    18
// User includes
sl@0
    19
#include "logclientop.h"
sl@0
    20
#include "logclipanic.h"
sl@0
    21
#include "LogViewWindowChangeObserver.h"
sl@0
    22
sl@0
    23
// Constants
sl@0
    24
const TInt KWindowSlideSize = 2;
sl@0
    25
sl@0
    26
sl@0
    27
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
    28
// -----> CLogViewWindow (source)
sl@0
    29
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
    30
sl@0
    31
CLogViewWindow::CLogViewWindow(RLogSession& aSession, TLogViewId aViewId, TInt aWindowSize, MLogViewChangeObserver* aCascadeObserver, TInt aPriority)
sl@0
    32
:	CLogActive(aPriority), iSession(aSession), iViewId(aViewId), iWindowSize(aWindowSize), iCascadeObserver(aCascadeObserver), iEvents(aWindowSize)
sl@0
    33
	{
sl@0
    34
	Reset();
sl@0
    35
	}
sl@0
    36
sl@0
    37
CLogViewWindow::~CLogViewWindow()
sl@0
    38
	{
sl@0
    39
	Cancel();
sl@0
    40
	//
sl@0
    41
	delete iWindowChangeObserver;
sl@0
    42
	delete iWindowPreparer;
sl@0
    43
	delete iWindowFetcher;
sl@0
    44
	delete iWindowLockObserver;
sl@0
    45
	//
sl@0
    46
	iEvents.ResetAndDestroy();
sl@0
    47
	iEvents.Close();
sl@0
    48
	}
sl@0
    49
sl@0
    50
void CLogViewWindow::ConstructL(CLogPackage& aPackage)
sl@0
    51
	{
sl@0
    52
	iWindowPreparer = new(ELeave) CLogViewSetupClientOp(iSession, aPackage, CActive::EPriorityStandard);
sl@0
    53
	//
sl@0
    54
	iWindowFetcher = new(ELeave) CLogViewWindowFetcher(iSession, iViewId, *this, CActive::EPriorityIdle + 1);
sl@0
    55
	iWindowFetcher->ConstructL();
sl@0
    56
	//
sl@0
    57
	iWindowLockObserver = new(ELeave) CLogViewWindowLockObserver(iSession, iViewId, *this, CActive::EPriorityHigh);
sl@0
    58
	iWindowLockObserver->ConstructL();
sl@0
    59
	//
sl@0
    60
	iWindowChangeObserver = new(ELeave) CLogViewWindowChangeObserver(*this);
sl@0
    61
	}
sl@0
    62
sl@0
    63
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
    64
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
    65
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
    66
sl@0
    67
TInt CLogViewWindow::Setup(const CLogFilterList& aFilterList, TInt aParam, TLogFilterConstructionType aFilterConstructionType)
sl@0
    68
	{
sl@0
    69
	Reset();
sl@0
    70
	iViewRecordCount = iWindowPreparer->Start(iViewId, aFilterList, aParam, aFilterConstructionType);
sl@0
    71
	return iViewRecordCount;
sl@0
    72
	}
sl@0
    73
sl@0
    74
TBool CLogViewWindow::NavigateL(TLogNavigation aNavigate, TRequestStatus& aStatus)
sl@0
    75
	{
sl@0
    76
	// Check why we're already active
sl@0
    77
	switch(iState)
sl@0
    78
		{
sl@0
    79
	case EStateIdle:
sl@0
    80
	case EStateLocked:
sl@0
    81
		__ASSERT_DEBUG(!IsActive(), Panic(ELogWindowStateMachineNavigationError1));
sl@0
    82
		break;
sl@0
    83
	case EStateFetchingWindow:
sl@0
    84
	case EStateProcessingWindow:
sl@0
    85
	case EStateNavigateWithinWindow:
sl@0
    86
		// We're trying to catch up with some changes.. use the requested
sl@0
    87
		// window as the new window, but refetch everything.
sl@0
    88
		__ASSERT_DEBUG(IsActive(), Panic(ELogWindowStateMachineNavigationError2));
sl@0
    89
		SilentCancel();
sl@0
    90
		iWindow = iWindowFetcher->RequestedWindow();
sl@0
    91
		break;
sl@0
    92
	default:
sl@0
    93
		break;
sl@0
    94
		}
sl@0
    95
sl@0
    96
	// Perform boundary checks
sl@0
    97
	TInt cursorPos = CalculateCursorPosition(aNavigate);
sl@0
    98
	if	(cursorPos < 0 || cursorPos >= iViewRecordCount)
sl@0
    99
		{
sl@0
   100
		// Can't navigate to the specified position
sl@0
   101
		return EFalse;
sl@0
   102
		}
sl@0
   103
sl@0
   104
	// Check whether the cursor position falls within the view window 
sl@0
   105
	if	(iWindow.iValid && iWindow.Contains(cursorPos))
sl@0
   106
		{
sl@0
   107
		// Can return event from window
sl@0
   108
		CompleteRequest(cursorPos);
sl@0
   109
		ChangeState(EStateNavigateWithinWindow);
sl@0
   110
		}
sl@0
   111
	else
sl@0
   112
		{
sl@0
   113
		// Have to fetch a new window. Work it out...
sl@0
   114
		TLogWindowAndCursor window;
sl@0
   115
		CalculateWindowForCursorPosition(cursorPos, window);
sl@0
   116
		window.iCursorPosition = cursorPos;
sl@0
   117
		iWindowFetcher->PrepareToFetchWindowL(window);
sl@0
   118
		//		
sl@0
   119
		CompleteRequest(KErrNone);
sl@0
   120
		ChangeState(EStateFetchingWindow);
sl@0
   121
		}
sl@0
   122
sl@0
   123
	// Okay to (try to) navigate here
sl@0
   124
	Queue(aStatus);
sl@0
   125
	return ETrue;
sl@0
   126
	}
sl@0
   127
sl@0
   128
void CLogViewWindow::RemoveFromWindowIfPresentL(TLogId aId)
sl@0
   129
	{
sl@0
   130
	TInt index = FindEvent(aId);
sl@0
   131
	if	(index >= 0)
sl@0
   132
		{
sl@0
   133
		// Ignore next window removal event (since we're proactively removing
sl@0
   134
		// the event from the client side without server prompting).
sl@0
   135
		iWindowChangeObserver->IgnoreNextEventL(aId, CLogViewWindowChangeObserver::ELogEventTypeDelete);
sl@0
   136
sl@0
   137
		// Delete item	
sl@0
   138
		RemoveEvent(index);
sl@0
   139
sl@0
   140
		// Map onto full view position
sl@0
   141
		index += iWindow.iLower;
sl@0
   142
sl@0
   143
		// Update window - when removing the last event from the window, we must
sl@0
   144
		// ensure we mark the window as invalid.
sl@0
   145
		if	(iWindow.AdjustForItemDeletion(index) == TLogWindowAndCursor::EWindowAffected && iEvents.Count() == 0)
sl@0
   146
			{
sl@0
   147
			iWindow.Reset();
sl@0
   148
			}
sl@0
   149
		}
sl@0
   150
	//
sl@0
   151
	--iViewRecordCount;
sl@0
   152
	}
sl@0
   153
sl@0
   154
MLogViewChangeObserverInternal& CLogViewWindow::ChangeObserver()
sl@0
   155
	{
sl@0
   156
	__ASSERT_ALWAYS(iWindowChangeObserver, Panic(ELogWindowNoChangeObserver));
sl@0
   157
	return *iWindowChangeObserver;
sl@0
   158
	}
sl@0
   159
sl@0
   160
const CLogEvent& CLogViewWindow::CurrsorEvent() const
sl@0
   161
	{
sl@0
   162
	// Map the cursor position to fall within the window
sl@0
   163
	const TInt mappedIndex = iWindow.WindowIndexFromCursorPosition();
sl@0
   164
	const TInt count = iEvents.Count();
sl@0
   165
	__ASSERT_ALWAYS(mappedIndex >= 0 && mappedIndex < count, Panic(ELogWindowCursorCalculationOutOfBounds));
sl@0
   166
	return *iEvents[mappedIndex];
sl@0
   167
	}
sl@0
   168
sl@0
   169
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   170
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   171
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   172
sl@0
   173
void CLogViewWindow::HandleWindowLockStatusChangeL(TLogViewLockStatus aStatus)
sl@0
   174
	{
sl@0
   175
	switch(aStatus)
sl@0
   176
		{
sl@0
   177
	case ELogViewWindowLocked:
sl@0
   178
		SilentCancel();
sl@0
   179
		iState = EStateLocked;
sl@0
   180
		break;
sl@0
   181
	case ELogViewWindowOpen:
sl@0
   182
		if (iState == EStateLocked)
sl@0
   183
			iState = EStateIdle; 
sl@0
   184
		break;
sl@0
   185
	default:
sl@0
   186
		break;
sl@0
   187
		}
sl@0
   188
sl@0
   189
	// The window is never valid after a change in lock status
sl@0
   190
	iWindow.iValid = EFalse;
sl@0
   191
	}
sl@0
   192
sl@0
   193
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   194
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   195
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   196
sl@0
   197
void CLogViewWindow::HandleFetchedWindowItemL(TInt /*aItemIndex*/, CLogEvent* aEvent)
sl@0
   198
	{
sl@0
   199
	// IMPROVEMENT: could use aItemIndex as the insertion point?
sl@0
   200
	User::LeaveIfError(iEvents.Append(aEvent));
sl@0
   201
	}
sl@0
   202
sl@0
   203
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   204
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   205
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   206
sl@0
   207
void CLogViewWindow::HandleLogViewChangeEventAddedL(TLogId aId, TInt aViewIndex, TInt aChangeIndex, TInt aTotalChangeCount)
sl@0
   208
	{
sl@0
   209
	///////////////////////////////////////
sl@0
   210
	// USE CASE 1:
sl@0
   211
	///////////////////////////////////////
sl@0
   212
	// Cursor position:  *
sl@0
   213
	// View Index:       0 1 2 3 4 5 6
sl@0
   214
	// View Contents:    A B C D E F G
sl@0
   215
	//
sl@0
   216
	// Then, item X is added => 
sl@0
   217
	// 
sl@0
   218
	// Cursor position:    *
sl@0
   219
	// View Index:       0 1 2 3 4 5 6 7
sl@0
   220
	// View Contents:    X A B C D E F G
sl@0
   221
	// 
sl@0
   222
	///////////////////////////////////////
sl@0
   223
	// USE CASE 2:
sl@0
   224
	///////////////////////////////////////
sl@0
   225
	// Cursor position:              *
sl@0
   226
	// View Index:       0 1 2 3 4 5 6
sl@0
   227
	// View Contents:    A B C D E F G
sl@0
   228
	//
sl@0
   229
	// Then, item X is added => 
sl@0
   230
	// 
sl@0
   231
	// Cursor position:                *
sl@0
   232
	// View Index:       0 1 2 3 4 5 6 7
sl@0
   233
	// View Contents:    X A B C D E F G
sl@0
   234
	// 
sl@0
   235
	///////////////////////////////////////
sl@0
   236
	// USE CASE 3:
sl@0
   237
	///////////////////////////////////////
sl@0
   238
	// Cursor position:    *          
sl@0
   239
	// View Index:       0 1 2 3 4 5 6
sl@0
   240
	// View Contents:    A B C D E F G
sl@0
   241
	//
sl@0
   242
	// Then, item X is added => 
sl@0
   243
	// 
sl@0
   244
	// Cursor position:      *          
sl@0
   245
	// View Index:       0 1 2 3 4 5 6 7
sl@0
   246
	// View Contents:    X A B C D E F G
sl@0
   247
	// 
sl@0
   248
	///////////////////////////////////////
sl@0
   249
	// USE CASE 4:
sl@0
   250
	///////////////////////////////////////
sl@0
   251
	// Cursor position:    *          
sl@0
   252
	// View Index:       0 1 2 3 4 5 6
sl@0
   253
	// View Contents:    A B C D E F G
sl@0
   254
	//
sl@0
   255
	// Then, change item Z so that it now appears in the view
sl@0
   256
	// 
sl@0
   257
	// Cursor position:    *          
sl@0
   258
	// View Index:       0 1 2 3 4 5 6 7
sl@0
   259
	// View Contents:    A B C Z D E F G
sl@0
   260
	// 
sl@0
   261
	///////////////////////////////////////
sl@0
   262
	// USE CASE 5:
sl@0
   263
	///////////////////////////////////////
sl@0
   264
	// Cursor position:        *      
sl@0
   265
	// View Index:       0 1 2 3 4 5 6
sl@0
   266
	// View Contents:    A B C D E F G
sl@0
   267
	//
sl@0
   268
	// Then, change item Z so that it now appears in the view
sl@0
   269
	// 
sl@0
   270
	// Cursor position:          *   
sl@0
   271
	// View Index:       0 1 2 3 4 5 6 7
sl@0
   272
	// View Contents:    A B C Z D E F G
sl@0
   273
	// 
sl@0
   274
	///////////////////////////////////////
sl@0
   275
	//RDebug::Print(_L("CLogViewWindow::HandleLogViewChangeEventAddedL()   - aId: %3d, aViewIndex: %3d, aChangeIndex: %3d, aTotalChangeCount: %d, cursorPos: %3d, window: (%3d, %3d), viewCount: %3d, iState: %d"), aId, aViewIndex, aChangeIndex, aTotalChangeCount, iWindow.iCursorPosition, iWindow.iLower, iWindow.iUpper, iViewRecordCount, iState);
sl@0
   276
sl@0
   277
	// Must compare against the current window (if this object is idle) or against
sl@0
   278
	// the window fetcher's window if it is in the process of making a fetch
sl@0
   279
	TLogWindowAndCursor currentWindow;
sl@0
   280
	switch(iState)
sl@0
   281
		{
sl@0
   282
	case EStateFetchingWindow:
sl@0
   283
	case EStateProcessingWindow:
sl@0
   284
		currentWindow = iWindowFetcher->RequestedWindow();
sl@0
   285
		break;
sl@0
   286
	case EStateNavigateWithinWindow:
sl@0
   287
	case EStateIdle:
sl@0
   288
	case EStateLocked:
sl@0
   289
		currentWindow = iWindow;
sl@0
   290
		break;
sl@0
   291
		}
sl@0
   292
sl@0
   293
	// If the addition took place after the window, then we do nothing (except update the
sl@0
   294
	// total view record count)
sl@0
   295
	if	(aViewIndex <= currentWindow.iUpper)
sl@0
   296
		{
sl@0
   297
		// If the addition took place before our window, or at the very start, then we simply need to adjust 
sl@0
   298
		// the window & cursor position. If the window fetcher was active then this will affect the window
sl@0
   299
		// being fetched - in this case, we MUST refetch the whole window.
sl@0
   300
		if	(iState == EStateIdle && aViewIndex <= currentWindow.iLower)
sl@0
   301
			{
sl@0
   302
			iWindow.AdjustForItemAddition(aViewIndex);
sl@0
   303
			}
sl@0
   304
		else
sl@0
   305
			{
sl@0
   306
			// If the addition took place within the window, then we have to refetch the window
sl@0
   307
			TBool refetch = ETrue;
sl@0
   308
			TLogWindowAndCursor newWindow;
sl@0
   309
			//
sl@0
   310
			switch(iState)
sl@0
   311
				{
sl@0
   312
			case EStateIdle:
sl@0
   313
				newWindow = iWindow;
sl@0
   314
				break;
sl@0
   315
			case EStateNavigateWithinWindow:
sl@0
   316
				// Since we complete our own request status with the new cursor position, 
sl@0
   317
				// we can use that here as the desired cursor position after the fetch
sl@0
   318
				newWindow = iWindow;
sl@0
   319
				newWindow.iCursorPosition = iStatus.Int();
sl@0
   320
				break;
sl@0
   321
			case EStateFetchingWindow:
sl@0
   322
			case EStateProcessingWindow:
sl@0
   323
				newWindow = iWindowFetcher->RequestedWindow();
sl@0
   324
				break;
sl@0
   325
			case EStateLocked:
sl@0
   326
				// Don't need to do anything. When the view is unlocked, we refetch anyway
sl@0
   327
				refetch = EFalse;
sl@0
   328
				break;
sl@0
   329
			default:
sl@0
   330
				break;
sl@0
   331
				}
sl@0
   332
			//
sl@0
   333
			if	(refetch)
sl@0
   334
				{
sl@0
   335
				newWindow.AdjustForItemAddition(aViewIndex);
sl@0
   336
				RefetchL(newWindow, newWindow.iCursorPosition);
sl@0
   337
				}
sl@0
   338
			}
sl@0
   339
		}
sl@0
   340
sl@0
   341
	// Increase the total view size
sl@0
   342
	++iViewRecordCount;
sl@0
   343
sl@0
   344
	if	(iCascadeObserver)
sl@0
   345
		iCascadeObserver->HandleLogViewChangeEventAddedL(aId, aViewIndex, aChangeIndex, aTotalChangeCount);
sl@0
   346
	}
sl@0
   347
sl@0
   348
void CLogViewWindow::HandleLogViewChangeEventChangedL(TLogId aId, TInt aViewIndex, TInt aChangeIndex, TInt aTotalChangeCount)
sl@0
   349
	{
sl@0
   350
	//RDebug::Print(_L("CLogViewWindow::HandleLogViewChangeEventChangedL() - aId: %3d, aViewIndex: %3d, aChangeIndex: %3d, aTotalChangeCount: %d, cursorPos: %3d, window: (%3d, %3d), viewCount: %3d, iState: %d"), aId, aViewIndex, aChangeIndex, aTotalChangeCount, iWindow.iCursorPosition, iWindow.iLower, iWindow.iUpper, iViewRecordCount, iState);
sl@0
   351
sl@0
   352
	// Must compare against the current window (if this object is idle) or against
sl@0
   353
	// the window fetcher's window if it is in the process of making a fetch
sl@0
   354
	TLogWindowAndCursor currentWindow;
sl@0
   355
	switch(iState)
sl@0
   356
		{
sl@0
   357
	case EStateFetchingWindow:
sl@0
   358
	case EStateProcessingWindow:
sl@0
   359
		currentWindow = iWindowFetcher->RequestedWindow();
sl@0
   360
		break;
sl@0
   361
	case EStateNavigateWithinWindow:
sl@0
   362
	case EStateIdle:
sl@0
   363
	case EStateLocked:
sl@0
   364
		currentWindow = iWindow;
sl@0
   365
		break;
sl@0
   366
	default:
sl@0
   367
		break;
sl@0
   368
		}
sl@0
   369
sl@0
   370
	// If the event that changed was within the view, then we have to refetch it
sl@0
   371
	if	(currentWindow.Contains(aViewIndex))
sl@0
   372
		{
sl@0
   373
		switch(iState)
sl@0
   374
			{
sl@0
   375
		case EStateIdle:
sl@0
   376
			RefetchL(iWindow, iWindow.iCursorPosition);
sl@0
   377
			break;
sl@0
   378
		case EStateNavigateWithinWindow:
sl@0
   379
			// Since we complete our own request status with the new cursor position, 
sl@0
   380
			// we can use that here as the desired cursor position after the fetch
sl@0
   381
			RefetchL(iWindow, iStatus.Int());
sl@0
   382
			break;
sl@0
   383
		case EStateFetchingWindow:
sl@0
   384
		case EStateProcessingWindow:
sl@0
   385
			RefetchL(iWindowFetcher->RequestedWindow(), iWindowFetcher->RequestedWindow().iCursorPosition);
sl@0
   386
			break;
sl@0
   387
		case EStateLocked:
sl@0
   388
			// Don't need to do anything. When the view is unlocked, we refetch anyway
sl@0
   389
			break;
sl@0
   390
		default:
sl@0
   391
			break;
sl@0
   392
			}
sl@0
   393
		}
sl@0
   394
sl@0
   395
	if	(iCascadeObserver)
sl@0
   396
		iCascadeObserver->HandleLogViewChangeEventChangedL(aId, aViewIndex, aChangeIndex, aTotalChangeCount);
sl@0
   397
	}
sl@0
   398
sl@0
   399
void CLogViewWindow::HandleLogViewChangeEventDeletedL(TLogId aId, TInt aViewIndex, TInt aChangeIndex, TInt aTotalChangeCount)
sl@0
   400
	{
sl@0
   401
	///////////////////////////////////////
sl@0
   402
	// USE CASE 1:
sl@0
   403
	///////////////////////////////////////
sl@0
   404
	// Cursor position:            *
sl@0
   405
	// View Index:       0 1 2 3 4 5 6
sl@0
   406
	// View Contents:    A B C D E F G
sl@0
   407
	//
sl@0
   408
	// Then, item 5 is deleted => 
sl@0
   409
	// 
sl@0
   410
	// Cursor position:            *
sl@0
   411
	// View Index:       0 1 2 3 4 5
sl@0
   412
	// View Contents:    A B C D E G
sl@0
   413
	// 
sl@0
   414
	///////////////////////////////////////
sl@0
   415
	// USE CASE 2:
sl@0
   416
	///////////////////////////////////////
sl@0
   417
	// Cursor position:            *
sl@0
   418
	// View Index:       0 1 2 3 4 5 6
sl@0
   419
	// View Contents:    A B C D E F G
sl@0
   420
	//
sl@0
   421
	// Then, item 4 is deleted => 
sl@0
   422
	// 
sl@0
   423
	// Cursor position:          *
sl@0
   424
	// View Index:       0 1 2 3 4 5
sl@0
   425
	// View Contents:    A B C D F G
sl@0
   426
	// 
sl@0
   427
	///////////////////////////////////////
sl@0
   428
	// USE CASE 3:
sl@0
   429
	///////////////////////////////////////
sl@0
   430
	// Cursor position:              *
sl@0
   431
	// View Index:       0 1 2 3 4 5 6
sl@0
   432
	// View Contents:    A B C D E F G
sl@0
   433
	//
sl@0
   434
	// Then, item 6 is deleted => 
sl@0
   435
	// 
sl@0
   436
	// Cursor position:            *
sl@0
   437
	// View Index:       0 1 2 3 4 5
sl@0
   438
	// View Contents:    A B C D E F
sl@0
   439
	// 
sl@0
   440
	///////////////////////////////////////
sl@0
   441
	// USE CASE 4:
sl@0
   442
	///////////////////////////////////////
sl@0
   443
	// Cursor position:  *            
sl@0
   444
	// View Index:       0 1 2 3 4 5 6
sl@0
   445
	// View Contents:    A B C D E F G
sl@0
   446
	//
sl@0
   447
	// Then, item 6 is deleted => 
sl@0
   448
	// 
sl@0
   449
	// Cursor position:  *
sl@0
   450
	// View Index:       0 1 2 3 4 5
sl@0
   451
	// View Contents:    B C D E F G
sl@0
   452
	// 
sl@0
   453
	///////////////////////////////////////
sl@0
   454
	//RDebug::Print(_L("CLogViewWindow::HandleLogViewChangeEventDeletedL() - aId: %3d, aViewIndex: %3d, aChangeIndex: %3d, aTotalChangeCount: %d, cursorPos: %3d, window: (%3d, %3d), viewCount: %3d, iState: %d"), aId, aViewIndex, aChangeIndex, aTotalChangeCount, iWindow.iCursorPosition, iWindow.iLower, iWindow.iUpper, iViewRecordCount, iState);
sl@0
   455
sl@0
   456
	// Must compare against the current window (if this object is idle) or against
sl@0
   457
	// the window fetcher's window if it is in the process of making a fetch
sl@0
   458
	TLogWindowAndCursor currentWindow;
sl@0
   459
	switch(iState)
sl@0
   460
		{
sl@0
   461
	case EStateFetchingWindow:
sl@0
   462
	case EStateProcessingWindow:
sl@0
   463
		currentWindow = iWindowFetcher->RequestedWindow();
sl@0
   464
		break;
sl@0
   465
	case EStateNavigateWithinWindow:
sl@0
   466
	case EStateIdle:
sl@0
   467
	case EStateLocked:
sl@0
   468
		currentWindow = iWindow;
sl@0
   469
		break;
sl@0
   470
	default:
sl@0
   471
		break;
sl@0
   472
		}
sl@0
   473
sl@0
   474
	// Does the change alter our current window in any way?
sl@0
   475
	if	(aViewIndex <= currentWindow.iUpper)
sl@0
   476
		{
sl@0
   477
		TBool refetch = ETrue;
sl@0
   478
		TLogWindowAndCursor newWindow;
sl@0
   479
		//
sl@0
   480
		switch(iState)
sl@0
   481
			{
sl@0
   482
		case EStateIdle:
sl@0
   483
			FindAndRemoveEvent(aId);
sl@0
   484
sl@0
   485
			// When removing the last event from the window, we must ensure we mark
sl@0
   486
			// the window as invalid.
sl@0
   487
			if	(iWindow.AdjustForItemDeletion(aViewIndex) == TLogWindowAndCursor::EWindowAffected && iEvents.Count() == 0)
sl@0
   488
				{
sl@0
   489
				iWindow.Reset();
sl@0
   490
				}
sl@0
   491
sl@0
   492
			refetch = EFalse;
sl@0
   493
			break;
sl@0
   494
		case EStateNavigateWithinWindow:
sl@0
   495
			newWindow = iWindow;
sl@0
   496
			newWindow.iCursorPosition = iStatus.Int();
sl@0
   497
			break;
sl@0
   498
		case EStateFetchingWindow:
sl@0
   499
		case EStateProcessingWindow:
sl@0
   500
			newWindow = iWindowFetcher->RequestedWindow();
sl@0
   501
			break;
sl@0
   502
		case EStateLocked:
sl@0
   503
			// Don't need to do anything. When the view is unlocked, we refetch anyway
sl@0
   504
			refetch = EFalse;
sl@0
   505
			break;
sl@0
   506
		default:
sl@0
   507
			break;
sl@0
   508
			}
sl@0
   509
		//
sl@0
   510
		if	(refetch)
sl@0
   511
			{
sl@0
   512
			newWindow.AdjustForItemDeletion(aViewIndex);
sl@0
   513
			RefetchL(newWindow, newWindow.iCursorPosition);
sl@0
   514
			}
sl@0
   515
		}
sl@0
   516
sl@0
   517
	// Reduce the total view size
sl@0
   518
	--iViewRecordCount;
sl@0
   519
sl@0
   520
	if	(iCascadeObserver)
sl@0
   521
		iCascadeObserver->HandleLogViewChangeEventDeletedL(aId, aViewIndex, aChangeIndex, aTotalChangeCount);
sl@0
   522
	}
sl@0
   523
sl@0
   524
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   525
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   526
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   527
sl@0
   528
void CLogViewWindow::HandleLogViewChangeEventLogClearedL()
sl@0
   529
	{
sl@0
   530
	Cancel();
sl@0
   531
	Reset();
sl@0
   532
sl@0
   533
	// This event type is not cascaded to the client of the log engine
sl@0
   534
	}
sl@0
   535
sl@0
   536
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   537
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   538
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   539
sl@0
   540
void CLogViewWindow::DoRunL()
sl@0
   541
	{
sl@0
   542
	switch(iState)
sl@0
   543
		{
sl@0
   544
	case EStateFetchingWindow:
sl@0
   545
		StateHandleWindowFetchStarting();
sl@0
   546
		break;
sl@0
   547
	case EStateProcessingWindow:
sl@0
   548
		StateHandleWindowFetchedL();
sl@0
   549
		break;
sl@0
   550
	case EStateNavigateWithinWindow:
sl@0
   551
		StateHandleNavigation();
sl@0
   552
		break;
sl@0
   553
	case EStateIdle:
sl@0
   554
	case EStateLocked:
sl@0
   555
	default:
sl@0
   556
		break;
sl@0
   557
		}
sl@0
   558
	}
sl@0
   559
sl@0
   560
void CLogViewWindow::DoCancel()
sl@0
   561
	{
sl@0
   562
	if(iState == EStateProcessingWindow)
sl@0
   563
		{
sl@0
   564
		iWindowFetcher->Cancel();
sl@0
   565
		}
sl@0
   566
	CLogActive::DoCancel();
sl@0
   567
	}
sl@0
   568
sl@0
   569
void CLogViewWindow::DoComplete(TInt& aComplete)
sl@0
   570
	{
sl@0
   571
	switch(iState)
sl@0
   572
		{
sl@0
   573
	default:
sl@0
   574
	case EStateIdle:
sl@0
   575
		break;
sl@0
   576
	case EStateNavigateWithinWindow:
sl@0
   577
		if	(aComplete < KErrNone)
sl@0
   578
			{
sl@0
   579
			// Reset to known state
sl@0
   580
			iState = EStateIdle;
sl@0
   581
			}
sl@0
   582
		break;
sl@0
   583
	case EStateFetchingWindow:
sl@0
   584
	case EStateProcessingWindow:
sl@0
   585
		if	(aComplete < KErrNone)
sl@0
   586
			{
sl@0
   587
			// Reset to known state
sl@0
   588
			iState = EStateIdle;
sl@0
   589
			iWindow = iWindowFetcher->RequestedWindow();
sl@0
   590
			}
sl@0
   591
		break;
sl@0
   592
	case EStateLocked:
sl@0
   593
		aComplete = KErrAccessDenied;
sl@0
   594
		break;
sl@0
   595
		}
sl@0
   596
	}
sl@0
   597
sl@0
   598
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   599
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   600
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   601
sl@0
   602
void CLogViewWindow::StateHandleWindowFetchStarting()
sl@0
   603
	{
sl@0
   604
	iEvents.ResetAndDestroy();
sl@0
   605
	iWindowFetcher->Start(iStatus);
sl@0
   606
	ChangeState(EStateProcessingWindow);
sl@0
   607
	SetActive();
sl@0
   608
	}
sl@0
   609
sl@0
   610
void CLogViewWindow::StateHandleWindowFetchedL()
sl@0
   611
	{
sl@0
   612
	const TInt count = iEvents.Count();
sl@0
   613
	const TInt expected = iWindowFetcher->RequestedWindow().Range();
sl@0
   614
	if	(expected != count)
sl@0
   615
		User::Leave(KErrGeneral);
sl@0
   616
	//	
sl@0
   617
	iWindow = iWindowFetcher->RequestedWindow();
sl@0
   618
	CompleteRequest(iWindow.iCursorPosition);
sl@0
   619
	ChangeState(EStateNavigateWithinWindow);
sl@0
   620
	}
sl@0
   621
sl@0
   622
void CLogViewWindow::StateHandleNavigation()
sl@0
   623
	{
sl@0
   624
	const TInt cursorPos = iStatus.Int();
sl@0
   625
	__ASSERT_ALWAYS(iWindow.Contains(cursorPos), Panic(ELogWindowNavigationOutsideWindow));
sl@0
   626
	iWindow.iCursorPosition = cursorPos;
sl@0
   627
	ChangeState(EStateIdle);
sl@0
   628
	}
sl@0
   629
sl@0
   630
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   631
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   632
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   633
sl@0
   634
void CLogViewWindow::CompleteRequest(TInt aCompletionCode)
sl@0
   635
	{
sl@0
   636
	if	(!IsActive() || (IsActive() && iStatus == KRequestPending))
sl@0
   637
		{
sl@0
   638
		TRequestStatus* status = &iStatus;
sl@0
   639
		User::RequestComplete(status, aCompletionCode);
sl@0
   640
		if	(!IsActive())
sl@0
   641
			SetActive();
sl@0
   642
		}
sl@0
   643
	}
sl@0
   644
sl@0
   645
void CLogViewWindow::CalculateWindowForCursorPosition(TInt aCursorPosition, TLogWindow& aWindow) const
sl@0
   646
	{
sl@0
   647
	aWindow.iLower = Max(0, aCursorPosition - KWindowSlideSize - 1);
sl@0
   648
	aWindow.iUpper = Min(iViewRecordCount - 1, aWindow.iLower + iWindowSize - 1);
sl@0
   649
	}
sl@0
   650
sl@0
   651
void CLogViewWindow::Reset()
sl@0
   652
	{
sl@0
   653
	Cancel();
sl@0
   654
	//
sl@0
   655
	iViewRecordCount = 0;
sl@0
   656
	iWindow.Reset();
sl@0
   657
	iEvents.ResetAndDestroy();
sl@0
   658
	iState = EStateIdle;
sl@0
   659
	}
sl@0
   660
sl@0
   661
void CLogViewWindow::SilentCancel()
sl@0
   662
	{
sl@0
   663
	iWindowFetcher->SilentCancel();
sl@0
   664
	}
sl@0
   665
sl@0
   666
void CLogViewWindow::RefetchL(const TLogWindow& aWindow, TInt aCursor)
sl@0
   667
	{
sl@0
   668
	SilentCancel();
sl@0
   669
	//
sl@0
   670
	TLogWindowAndCursor newWindow(aWindow, aCursor);
sl@0
   671
	iWindowFetcher->PrepareToFetchWindowL(newWindow);
sl@0
   672
	CompleteRequest(KErrNone);
sl@0
   673
	ChangeState(EStateFetchingWindow);
sl@0
   674
	}
sl@0
   675
sl@0
   676
void CLogViewWindow::ChangeState(TWindowState aNewState)
sl@0
   677
	{
sl@0
   678
	iState = aNewState;
sl@0
   679
	}
sl@0
   680
sl@0
   681
void CLogViewWindow::RemoveEvent(TInt aIndex)
sl@0
   682
	{
sl@0
   683
	CLogEvent* event = iEvents[aIndex];
sl@0
   684
	delete event;
sl@0
   685
	iEvents.Remove(aIndex);
sl@0
   686
	}
sl@0
   687
sl@0
   688
TInt CLogViewWindow::CalculateCursorPosition(TLogNavigation aNavigate) const
sl@0
   689
	{
sl@0
   690
	TInt position = 0;
sl@0
   691
	switch(aNavigate)
sl@0
   692
		{
sl@0
   693
	case ELogNavigateForwards:
sl@0
   694
		position = iWindow.iCursorPosition + 1;
sl@0
   695
		break;
sl@0
   696
	case ELogNavigateBackwards:
sl@0
   697
		position = iWindow.iCursorPosition - 1;
sl@0
   698
		break;
sl@0
   699
	case ELogNavigateFirst:
sl@0
   700
		position = 0;
sl@0
   701
		break;
sl@0
   702
	case ELogNavigateLast:
sl@0
   703
		position = iViewRecordCount - 1;
sl@0
   704
		break;
sl@0
   705
	default:
sl@0
   706
		break;
sl@0
   707
		}
sl@0
   708
	return position;
sl@0
   709
	}
sl@0
   710
sl@0
   711
TInt CLogViewWindow::FindEvent(TLogId aId)
sl@0
   712
	{
sl@0
   713
	const TInt count = iEvents.Count();
sl@0
   714
	for(TInt i=0; i<count; i++)
sl@0
   715
		{
sl@0
   716
		CLogEvent* event = iEvents[i];
sl@0
   717
		if	(event->Id() == aId)
sl@0
   718
			return i;
sl@0
   719
		}
sl@0
   720
	return KErrNotFound;
sl@0
   721
	}
sl@0
   722
sl@0
   723
TInt CLogViewWindow::FindAndRemoveEvent(TLogId aId)
sl@0
   724
	{
sl@0
   725
	TInt index = FindEvent(aId);
sl@0
   726
	if	(index >= 0)
sl@0
   727
		{
sl@0
   728
		RemoveEvent(index);
sl@0
   729
		index += iWindow.iLower;
sl@0
   730
		}
sl@0
   731
	return index;
sl@0
   732
	}