571c19840f9b28c91457538789c15da04ecc7bd6
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / views / timechart / TimeChartView.java
1 /*******************************************************************************
2 * Copyright (c) 2010, 2015 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Patrick Tasse - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.tracecompass.tmf.ui.views.timechart;
14
15 import java.util.ArrayList;
16 import java.util.HashMap;
17 import java.util.Iterator;
18 import java.util.List;
19 import java.util.Map;
20
21 import org.eclipse.core.resources.IFile;
22 import org.eclipse.core.resources.IMarker;
23 import org.eclipse.core.resources.IMarkerDelta;
24 import org.eclipse.core.resources.IResourceChangeEvent;
25 import org.eclipse.core.resources.IResourceChangeListener;
26 import org.eclipse.core.resources.IResourceDelta;
27 import org.eclipse.core.resources.ResourcesPlugin;
28 import org.eclipse.jface.action.IStatusLineManager;
29 import org.eclipse.swt.SWT;
30 import org.eclipse.swt.widgets.Composite;
31 import org.eclipse.swt.widgets.Display;
32 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
33 import org.eclipse.tracecompass.tmf.core.signal.TmfEventFilterAppliedSignal;
34 import org.eclipse.tracecompass.tmf.core.signal.TmfEventSearchAppliedSignal;
35 import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
36 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
37 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal;
38 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
39 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
40 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceUpdatedSignal;
41 import org.eclipse.tracecompass.tmf.core.signal.TmfWindowRangeUpdatedSignal;
42 import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
43 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
44 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
45 import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
46 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
47 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceContext;
48 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
49 import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentInfo;
50 import org.eclipse.tracecompass.tmf.ui.views.ITmfTimeAligned;
51 import org.eclipse.tracecompass.tmf.ui.views.TmfView;
52 import org.eclipse.tracecompass.tmf.ui.views.colors.ColorSetting;
53 import org.eclipse.tracecompass.tmf.ui.views.colors.ColorSettingsManager;
54 import org.eclipse.tracecompass.tmf.ui.views.colors.IColorSettingsListener;
55 import org.eclipse.tracecompass.tmf.ui.views.timechart.TimeChartEvent.RankRange;
56 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider;
57 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphRangeListener;
58 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphSelectionListener;
59 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphTimeListener;
60 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEvent;
61 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphSelectionEvent;
62 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphTimeEvent;
63 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphViewer;
64 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
65 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
66 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
67
68 /**
69 * Generic Time Chart view, which is similar to a Gantt chart for trace analysis
70 *
71 * @version 1.0
72 * @author Patrick Tasse
73 */
74 public class TimeChartView extends TmfView implements ITimeGraphRangeListener, ITimeGraphSelectionListener, ITimeGraphTimeListener, IColorSettingsListener, IResourceChangeListener, ITmfTimeAligned {
75
76 /** TimeChartView's ID */
77 public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.timechart"; //$NON-NLS-1$
78
79 private final int fDisplayWidth;
80 private TimeGraphViewer fViewer;
81 private final List<TimeChartAnalysisEntry> fTimeAnalysisEntries = new ArrayList<>();
82 private final Map<ITmfTrace, TimeChartDecorationProvider> fDecorationProviders = new HashMap<>();
83 private final List<DecorateThread> fDecorateThreads = new ArrayList<>();
84 private long fStartTime = 0;
85 private long fStopTime = Long.MAX_VALUE;
86 private boolean fRefreshBusy = false;
87 private boolean fRefreshPending = false;
88 private boolean fRedrawBusy = false;
89 private boolean fRedrawPending = false;
90 private final Object fSyncObj = new Object();
91 private ITimeGraphPresentationProvider fPresentationProvider;
92
93 /**
94 * Default constructor
95 */
96 public TimeChartView() {
97 super("Time Chart"); //$NON-NLS-1$
98 fDisplayWidth = Display.getDefault().getBounds().width;
99 }
100
101 @Override
102 public void createPartControl(Composite parent) {
103 super.createPartControl(parent);
104 fViewer = new TimeGraphViewer(parent, SWT.NONE);
105 fPresentationProvider = new TimeChartAnalysisProvider();
106 fViewer.setTimeGraphProvider(fPresentationProvider);
107 fViewer.setTimeFormat(TimeFormat.CALENDAR);
108 fViewer.addTimeListener(this);
109 fViewer.addRangeListener(this);
110 fViewer.addSelectionListener(this);
111 fViewer.setMinimumItemWidth(1);
112 fViewer.getTimeGraphControl().setBlendSubPixelEvents(true);
113
114 IStatusLineManager statusLineManager = getViewSite().getActionBars().getStatusLineManager();
115 fViewer.getTimeGraphControl().setStatusLineManager(statusLineManager);
116
117 for (ITmfTrace trace : TmfTraceManager.getInstance().getOpenedTraces()) {
118 IFile bookmarksFile = TmfTraceManager.getInstance().getTraceEditorFile(trace);
119 TimeChartAnalysisEntry timeAnalysisEntry = new TimeChartAnalysisEntry(trace, fDisplayWidth * 2);
120 fTimeAnalysisEntries.add(timeAnalysisEntry);
121 fDecorationProviders.put(trace, new TimeChartDecorationProvider(bookmarksFile));
122 Thread thread = new ProcessTraceThread(timeAnalysisEntry);
123 thread.start();
124 }
125 fViewer.setInput(fTimeAnalysisEntries.toArray(new TimeChartAnalysisEntry[0]));
126
127 ColorSettingsManager.addColorSettingsListener(this);
128 ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);
129 }
130
131 @Override
132 public void dispose() {
133 ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
134 for (DecorateThread thread : fDecorateThreads) {
135 thread.cancel();
136 }
137 ColorSettingsManager.removeColorSettingsListener(this);
138 super.dispose();
139 }
140
141 @Override
142 public void setFocus() {
143 fViewer.setFocus();
144 }
145
146 private class ProcessTraceThread extends Thread {
147
148 private final TimeChartAnalysisEntry fTimeAnalysisEntry;
149
150 public ProcessTraceThread(TimeChartAnalysisEntry timeAnalysisEntry) {
151 super("ProcessTraceJob:" + timeAnalysisEntry.getName()); //$NON-NLS-1$
152 fTimeAnalysisEntry = timeAnalysisEntry;
153 }
154
155 @Override
156 public void run() {
157 TmfTimeRange range = TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange();
158
159 updateTraceEntry(fTimeAnalysisEntry, Long.MAX_VALUE,
160 range.getStartTime().toNanos(),
161 range.getEndTime().toNanos());
162 }
163 }
164
165 private void updateTraceEntry(TimeChartAnalysisEntry timeAnalysisEntry, long stopRank, long startTime, long stopTime) {
166 ITmfTrace trace = timeAnalysisEntry.getTrace();
167 TimeChartDecorationProvider decorationProvider = fDecorationProviders.get(trace);
168 if (decorationProvider == null) {
169 return; // the trace has been closed
170 }
171 ITmfContext context = null;
172 // TmfTimestamp lastTimestamp = null;
173 boolean done = false;
174 while (!done) {
175 synchronized (timeAnalysisEntry) {
176 if (timeAnalysisEntry.getLastRank() >= trace.getNbEvents()) {
177 done = true;
178 break;
179 }
180 if (context == null || context.getRank() != timeAnalysisEntry.getLastRank()) {
181 if (context != null) {
182 context.dispose();
183 }
184 if (timeAnalysisEntry.getLastRank() != -1) {
185 context = trace.seekEvent(timeAnalysisEntry.getLastRank());
186 } else {
187 // context = trace.seekLocation(null);
188 context = trace.seekEvent(0);
189 }
190 }
191 while (true) {
192 long rank = context.getRank();
193 ITmfEvent event = trace.getNext(context);
194 if (event == null) {
195 done = true;
196 break;
197 }
198 // if (!event.getTimestamp().equals(lastTimestamp)) {
199 TimeChartEvent timeEvent = new TimeChartEvent(timeAnalysisEntry, event, rank, decorationProvider);
200 if (timeEvent.getTime() >= startTime && timeEvent.getTime() <= stopTime) {
201 timeAnalysisEntry.addTraceEvent(timeEvent);
202 }
203 // lastTimestamp = event.getTimestamp();
204 // } *** commented out so that color setting priority gets
205 // set even if the event has same time
206 if (context.getRank() == trace.getNbEvents() || context.getRank() == stopRank) {
207 done = true;
208 break;
209 }
210 if (context.getRank() % trace.getCacheSize() == 1) {
211 // break for UI refresh
212 break;
213 }
214 }
215 // timeAnalysisEntry.setLastRank(Math.min(trace.getNbEvents(),
216 // stopRank));
217 timeAnalysisEntry.setLastRank(context.getRank());
218 }
219 redrawViewer(true);
220 }
221 if (context != null) {
222 context.dispose();
223 }
224 }
225
226 private void refreshViewer() {
227 synchronized (fSyncObj) {
228 if (fRefreshBusy) {
229 fRefreshPending = true;
230 return;
231 }
232 fRefreshBusy = true;
233 }
234 // Perform the refresh on the UI thread
235 Display.getDefault().asyncExec(new Runnable() {
236 @Override
237 public void run() {
238 if (fViewer.getControl().isDisposed()) {
239 return;
240 }
241 fViewer.setInput(fTimeAnalysisEntries.toArray(new TimeChartAnalysisEntry[0]));
242 fViewer.resetStartFinishTime();
243 synchronized (fSyncObj) {
244 fRefreshBusy = false;
245 if (fRefreshPending) {
246 fRefreshPending = false;
247 refreshViewer();
248 }
249 }
250 }
251 });
252 }
253
254 private void redrawViewer(boolean resetTimeIntervals) {
255 synchronized (fSyncObj) {
256 if (fRedrawBusy) {
257 fRedrawPending = true;
258 return;
259 }
260 fRedrawBusy = true;
261 }
262 final boolean reset = resetTimeIntervals;
263 // Perform the refresh on the UI thread
264 Display.getDefault().asyncExec(new Runnable() {
265 @Override
266 public void run() {
267 if (fViewer.getControl().isDisposed()) {
268 return;
269 }
270 if (reset) {
271 fViewer.setTimeRange(fTimeAnalysisEntries.toArray(new TimeChartAnalysisEntry[0]));
272 fViewer.setTimeBounds();
273 }
274 fViewer.getControl().redraw();
275 fViewer.getControl().update();
276 synchronized (fSyncObj) {
277 fRedrawBusy = false;
278 if (fRedrawPending) {
279 fRedrawPending = false;
280 redrawViewer(reset);
281 }
282 }
283 }
284 });
285 }
286
287 private void itemize(long startTime, long stopTime) {
288 for (int i = 0; i < fTimeAnalysisEntries.size(); i++) {
289 Thread thread = new ItemizeThread(fTimeAnalysisEntries.get(i), startTime, stopTime);
290 thread.start();
291 }
292 }
293
294 private class ItemizeThread extends Thread {
295
296 private final TimeChartAnalysisEntry fTimeAnalysisEntry;
297 private final long startTime;
298 private final long stopTime;
299 private final long fMaxDuration;
300
301 private ItemizeThread(TimeChartAnalysisEntry timeAnalysisEntry, long startTime, long stopTime) {
302 super("Itemize Thread:" + timeAnalysisEntry.getName()); //$NON-NLS-1$
303 fTimeAnalysisEntry = timeAnalysisEntry;
304 this.startTime = startTime;
305 this.stopTime = stopTime;
306 fMaxDuration = 3 * (stopTime - startTime) / fDisplayWidth;
307 }
308
309 @Override
310 public void run() {
311 itemizeTraceEntry(fTimeAnalysisEntry);
312 }
313
314 public void itemizeTraceEntry(TimeChartAnalysisEntry timeAnalysisEntry) {
315 Iterator<ITimeEvent> iterator = timeAnalysisEntry.getTimeEventsIterator();
316 TimeChartEvent event = null;
317 boolean hasNext = true;
318 while (hasNext) {
319 synchronized (timeAnalysisEntry) {
320 while ((hasNext = iterator.hasNext()) == true) {
321 event = (TimeChartEvent) iterator.next();
322 if (event.getTime() + event.getDuration() > startTime && event.getTime() < stopTime && event.getDuration() > fMaxDuration
323 && event.getNbEvents() > 1) {
324 break;
325 }
326 }
327 }
328 if (hasNext && event != null) {
329 if (event.getItemizedEntry() == null) {
330 itemizeEvent(event);
331 } else {
332 itemizeTraceEntry(event.getItemizedEntry());
333 }
334 }
335 }
336 }
337
338 public void itemizeEvent(TimeChartEvent event) {
339 synchronized (event) {
340 if (event.isItemizing()) {
341 return;
342 }
343 event.setItemizing(true);
344 }
345 TimeChartAnalysisEntry timeAnalysisEntry = new TimeChartAnalysisEntry(fTimeAnalysisEntry.getTrace(), (int) Math.min(
346 event.getNbEvents() + 1, fDisplayWidth * 2));
347 synchronized (event.getRankRangeList()) {
348 for (RankRange range : event.getRankRangeList()) {
349 timeAnalysisEntry.setLastRank(range.getFirstRank());
350 updateTraceEntry(timeAnalysisEntry, range.getLastRank() + 1, event.getTime(), event.getTime() + event.getDuration());
351 }
352 }
353 event.setItemizedEntry(timeAnalysisEntry);
354 redrawViewer(false);
355 itemizeTraceEntry(timeAnalysisEntry);
356 synchronized (event) {
357 event.setItemizing(false);
358 }
359 }
360 }
361
362 private void redecorate() {
363 synchronized (fDecorateThreads) {
364 for (DecorateThread thread : fDecorateThreads) {
365 thread.cancel();
366 }
367 fDecorateThreads.clear();
368 for (int i = 0; i < fTimeAnalysisEntries.size(); i++) {
369 DecorateThread thread = new DecorateThread(fTimeAnalysisEntries.get(i));
370 thread.start();
371 fDecorateThreads.add(thread);
372 }
373 }
374 }
375
376 private class DecorateThread extends Thread {
377 private volatile boolean interrupted = false;
378 private final TimeChartAnalysisEntry fTimeAnalysisEntry;
379 private final TimeChartDecorationProvider fDecorationProvider;
380 private ITmfContext fContext;
381 private int fCount = 0;
382
383 private DecorateThread(TimeChartAnalysisEntry timeAnalysisEntry) {
384 super("Decorate Thread:" + timeAnalysisEntry.getName()); //$NON-NLS-1$
385 fTimeAnalysisEntry = timeAnalysisEntry;
386 fDecorationProvider = fDecorationProviders.get(timeAnalysisEntry.getTrace());
387 }
388
389 @Override
390 public void run() {
391 resetTraceEntry(fTimeAnalysisEntry);
392 redrawViewer(false);
393 decorateTraceEntry(fTimeAnalysisEntry, null);
394 redrawViewer(false);
395 synchronized (fDecorateThreads) {
396 fDecorateThreads.remove(this);
397 }
398 if (fContext != null) {
399 fContext.dispose();
400 }
401 }
402
403 public void resetTraceEntry(TimeChartAnalysisEntry timeAnalysisEntry) {
404 Iterator<ITimeEvent> iterator = timeAnalysisEntry.getTimeEventsIterator();
405 TimeChartEvent event = null;
406 boolean hasNext = true;
407 while (!interrupted && hasNext) {
408 synchronized (timeAnalysisEntry) {
409 while ((hasNext = iterator.hasNext()) == true) {
410 event = (TimeChartEvent) iterator.next();
411 break;
412 }
413 }
414 if (hasNext && event != null) {
415 // TODO possible concurrency problem here with ItemizeJob
416 event.setColorSettingPriority(ColorSettingsManager.PRIORITY_NONE);
417 if (event.getItemizedEntry() != null) {
418 resetTraceEntry(event.getItemizedEntry());
419 }
420 }
421 }
422 }
423
424 public void decorateTraceEntry(TimeChartAnalysisEntry timeAnalysisEntry, TimeChartEvent parentEvent) {
425 // Set max duration high to ensure iterator does not consider
426 // itemized events
427 Iterator<ITimeEvent> iterator = timeAnalysisEntry.getTimeEventsIterator(0, Long.MAX_VALUE, Long.MAX_VALUE);
428 TimeChartEvent event = null;
429 int entryPriority = ColorSettingsManager.PRIORITY_NONE;
430 boolean entryIsBookmarked = false;
431 boolean entryIsVisible = false;
432 boolean entryIsSearchMatch = false;
433 boolean hasNext = true;
434 while (!interrupted && hasNext) {
435 synchronized (timeAnalysisEntry) {
436 while ((hasNext = iterator.hasNext()) == true) {
437 event = (TimeChartEvent) iterator.next();
438 break;
439 }
440 }
441 if (hasNext && event != null) {
442 // TODO possible concurrency problem here with ItemizeJob
443 if (event.getItemizedEntry() == null) {
444 decorateEvent(event);
445 } else {
446 decorateTraceEntry(event.getItemizedEntry(), event);
447 }
448 entryPriority = Math.min(entryPriority, event.getColorSettingPriority());
449 entryIsBookmarked |= event.isBookmarked();
450 entryIsVisible |= event.isVisible();
451 entryIsSearchMatch |= event.isSearchMatch();
452 if (++fCount % timeAnalysisEntry.getTrace().getCacheSize() == 0) {
453 redrawViewer(false);
454 }
455 }
456 }
457 if (parentEvent != null) {
458 parentEvent.setColorSettingPriority(entryPriority);
459 parentEvent.setIsBookmarked(entryIsBookmarked);
460 parentEvent.setIsVisible(entryIsVisible);
461 parentEvent.setIsSearchMatch(entryIsSearchMatch);
462 }
463 }
464
465 public void decorateEvent(TimeChartEvent timeChartEvent) {
466 // TODO possible concurrency problem here with ItemizeJob
467 TimeChartAnalysisEntry timeAnalysisEntry = (TimeChartAnalysisEntry) timeChartEvent.getEntry();
468 ITmfTrace trace = timeAnalysisEntry.getTrace();
469 int priority = ColorSettingsManager.PRIORITY_NONE;
470 boolean isBookmarked = false;
471 boolean isVisible = false;
472 boolean isSearchMatch = false;
473 synchronized (timeChartEvent.getRankRangeList()) {
474 for (RankRange range : timeChartEvent.getRankRangeList()) {
475 if (interrupted) {
476 return;
477 }
478 if (fContext == null || fContext.getRank() != range.getFirstRank()) {
479 if (fContext != null) {
480 fContext.dispose();
481 }
482 fContext = trace.seekEvent(range.getFirstRank());
483 fContext.setRank(range.getFirstRank());
484 }
485 while (true) {
486 if (interrupted) {
487 return;
488 }
489 long rank = fContext.getRank();
490 ITmfEvent event = trace.getNext(fContext);
491 if (event == null) {
492 break;
493 }
494 long eventTime = event.getTimestamp().toNanos();
495 if (eventTime >= timeChartEvent.getTime() && eventTime <= timeChartEvent.getTime() + timeChartEvent.getDuration()) {
496 priority = Math.min(priority, ColorSettingsManager.getColorSettingPriority(event));
497 }
498 isBookmarked |= fDecorationProvider.isBookmark(rank);
499 isVisible |= fDecorationProvider.isVisible(event);
500 isSearchMatch |= fDecorationProvider.isSearchMatch(event);
501 if (fContext.getRank() > range.getLastRank()) {
502 break;
503 }
504 }
505 }
506 }
507 timeChartEvent.setColorSettingPriority(priority);
508 timeChartEvent.setIsBookmarked(isBookmarked);
509 timeChartEvent.setIsVisible(isVisible);
510 timeChartEvent.setIsSearchMatch(isSearchMatch);
511 }
512
513 public void cancel() {
514 interrupted = true;
515 }
516 }
517
518 // ------------------------------------------------------------------------
519 // Listeners
520 // ------------------------------------------------------------------------
521
522 @Override
523 public void timeRangeUpdated(TimeGraphRangeUpdateEvent event) {
524 fStartTime = event.getStartTime();
525 fStopTime = event.getEndTime();
526 itemize(fStartTime, fStopTime);
527 final ITmfTimestamp startTimestamp = TmfTimestamp.fromNanos(event.getStartTime());
528 final ITmfTimestamp endTimestamp = TmfTimestamp.fromNanos(event.getEndTime());
529 TmfTimeRange range = new TmfTimeRange(startTimestamp, endTimestamp);
530 broadcast(new TmfWindowRangeUpdatedSignal(this, range));
531 }
532
533 @Override
534 public void selectionChanged(TimeGraphSelectionEvent event) {
535 ITimeGraphEntry timeAnalysisEntry = null;
536 if (event.getSelection() instanceof TimeChartAnalysisEntry) {
537 timeAnalysisEntry = event.getSelection();
538 } else if (event.getSelection() instanceof TimeChartEvent) {
539 timeAnalysisEntry = ((TimeChartEvent) event.getSelection()).getEntry();
540 }
541 if (timeAnalysisEntry instanceof TimeChartAnalysisEntry) {
542 broadcast(new TmfTraceSelectedSignal(this, ((TimeChartAnalysisEntry) timeAnalysisEntry).getTrace()));
543 }
544 }
545
546 @Override
547 public void timeSelected(TimeGraphTimeEvent event) {
548 broadcast(new TmfSelectionRangeUpdatedSignal(this, TmfTimestamp.fromNanos(event.getBeginTime()), TmfTimestamp.fromNanos(event.getEndTime())));
549 }
550
551 @Override
552 public void colorSettingsChanged(ColorSetting[] colorSettings) {
553 // Set presentation provider again to trigger re-creation of new color
554 // settings which are stored in the TimeGraphControl class
555 fViewer.setTimeGraphProvider(fPresentationProvider);
556 redecorate();
557 }
558
559 @Override
560 public void resourceChanged(IResourceChangeEvent event) {
561 for (IMarkerDelta delta : event.findMarkerDeltas(IMarker.BOOKMARK, false)) {
562 for (TimeChartDecorationProvider provider : fDecorationProviders.values()) {
563 if (delta.getResource().equals(provider.getBookmarksFile())) {
564 if (delta.getKind() == IResourceDelta.CHANGED && delta.getMarker().getAttribute(IMarker.LOCATION, -1) != -1) {
565 provider.refreshBookmarks();
566 } else if (delta.getKind() == IResourceDelta.REMOVED) {
567 provider.refreshBookmarks();
568 }
569 }
570 }
571 }
572 redecorate();
573 }
574
575 // ------------------------------------------------------------------------
576 // Signal handlers
577 // ------------------------------------------------------------------------
578
579 /**
580 * Handler for the Trace Opened signal
581 *
582 * @param signal
583 * The incoming signal
584 */
585 @TmfSignalHandler
586 public void traceOpened(TmfTraceOpenedSignal signal) {
587 final ITmfTrace trace = signal.getTrace();
588 final IFile bookmarksFile = signal.getEditorFile();
589 TimeChartAnalysisEntry timeAnalysisEntry = null;
590 for (int i = 0; i < fTimeAnalysisEntries.size(); i++) {
591 if (fTimeAnalysisEntries.get(i).getTrace().equals(trace)) {
592 timeAnalysisEntry = fTimeAnalysisEntries.get(i);
593 break;
594 }
595 }
596 if (timeAnalysisEntry == null) {
597 timeAnalysisEntry = new TimeChartAnalysisEntry(trace, fDisplayWidth * 2);
598 fTimeAnalysisEntries.add(timeAnalysisEntry);
599 fDecorationProviders.put(trace, new TimeChartDecorationProvider(bookmarksFile));
600 Thread thread = new ProcessTraceThread(timeAnalysisEntry);
601 thread.start();
602 }
603 refreshViewer();
604 }
605
606 /**
607 * Handler for the Trace Closed signal
608 *
609 * @param signal
610 * The incoming signal
611 */
612 @TmfSignalHandler
613 public void traceClosed(TmfTraceClosedSignal signal) {
614 final ITmfTrace trace = signal.getTrace();
615 for (int i = 0; i < fTimeAnalysisEntries.size(); i++) {
616 if (fTimeAnalysisEntries.get(i).getTrace().equals(trace)) {
617 fTimeAnalysisEntries.remove(i);
618 fDecorationProviders.remove(trace);
619 synchronized (fDecorateThreads) {
620 for (DecorateThread thread : fDecorateThreads) {
621 if (thread.fTimeAnalysisEntry.getTrace() == trace) {
622 thread.cancel();
623 fDecorateThreads.remove(thread);
624 break;
625 }
626 }
627 }
628 refreshViewer();
629 break;
630 }
631 }
632 }
633
634 /**
635 * Handler for the Trace Selected signal
636 *
637 * @param signal
638 * The incoming signal
639 */
640 @TmfSignalHandler
641 public void traceSelected(TmfTraceSelectedSignal signal) {
642 if (signal.getSource() != this) {
643 ITmfTrace trace = signal.getTrace();
644 for (int i = 0; i < fTimeAnalysisEntries.size(); i++) {
645 if (fTimeAnalysisEntries.get(i).getTrace().equals(trace)) {
646 fViewer.setSelection(fTimeAnalysisEntries.get(i));
647 break;
648 }
649 }
650 TmfTraceContext ctx = TmfTraceManager.getInstance().getCurrentTraceContext();
651 long beginTime = ctx.getSelectionRange().getStartTime().toNanos();
652 long endTime = ctx.getSelectionRange().getEndTime().toNanos();
653 fViewer.setSelectionRange(beginTime, endTime, false);
654 }
655 }
656
657 /**
658 * Handler for the Trace Updated signal
659 *
660 * @param signal
661 * The incoming signal
662 */
663 @TmfSignalHandler
664 public void traceUpdated(TmfTraceUpdatedSignal signal) {
665 final ITmfTrace trace = signal.getTrace();
666 for (int i = 0; i < fTimeAnalysisEntries.size(); i++) {
667 TimeChartAnalysisEntry timeAnalysisEntry = fTimeAnalysisEntries.get(i);
668 if (timeAnalysisEntry.getTrace().equals(trace)) {
669 updateTraceEntry(timeAnalysisEntry, Long.MAX_VALUE, 0, Long.MAX_VALUE);
670 break;
671 }
672 }
673 }
674
675 /**
676 * Handler for the selection range updated signal.
677 *
678 * @param signal
679 * The incoming signal
680 * @since 1.0
681 */
682 @TmfSignalHandler
683 public void selectionRangeUpdated(TmfSelectionRangeUpdatedSignal signal) {
684 final long beginTime = signal.getBeginTime().toNanos();
685 final long endTime = signal.getEndTime().toNanos();
686
687 Display.getDefault().asyncExec(new Runnable() {
688 @Override
689 public void run() {
690 if (beginTime == endTime) {
691 fViewer.setSelectedTime(beginTime, true);
692 if (fStartTime != fViewer.getTime0() || fStopTime != fViewer.getTime1()) {
693 fStartTime = fViewer.getTime0();
694 fStopTime = fViewer.getTime1();
695 itemize(fStartTime, fStopTime);
696 }
697 } else {
698 fViewer.setSelectionRange(beginTime, endTime, true);
699 }
700 }
701 });
702 }
703
704 /**
705 * Handler for the window range updated signal.
706 *
707 * @param signal
708 * The incoming signal
709 * @since 1.0
710 */
711 @TmfSignalHandler
712 public void windowRangeUpdated(final TmfWindowRangeUpdatedSignal signal) {
713 if (signal.getSource() == this) {
714 return;
715 }
716 final long startTime = signal.getCurrentRange().getStartTime().toNanos();
717 final long endTime = signal.getCurrentRange().getEndTime().toNanos();
718 Display.getDefault().asyncExec(new Runnable() {
719 @Override
720 public void run() {
721 fStartTime = startTime;
722 fStopTime = endTime;
723 itemize(fStartTime, fStopTime);
724 fViewer.setStartFinishTime(startTime, endTime);
725 }
726 });
727 }
728
729 /**
730 * Handler for the Event Filter Applied signal
731 *
732 * @param signal
733 * The incoming signal
734 */
735 @TmfSignalHandler
736 public void filterApplied(TmfEventFilterAppliedSignal signal) {
737 TimeChartDecorationProvider decorationProvider = fDecorationProviders.get(signal.getTrace());
738 if (decorationProvider == null) {
739 return;
740 }
741 decorationProvider.filterApplied(signal.getEventFilter());
742 redecorate();
743 }
744
745 /**
746 * Handler for the Event Search Applied signal
747 *
748 * @param signal
749 * The incoming signal
750 */
751 @TmfSignalHandler
752 public void searchApplied(TmfEventSearchAppliedSignal signal) {
753 TimeChartDecorationProvider decorationProvider = fDecorationProviders.get(signal.getTrace());
754 if (decorationProvider == null) {
755 return;
756 }
757 decorationProvider.searchApplied(signal.getSearchFilter());
758 redecorate();
759 }
760
761 /**
762 * @since 1.0
763 */
764 @Override
765 public TmfTimeViewAlignmentInfo getTimeViewAlignmentInfo() {
766 if (fViewer == null) {
767 return null;
768 }
769 return fViewer.getTimeViewAlignmentInfo();
770 }
771
772 /**
773 * @since 1.0
774 */
775 @Override
776 public int getAvailableWidth(int requestedOffset) {
777 return fViewer.getAvailableWidth(requestedOffset);
778 }
779
780 /**
781 * @since 1.0
782 */
783 @Override
784 public void performAlign(int offset, int width) {
785 fViewer.performAlign(offset, width);
786 }
787 }
This page took 0.048451 seconds and 4 git commands to generate.