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