1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/loggingservices/eventlogger/LogCli/src/LogViewWindow.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,732 @@
1.4 +// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include "LogViewWindow.h"
1.20 +
1.21 +// User includes
1.22 +#include "logclientop.h"
1.23 +#include "logclipanic.h"
1.24 +#include "LogViewWindowChangeObserver.h"
1.25 +
1.26 +// Constants
1.27 +const TInt KWindowSlideSize = 2;
1.28 +
1.29 +
1.30 +/////////////////////////////////////////////////////////////////////////////////////////
1.31 +// -----> CLogViewWindow (source)
1.32 +/////////////////////////////////////////////////////////////////////////////////////////
1.33 +
1.34 +CLogViewWindow::CLogViewWindow(RLogSession& aSession, TLogViewId aViewId, TInt aWindowSize, MLogViewChangeObserver* aCascadeObserver, TInt aPriority)
1.35 +: CLogActive(aPriority), iSession(aSession), iViewId(aViewId), iWindowSize(aWindowSize), iCascadeObserver(aCascadeObserver), iEvents(aWindowSize)
1.36 + {
1.37 + Reset();
1.38 + }
1.39 +
1.40 +CLogViewWindow::~CLogViewWindow()
1.41 + {
1.42 + Cancel();
1.43 + //
1.44 + delete iWindowChangeObserver;
1.45 + delete iWindowPreparer;
1.46 + delete iWindowFetcher;
1.47 + delete iWindowLockObserver;
1.48 + //
1.49 + iEvents.ResetAndDestroy();
1.50 + iEvents.Close();
1.51 + }
1.52 +
1.53 +void CLogViewWindow::ConstructL(CLogPackage& aPackage)
1.54 + {
1.55 + iWindowPreparer = new(ELeave) CLogViewSetupClientOp(iSession, aPackage, CActive::EPriorityStandard);
1.56 + //
1.57 + iWindowFetcher = new(ELeave) CLogViewWindowFetcher(iSession, iViewId, *this, CActive::EPriorityIdle + 1);
1.58 + iWindowFetcher->ConstructL();
1.59 + //
1.60 + iWindowLockObserver = new(ELeave) CLogViewWindowLockObserver(iSession, iViewId, *this, CActive::EPriorityHigh);
1.61 + iWindowLockObserver->ConstructL();
1.62 + //
1.63 + iWindowChangeObserver = new(ELeave) CLogViewWindowChangeObserver(*this);
1.64 + }
1.65 +
1.66 +/////////////////////////////////////////////////////////////////////////////////////////
1.67 +/////////////////////////////////////////////////////////////////////////////////////////
1.68 +/////////////////////////////////////////////////////////////////////////////////////////
1.69 +
1.70 +TInt CLogViewWindow::Setup(const CLogFilterList& aFilterList, TInt aParam, TLogFilterConstructionType aFilterConstructionType)
1.71 + {
1.72 + Reset();
1.73 + iViewRecordCount = iWindowPreparer->Start(iViewId, aFilterList, aParam, aFilterConstructionType);
1.74 + return iViewRecordCount;
1.75 + }
1.76 +
1.77 +TBool CLogViewWindow::NavigateL(TLogNavigation aNavigate, TRequestStatus& aStatus)
1.78 + {
1.79 + // Check why we're already active
1.80 + switch(iState)
1.81 + {
1.82 + case EStateIdle:
1.83 + case EStateLocked:
1.84 + __ASSERT_DEBUG(!IsActive(), Panic(ELogWindowStateMachineNavigationError1));
1.85 + break;
1.86 + case EStateFetchingWindow:
1.87 + case EStateProcessingWindow:
1.88 + case EStateNavigateWithinWindow:
1.89 + // We're trying to catch up with some changes.. use the requested
1.90 + // window as the new window, but refetch everything.
1.91 + __ASSERT_DEBUG(IsActive(), Panic(ELogWindowStateMachineNavigationError2));
1.92 + SilentCancel();
1.93 + iWindow = iWindowFetcher->RequestedWindow();
1.94 + break;
1.95 + default:
1.96 + break;
1.97 + }
1.98 +
1.99 + // Perform boundary checks
1.100 + TInt cursorPos = CalculateCursorPosition(aNavigate);
1.101 + if (cursorPos < 0 || cursorPos >= iViewRecordCount)
1.102 + {
1.103 + // Can't navigate to the specified position
1.104 + return EFalse;
1.105 + }
1.106 +
1.107 + // Check whether the cursor position falls within the view window
1.108 + if (iWindow.iValid && iWindow.Contains(cursorPos))
1.109 + {
1.110 + // Can return event from window
1.111 + CompleteRequest(cursorPos);
1.112 + ChangeState(EStateNavigateWithinWindow);
1.113 + }
1.114 + else
1.115 + {
1.116 + // Have to fetch a new window. Work it out...
1.117 + TLogWindowAndCursor window;
1.118 + CalculateWindowForCursorPosition(cursorPos, window);
1.119 + window.iCursorPosition = cursorPos;
1.120 + iWindowFetcher->PrepareToFetchWindowL(window);
1.121 + //
1.122 + CompleteRequest(KErrNone);
1.123 + ChangeState(EStateFetchingWindow);
1.124 + }
1.125 +
1.126 + // Okay to (try to) navigate here
1.127 + Queue(aStatus);
1.128 + return ETrue;
1.129 + }
1.130 +
1.131 +void CLogViewWindow::RemoveFromWindowIfPresentL(TLogId aId)
1.132 + {
1.133 + TInt index = FindEvent(aId);
1.134 + if (index >= 0)
1.135 + {
1.136 + // Ignore next window removal event (since we're proactively removing
1.137 + // the event from the client side without server prompting).
1.138 + iWindowChangeObserver->IgnoreNextEventL(aId, CLogViewWindowChangeObserver::ELogEventTypeDelete);
1.139 +
1.140 + // Delete item
1.141 + RemoveEvent(index);
1.142 +
1.143 + // Map onto full view position
1.144 + index += iWindow.iLower;
1.145 +
1.146 + // Update window - when removing the last event from the window, we must
1.147 + // ensure we mark the window as invalid.
1.148 + if (iWindow.AdjustForItemDeletion(index) == TLogWindowAndCursor::EWindowAffected && iEvents.Count() == 0)
1.149 + {
1.150 + iWindow.Reset();
1.151 + }
1.152 + }
1.153 + //
1.154 + --iViewRecordCount;
1.155 + }
1.156 +
1.157 +MLogViewChangeObserverInternal& CLogViewWindow::ChangeObserver()
1.158 + {
1.159 + __ASSERT_ALWAYS(iWindowChangeObserver, Panic(ELogWindowNoChangeObserver));
1.160 + return *iWindowChangeObserver;
1.161 + }
1.162 +
1.163 +const CLogEvent& CLogViewWindow::CurrsorEvent() const
1.164 + {
1.165 + // Map the cursor position to fall within the window
1.166 + const TInt mappedIndex = iWindow.WindowIndexFromCursorPosition();
1.167 + const TInt count = iEvents.Count();
1.168 + __ASSERT_ALWAYS(mappedIndex >= 0 && mappedIndex < count, Panic(ELogWindowCursorCalculationOutOfBounds));
1.169 + return *iEvents[mappedIndex];
1.170 + }
1.171 +
1.172 +/////////////////////////////////////////////////////////////////////////////////////////
1.173 +/////////////////////////////////////////////////////////////////////////////////////////
1.174 +/////////////////////////////////////////////////////////////////////////////////////////
1.175 +
1.176 +void CLogViewWindow::HandleWindowLockStatusChangeL(TLogViewLockStatus aStatus)
1.177 + {
1.178 + switch(aStatus)
1.179 + {
1.180 + case ELogViewWindowLocked:
1.181 + SilentCancel();
1.182 + iState = EStateLocked;
1.183 + break;
1.184 + case ELogViewWindowOpen:
1.185 + if (iState == EStateLocked)
1.186 + iState = EStateIdle;
1.187 + break;
1.188 + default:
1.189 + break;
1.190 + }
1.191 +
1.192 + // The window is never valid after a change in lock status
1.193 + iWindow.iValid = EFalse;
1.194 + }
1.195 +
1.196 +/////////////////////////////////////////////////////////////////////////////////////////
1.197 +/////////////////////////////////////////////////////////////////////////////////////////
1.198 +/////////////////////////////////////////////////////////////////////////////////////////
1.199 +
1.200 +void CLogViewWindow::HandleFetchedWindowItemL(TInt /*aItemIndex*/, CLogEvent* aEvent)
1.201 + {
1.202 + // IMPROVEMENT: could use aItemIndex as the insertion point?
1.203 + User::LeaveIfError(iEvents.Append(aEvent));
1.204 + }
1.205 +
1.206 +/////////////////////////////////////////////////////////////////////////////////////////
1.207 +/////////////////////////////////////////////////////////////////////////////////////////
1.208 +/////////////////////////////////////////////////////////////////////////////////////////
1.209 +
1.210 +void CLogViewWindow::HandleLogViewChangeEventAddedL(TLogId aId, TInt aViewIndex, TInt aChangeIndex, TInt aTotalChangeCount)
1.211 + {
1.212 + ///////////////////////////////////////
1.213 + // USE CASE 1:
1.214 + ///////////////////////////////////////
1.215 + // Cursor position: *
1.216 + // View Index: 0 1 2 3 4 5 6
1.217 + // View Contents: A B C D E F G
1.218 + //
1.219 + // Then, item X is added =>
1.220 + //
1.221 + // Cursor position: *
1.222 + // View Index: 0 1 2 3 4 5 6 7
1.223 + // View Contents: X A B C D E F G
1.224 + //
1.225 + ///////////////////////////////////////
1.226 + // USE CASE 2:
1.227 + ///////////////////////////////////////
1.228 + // Cursor position: *
1.229 + // View Index: 0 1 2 3 4 5 6
1.230 + // View Contents: A B C D E F G
1.231 + //
1.232 + // Then, item X is added =>
1.233 + //
1.234 + // Cursor position: *
1.235 + // View Index: 0 1 2 3 4 5 6 7
1.236 + // View Contents: X A B C D E F G
1.237 + //
1.238 + ///////////////////////////////////////
1.239 + // USE CASE 3:
1.240 + ///////////////////////////////////////
1.241 + // Cursor position: *
1.242 + // View Index: 0 1 2 3 4 5 6
1.243 + // View Contents: A B C D E F G
1.244 + //
1.245 + // Then, item X is added =>
1.246 + //
1.247 + // Cursor position: *
1.248 + // View Index: 0 1 2 3 4 5 6 7
1.249 + // View Contents: X A B C D E F G
1.250 + //
1.251 + ///////////////////////////////////////
1.252 + // USE CASE 4:
1.253 + ///////////////////////////////////////
1.254 + // Cursor position: *
1.255 + // View Index: 0 1 2 3 4 5 6
1.256 + // View Contents: A B C D E F G
1.257 + //
1.258 + // Then, change item Z so that it now appears in the view
1.259 + //
1.260 + // Cursor position: *
1.261 + // View Index: 0 1 2 3 4 5 6 7
1.262 + // View Contents: A B C Z D E F G
1.263 + //
1.264 + ///////////////////////////////////////
1.265 + // USE CASE 5:
1.266 + ///////////////////////////////////////
1.267 + // Cursor position: *
1.268 + // View Index: 0 1 2 3 4 5 6
1.269 + // View Contents: A B C D E F G
1.270 + //
1.271 + // Then, change item Z so that it now appears in the view
1.272 + //
1.273 + // Cursor position: *
1.274 + // View Index: 0 1 2 3 4 5 6 7
1.275 + // View Contents: A B C Z D E F G
1.276 + //
1.277 + ///////////////////////////////////////
1.278 + //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);
1.279 +
1.280 + // Must compare against the current window (if this object is idle) or against
1.281 + // the window fetcher's window if it is in the process of making a fetch
1.282 + TLogWindowAndCursor currentWindow;
1.283 + switch(iState)
1.284 + {
1.285 + case EStateFetchingWindow:
1.286 + case EStateProcessingWindow:
1.287 + currentWindow = iWindowFetcher->RequestedWindow();
1.288 + break;
1.289 + case EStateNavigateWithinWindow:
1.290 + case EStateIdle:
1.291 + case EStateLocked:
1.292 + currentWindow = iWindow;
1.293 + break;
1.294 + }
1.295 +
1.296 + // If the addition took place after the window, then we do nothing (except update the
1.297 + // total view record count)
1.298 + if (aViewIndex <= currentWindow.iUpper)
1.299 + {
1.300 + // If the addition took place before our window, or at the very start, then we simply need to adjust
1.301 + // the window & cursor position. If the window fetcher was active then this will affect the window
1.302 + // being fetched - in this case, we MUST refetch the whole window.
1.303 + if (iState == EStateIdle && aViewIndex <= currentWindow.iLower)
1.304 + {
1.305 + iWindow.AdjustForItemAddition(aViewIndex);
1.306 + }
1.307 + else
1.308 + {
1.309 + // If the addition took place within the window, then we have to refetch the window
1.310 + TBool refetch = ETrue;
1.311 + TLogWindowAndCursor newWindow;
1.312 + //
1.313 + switch(iState)
1.314 + {
1.315 + case EStateIdle:
1.316 + newWindow = iWindow;
1.317 + break;
1.318 + case EStateNavigateWithinWindow:
1.319 + // Since we complete our own request status with the new cursor position,
1.320 + // we can use that here as the desired cursor position after the fetch
1.321 + newWindow = iWindow;
1.322 + newWindow.iCursorPosition = iStatus.Int();
1.323 + break;
1.324 + case EStateFetchingWindow:
1.325 + case EStateProcessingWindow:
1.326 + newWindow = iWindowFetcher->RequestedWindow();
1.327 + break;
1.328 + case EStateLocked:
1.329 + // Don't need to do anything. When the view is unlocked, we refetch anyway
1.330 + refetch = EFalse;
1.331 + break;
1.332 + default:
1.333 + break;
1.334 + }
1.335 + //
1.336 + if (refetch)
1.337 + {
1.338 + newWindow.AdjustForItemAddition(aViewIndex);
1.339 + RefetchL(newWindow, newWindow.iCursorPosition);
1.340 + }
1.341 + }
1.342 + }
1.343 +
1.344 + // Increase the total view size
1.345 + ++iViewRecordCount;
1.346 +
1.347 + if (iCascadeObserver)
1.348 + iCascadeObserver->HandleLogViewChangeEventAddedL(aId, aViewIndex, aChangeIndex, aTotalChangeCount);
1.349 + }
1.350 +
1.351 +void CLogViewWindow::HandleLogViewChangeEventChangedL(TLogId aId, TInt aViewIndex, TInt aChangeIndex, TInt aTotalChangeCount)
1.352 + {
1.353 + //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);
1.354 +
1.355 + // Must compare against the current window (if this object is idle) or against
1.356 + // the window fetcher's window if it is in the process of making a fetch
1.357 + TLogWindowAndCursor currentWindow;
1.358 + switch(iState)
1.359 + {
1.360 + case EStateFetchingWindow:
1.361 + case EStateProcessingWindow:
1.362 + currentWindow = iWindowFetcher->RequestedWindow();
1.363 + break;
1.364 + case EStateNavigateWithinWindow:
1.365 + case EStateIdle:
1.366 + case EStateLocked:
1.367 + currentWindow = iWindow;
1.368 + break;
1.369 + default:
1.370 + break;
1.371 + }
1.372 +
1.373 + // If the event that changed was within the view, then we have to refetch it
1.374 + if (currentWindow.Contains(aViewIndex))
1.375 + {
1.376 + switch(iState)
1.377 + {
1.378 + case EStateIdle:
1.379 + RefetchL(iWindow, iWindow.iCursorPosition);
1.380 + break;
1.381 + case EStateNavigateWithinWindow:
1.382 + // Since we complete our own request status with the new cursor position,
1.383 + // we can use that here as the desired cursor position after the fetch
1.384 + RefetchL(iWindow, iStatus.Int());
1.385 + break;
1.386 + case EStateFetchingWindow:
1.387 + case EStateProcessingWindow:
1.388 + RefetchL(iWindowFetcher->RequestedWindow(), iWindowFetcher->RequestedWindow().iCursorPosition);
1.389 + break;
1.390 + case EStateLocked:
1.391 + // Don't need to do anything. When the view is unlocked, we refetch anyway
1.392 + break;
1.393 + default:
1.394 + break;
1.395 + }
1.396 + }
1.397 +
1.398 + if (iCascadeObserver)
1.399 + iCascadeObserver->HandleLogViewChangeEventChangedL(aId, aViewIndex, aChangeIndex, aTotalChangeCount);
1.400 + }
1.401 +
1.402 +void CLogViewWindow::HandleLogViewChangeEventDeletedL(TLogId aId, TInt aViewIndex, TInt aChangeIndex, TInt aTotalChangeCount)
1.403 + {
1.404 + ///////////////////////////////////////
1.405 + // USE CASE 1:
1.406 + ///////////////////////////////////////
1.407 + // Cursor position: *
1.408 + // View Index: 0 1 2 3 4 5 6
1.409 + // View Contents: A B C D E F G
1.410 + //
1.411 + // Then, item 5 is deleted =>
1.412 + //
1.413 + // Cursor position: *
1.414 + // View Index: 0 1 2 3 4 5
1.415 + // View Contents: A B C D E G
1.416 + //
1.417 + ///////////////////////////////////////
1.418 + // USE CASE 2:
1.419 + ///////////////////////////////////////
1.420 + // Cursor position: *
1.421 + // View Index: 0 1 2 3 4 5 6
1.422 + // View Contents: A B C D E F G
1.423 + //
1.424 + // Then, item 4 is deleted =>
1.425 + //
1.426 + // Cursor position: *
1.427 + // View Index: 0 1 2 3 4 5
1.428 + // View Contents: A B C D F G
1.429 + //
1.430 + ///////////////////////////////////////
1.431 + // USE CASE 3:
1.432 + ///////////////////////////////////////
1.433 + // Cursor position: *
1.434 + // View Index: 0 1 2 3 4 5 6
1.435 + // View Contents: A B C D E F G
1.436 + //
1.437 + // Then, item 6 is deleted =>
1.438 + //
1.439 + // Cursor position: *
1.440 + // View Index: 0 1 2 3 4 5
1.441 + // View Contents: A B C D E F
1.442 + //
1.443 + ///////////////////////////////////////
1.444 + // USE CASE 4:
1.445 + ///////////////////////////////////////
1.446 + // Cursor position: *
1.447 + // View Index: 0 1 2 3 4 5 6
1.448 + // View Contents: A B C D E F G
1.449 + //
1.450 + // Then, item 6 is deleted =>
1.451 + //
1.452 + // Cursor position: *
1.453 + // View Index: 0 1 2 3 4 5
1.454 + // View Contents: B C D E F G
1.455 + //
1.456 + ///////////////////////////////////////
1.457 + //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);
1.458 +
1.459 + // Must compare against the current window (if this object is idle) or against
1.460 + // the window fetcher's window if it is in the process of making a fetch
1.461 + TLogWindowAndCursor currentWindow;
1.462 + switch(iState)
1.463 + {
1.464 + case EStateFetchingWindow:
1.465 + case EStateProcessingWindow:
1.466 + currentWindow = iWindowFetcher->RequestedWindow();
1.467 + break;
1.468 + case EStateNavigateWithinWindow:
1.469 + case EStateIdle:
1.470 + case EStateLocked:
1.471 + currentWindow = iWindow;
1.472 + break;
1.473 + default:
1.474 + break;
1.475 + }
1.476 +
1.477 + // Does the change alter our current window in any way?
1.478 + if (aViewIndex <= currentWindow.iUpper)
1.479 + {
1.480 + TBool refetch = ETrue;
1.481 + TLogWindowAndCursor newWindow;
1.482 + //
1.483 + switch(iState)
1.484 + {
1.485 + case EStateIdle:
1.486 + FindAndRemoveEvent(aId);
1.487 +
1.488 + // When removing the last event from the window, we must ensure we mark
1.489 + // the window as invalid.
1.490 + if (iWindow.AdjustForItemDeletion(aViewIndex) == TLogWindowAndCursor::EWindowAffected && iEvents.Count() == 0)
1.491 + {
1.492 + iWindow.Reset();
1.493 + }
1.494 +
1.495 + refetch = EFalse;
1.496 + break;
1.497 + case EStateNavigateWithinWindow:
1.498 + newWindow = iWindow;
1.499 + newWindow.iCursorPosition = iStatus.Int();
1.500 + break;
1.501 + case EStateFetchingWindow:
1.502 + case EStateProcessingWindow:
1.503 + newWindow = iWindowFetcher->RequestedWindow();
1.504 + break;
1.505 + case EStateLocked:
1.506 + // Don't need to do anything. When the view is unlocked, we refetch anyway
1.507 + refetch = EFalse;
1.508 + break;
1.509 + default:
1.510 + break;
1.511 + }
1.512 + //
1.513 + if (refetch)
1.514 + {
1.515 + newWindow.AdjustForItemDeletion(aViewIndex);
1.516 + RefetchL(newWindow, newWindow.iCursorPosition);
1.517 + }
1.518 + }
1.519 +
1.520 + // Reduce the total view size
1.521 + --iViewRecordCount;
1.522 +
1.523 + if (iCascadeObserver)
1.524 + iCascadeObserver->HandleLogViewChangeEventDeletedL(aId, aViewIndex, aChangeIndex, aTotalChangeCount);
1.525 + }
1.526 +
1.527 +/////////////////////////////////////////////////////////////////////////////////////////
1.528 +/////////////////////////////////////////////////////////////////////////////////////////
1.529 +/////////////////////////////////////////////////////////////////////////////////////////
1.530 +
1.531 +void CLogViewWindow::HandleLogViewChangeEventLogClearedL()
1.532 + {
1.533 + Cancel();
1.534 + Reset();
1.535 +
1.536 + // This event type is not cascaded to the client of the log engine
1.537 + }
1.538 +
1.539 +/////////////////////////////////////////////////////////////////////////////////////////
1.540 +/////////////////////////////////////////////////////////////////////////////////////////
1.541 +/////////////////////////////////////////////////////////////////////////////////////////
1.542 +
1.543 +void CLogViewWindow::DoRunL()
1.544 + {
1.545 + switch(iState)
1.546 + {
1.547 + case EStateFetchingWindow:
1.548 + StateHandleWindowFetchStarting();
1.549 + break;
1.550 + case EStateProcessingWindow:
1.551 + StateHandleWindowFetchedL();
1.552 + break;
1.553 + case EStateNavigateWithinWindow:
1.554 + StateHandleNavigation();
1.555 + break;
1.556 + case EStateIdle:
1.557 + case EStateLocked:
1.558 + default:
1.559 + break;
1.560 + }
1.561 + }
1.562 +
1.563 +void CLogViewWindow::DoCancel()
1.564 + {
1.565 + if(iState == EStateProcessingWindow)
1.566 + {
1.567 + iWindowFetcher->Cancel();
1.568 + }
1.569 + CLogActive::DoCancel();
1.570 + }
1.571 +
1.572 +void CLogViewWindow::DoComplete(TInt& aComplete)
1.573 + {
1.574 + switch(iState)
1.575 + {
1.576 + default:
1.577 + case EStateIdle:
1.578 + break;
1.579 + case EStateNavigateWithinWindow:
1.580 + if (aComplete < KErrNone)
1.581 + {
1.582 + // Reset to known state
1.583 + iState = EStateIdle;
1.584 + }
1.585 + break;
1.586 + case EStateFetchingWindow:
1.587 + case EStateProcessingWindow:
1.588 + if (aComplete < KErrNone)
1.589 + {
1.590 + // Reset to known state
1.591 + iState = EStateIdle;
1.592 + iWindow = iWindowFetcher->RequestedWindow();
1.593 + }
1.594 + break;
1.595 + case EStateLocked:
1.596 + aComplete = KErrAccessDenied;
1.597 + break;
1.598 + }
1.599 + }
1.600 +
1.601 +/////////////////////////////////////////////////////////////////////////////////////////
1.602 +/////////////////////////////////////////////////////////////////////////////////////////
1.603 +/////////////////////////////////////////////////////////////////////////////////////////
1.604 +
1.605 +void CLogViewWindow::StateHandleWindowFetchStarting()
1.606 + {
1.607 + iEvents.ResetAndDestroy();
1.608 + iWindowFetcher->Start(iStatus);
1.609 + ChangeState(EStateProcessingWindow);
1.610 + SetActive();
1.611 + }
1.612 +
1.613 +void CLogViewWindow::StateHandleWindowFetchedL()
1.614 + {
1.615 + const TInt count = iEvents.Count();
1.616 + const TInt expected = iWindowFetcher->RequestedWindow().Range();
1.617 + if (expected != count)
1.618 + User::Leave(KErrGeneral);
1.619 + //
1.620 + iWindow = iWindowFetcher->RequestedWindow();
1.621 + CompleteRequest(iWindow.iCursorPosition);
1.622 + ChangeState(EStateNavigateWithinWindow);
1.623 + }
1.624 +
1.625 +void CLogViewWindow::StateHandleNavigation()
1.626 + {
1.627 + const TInt cursorPos = iStatus.Int();
1.628 + __ASSERT_ALWAYS(iWindow.Contains(cursorPos), Panic(ELogWindowNavigationOutsideWindow));
1.629 + iWindow.iCursorPosition = cursorPos;
1.630 + ChangeState(EStateIdle);
1.631 + }
1.632 +
1.633 +/////////////////////////////////////////////////////////////////////////////////////////
1.634 +/////////////////////////////////////////////////////////////////////////////////////////
1.635 +/////////////////////////////////////////////////////////////////////////////////////////
1.636 +
1.637 +void CLogViewWindow::CompleteRequest(TInt aCompletionCode)
1.638 + {
1.639 + if (!IsActive() || (IsActive() && iStatus == KRequestPending))
1.640 + {
1.641 + TRequestStatus* status = &iStatus;
1.642 + User::RequestComplete(status, aCompletionCode);
1.643 + if (!IsActive())
1.644 + SetActive();
1.645 + }
1.646 + }
1.647 +
1.648 +void CLogViewWindow::CalculateWindowForCursorPosition(TInt aCursorPosition, TLogWindow& aWindow) const
1.649 + {
1.650 + aWindow.iLower = Max(0, aCursorPosition - KWindowSlideSize - 1);
1.651 + aWindow.iUpper = Min(iViewRecordCount - 1, aWindow.iLower + iWindowSize - 1);
1.652 + }
1.653 +
1.654 +void CLogViewWindow::Reset()
1.655 + {
1.656 + Cancel();
1.657 + //
1.658 + iViewRecordCount = 0;
1.659 + iWindow.Reset();
1.660 + iEvents.ResetAndDestroy();
1.661 + iState = EStateIdle;
1.662 + }
1.663 +
1.664 +void CLogViewWindow::SilentCancel()
1.665 + {
1.666 + iWindowFetcher->SilentCancel();
1.667 + }
1.668 +
1.669 +void CLogViewWindow::RefetchL(const TLogWindow& aWindow, TInt aCursor)
1.670 + {
1.671 + SilentCancel();
1.672 + //
1.673 + TLogWindowAndCursor newWindow(aWindow, aCursor);
1.674 + iWindowFetcher->PrepareToFetchWindowL(newWindow);
1.675 + CompleteRequest(KErrNone);
1.676 + ChangeState(EStateFetchingWindow);
1.677 + }
1.678 +
1.679 +void CLogViewWindow::ChangeState(TWindowState aNewState)
1.680 + {
1.681 + iState = aNewState;
1.682 + }
1.683 +
1.684 +void CLogViewWindow::RemoveEvent(TInt aIndex)
1.685 + {
1.686 + CLogEvent* event = iEvents[aIndex];
1.687 + delete event;
1.688 + iEvents.Remove(aIndex);
1.689 + }
1.690 +
1.691 +TInt CLogViewWindow::CalculateCursorPosition(TLogNavigation aNavigate) const
1.692 + {
1.693 + TInt position = 0;
1.694 + switch(aNavigate)
1.695 + {
1.696 + case ELogNavigateForwards:
1.697 + position = iWindow.iCursorPosition + 1;
1.698 + break;
1.699 + case ELogNavigateBackwards:
1.700 + position = iWindow.iCursorPosition - 1;
1.701 + break;
1.702 + case ELogNavigateFirst:
1.703 + position = 0;
1.704 + break;
1.705 + case ELogNavigateLast:
1.706 + position = iViewRecordCount - 1;
1.707 + break;
1.708 + default:
1.709 + break;
1.710 + }
1.711 + return position;
1.712 + }
1.713 +
1.714 +TInt CLogViewWindow::FindEvent(TLogId aId)
1.715 + {
1.716 + const TInt count = iEvents.Count();
1.717 + for(TInt i=0; i<count; i++)
1.718 + {
1.719 + CLogEvent* event = iEvents[i];
1.720 + if (event->Id() == aId)
1.721 + return i;
1.722 + }
1.723 + return KErrNotFound;
1.724 + }
1.725 +
1.726 +TInt CLogViewWindow::FindAndRemoveEvent(TLogId aId)
1.727 + {
1.728 + TInt index = FindEvent(aId);
1.729 + if (index >= 0)
1.730 + {
1.731 + RemoveEvent(index);
1.732 + index += iWindow.iLower;
1.733 + }
1.734 + return index;
1.735 + }