tmf: Switch tmf.core.tests to Java 7 + fix warnings
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / views / callstack / CallStackView.java
CommitLineData
e8251298
PT
1/*******************************************************************************
2 * Copyright (c) 2013 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
fec1ac0b 11 * Bernd Hufmann - Updated signal handling
e8251298
PT
12 *******************************************************************************/
13
14package org.eclipse.linuxtools.tmf.ui.views.callstack;
15
5da83da5 16import java.io.File;
e8251298
PT
17import java.util.ArrayList;
18import java.util.HashMap;
19import java.util.Iterator;
20import java.util.List;
52974e38 21import java.util.Map;
e8251298
PT
22
23import org.eclipse.core.runtime.IProgressMonitor;
5da83da5 24import org.eclipse.core.runtime.IStatus;
e8251298 25import org.eclipse.core.runtime.NullProgressMonitor;
5da83da5
AM
26import org.eclipse.core.runtime.Status;
27import org.eclipse.core.runtime.jobs.Job;
e8251298
PT
28import org.eclipse.jface.action.Action;
29import org.eclipse.jface.action.IAction;
0fcf3b09 30import org.eclipse.jface.action.IStatusLineManager;
e8251298
PT
31import org.eclipse.jface.action.IToolBarManager;
32import org.eclipse.jface.action.Separator;
33import org.eclipse.jface.util.IPropertyChangeListener;
34import org.eclipse.jface.util.PropertyChangeEvent;
35import org.eclipse.jface.viewers.DoubleClickEvent;
36import org.eclipse.jface.viewers.IDoubleClickListener;
37import org.eclipse.jface.viewers.ILabelProviderListener;
38import org.eclipse.jface.viewers.ISelection;
39import org.eclipse.jface.viewers.IStructuredSelection;
40import org.eclipse.jface.viewers.ITableLabelProvider;
41import org.eclipse.jface.viewers.ITreeContentProvider;
42import org.eclipse.jface.viewers.Viewer;
43import org.eclipse.linuxtools.internal.tmf.ui.Activator;
44import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants;
45import org.eclipse.linuxtools.internal.tmf.ui.Messages;
46import org.eclipse.linuxtools.tmf.core.callstack.CallStackStateProvider;
e8251298
PT
47import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
48import org.eclipse.linuxtools.tmf.core.exceptions.StateSystemDisposedException;
49import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
50import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
51import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval;
52import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;
53import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
54import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;
55import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal;
fec1ac0b 56import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal;
e8251298
PT
57import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal;
58import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
59import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
60import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue.Type;
61import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
f566d40a 62import org.eclipse.linuxtools.tmf.core.timestamp.TmfNanoTimestamp;
e8251298
PT
63import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
64import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
65import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampDelta;
66import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
67import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment;
68import org.eclipse.linuxtools.tmf.ui.editors.ITmfTraceEditor;
69import org.eclipse.linuxtools.tmf.ui.views.TmfView;
70import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphRangeListener;
71import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphTimeListener;
72import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphCombo;
73import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEvent;
74import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTimeEvent;
75import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphViewer;
76import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent;
77import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
78import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.NullTimeEvent;
79import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeEvent;
80import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
81import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphSelection;
82import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
83import org.eclipse.swt.SWT;
84import org.eclipse.swt.events.ControlAdapter;
85import org.eclipse.swt.events.ControlEvent;
86import org.eclipse.swt.events.MouseAdapter;
87import org.eclipse.swt.events.MouseEvent;
88import org.eclipse.swt.graphics.Image;
89import org.eclipse.swt.widgets.Composite;
90import org.eclipse.swt.widgets.Display;
5da83da5 91import org.eclipse.swt.widgets.FileDialog;
e8251298
PT
92import org.eclipse.ui.IActionBars;
93import org.eclipse.ui.IEditorPart;
94
95/**
96 * Main implementation for the Call Stack view
97 *
98 * @author Patrick Tasse
99 * @since 2.0
100 */
101public class CallStackView extends TmfView {
102
103 // ------------------------------------------------------------------------
104 // Constants
105 // ------------------------------------------------------------------------
106
107 /** View ID. */
108 public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.callstack"; //$NON-NLS-1$
109
110 /**
111 * Redraw state enum
112 */
113 private enum State { IDLE, BUSY, PENDING }
114
52974e38 115 private static final String[] COLUMN_NAMES = new String[] {
e8251298
PT
116 Messages.CallStackView_FunctionColumn,
117 Messages.CallStackView_DepthColumn,
118 Messages.CallStackView_EntryTimeColumn,
119 Messages.CallStackView_ExitTimeColumn,
120 Messages.CallStackView_DurationColumn
121 };
122
52974e38
PT
123 private static final int[] COLUMN_WIDTHS = new int[] {
124 200,
125 50,
126 120,
127 120,
128 120
129 };
130
131 // Fraction of a function duration to be added as spacing
132 private static final double SPACING_RATIO = 0.01;
133
e8251298
PT
134 private static final Image THREAD_IMAGE = Activator.getDefault().getImageFromPath("icons/obj16/thread_obj.gif"); //$NON-NLS-1$
135 private static final Image STACKFRAME_IMAGE = Activator.getDefault().getImageFromPath("icons/obj16/stckframe_obj.gif"); //$NON-NLS-1$
136
5da83da5
AM
137 private static final String IMPORT_MAPPING_ICON_PATH = "icons/etool16/import.gif"; //$NON-NLS-1$
138
e8251298
PT
139 // ------------------------------------------------------------------------
140 // Fields
141 // ------------------------------------------------------------------------
142
143 // The time graph combo
52974e38 144 private TimeGraphCombo fTimeGraphCombo;
e8251298
PT
145
146 // The selected trace
147 private ITmfTrace fTrace;
148
149 // The selected thread map
52974e38 150 private final Map<ITmfTrace, String> fSelectedThreadMap = new HashMap<ITmfTrace, String>();
e8251298
PT
151
152 // The time graph entry list
52974e38 153 private List<ThreadEntry> fEntryList;
e8251298
PT
154
155 // The trace to entry list hash map
52974e38 156 private final Map<ITmfTrace, ArrayList<ThreadEntry>> fEntryListMap = new HashMap<ITmfTrace, ArrayList<ThreadEntry>>();
e8251298
PT
157
158 // The trace to build thread hash map
52974e38 159 private final Map<ITmfTrace, BuildThread> fBuildThreadMap = new HashMap<ITmfTrace, BuildThread>();
e8251298 160
5da83da5
AM
161 /** The map to map function addresses to function names */
162 private Map<String, String> fNameMapping;
163
e8251298
PT
164 // The start time
165 private long fStartTime;
166
167 // The end time
168 private long fEndTime;
169
170 // The display width
171 private int fDisplayWidth;
172
173 // The next event action
174 private Action fNextEventAction;
175
176 // The previous event action
177 private Action fPrevEventAction;
178
179 // The next item action
180 private Action fNextItemAction;
181
182 // The previous item action
183 private Action fPreviousItemAction;
184
5da83da5
AM
185 /** The action to import a function-name mapping file */
186 private Action fImportMappingAction;
187
e8251298
PT
188 // The zoom thread
189 private ZoomThread fZoomThread;
190
191 // The redraw state used to prevent unnecessary queuing of display runnables
192 private State fRedrawState = State.IDLE;
193
194 // The redraw synchronization object
52974e38 195 private final Object fSyncObj = new Object();
e8251298
PT
196
197 // The saved time sync. signal used when switching off the pinning of a view
198 private TmfTimeSynchSignal fSavedTimeSyncSignal;
199
200 // The saved time range sync. signal used when switching off the pinning of a view
201 private TmfRangeSynchSignal fSavedRangeSyncSignal;
202
203 // ------------------------------------------------------------------------
204 // Classes
205 // ------------------------------------------------------------------------
206
207 private class ThreadEntry implements ITimeGraphEntry {
208 // The Trace
209 private final ITmfTrace fThreadTrace;
210 // The start time
211 private final long fTraceStartTime;
212 // The end time
213 private final long fTraceEndTime;
214 // The children of the entry
215 private ArrayList<CallStackEntry> fChildren;
216 // The name of entry
217 private final String fName;
218 // The thread attribute quark
219 private final int fThreadQuark;
220
221 public ThreadEntry(ITmfTrace trace, String name, int threadQuark, long startTime, long endTime) {
222 fThreadTrace = trace;
223 fChildren = new ArrayList<CallStackEntry>();
224 fName = name;
225 fTraceStartTime = startTime;
226 fTraceEndTime = endTime;
227 fThreadQuark = threadQuark;
228 }
229
230 @Override
231 public ITimeGraphEntry getParent() {
232 return null;
233 }
234
235 @Override
236 public boolean hasChildren() {
237 if (fChildren == null) {
238 ITmfStateSystem ss = fThreadTrace.getStateSystems().get(CallStackStateProvider.ID);
239 try {
240 int eventStackQuark = ss.getQuarkRelative(fThreadQuark, CallStackStateProvider.CALL_STACK);
241 ITmfStateInterval eventStackInterval = ss.querySingleState(ss.getStartTime(), eventStackQuark);
242 return ! eventStackInterval.getStateValue().isNull() || eventStackInterval.getEndTime() != ss.getCurrentEndTime();
243 } catch (AttributeNotFoundException e) {
52974e38 244 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 245 } catch (TimeRangeException e) {
52974e38 246 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298
PT
247 } catch (StateSystemDisposedException e) {
248 /* Ignored */
249 }
250 }
251 return fChildren != null && fChildren.size() > 0;
252 }
253
254 @Override
255 public List<CallStackEntry> getChildren() {
256 return fChildren;
257 }
258
259 @Override
260 public String getName() {
261 return fName;
262 }
263
264 @Override
265 public long getStartTime() {
266 return fTraceStartTime;
267 }
268
269 @Override
270 public long getEndTime() {
271 return fTraceEndTime;
272 }
273
274 @Override
275 public boolean hasTimeEvents() {
276 return false;
277 }
278
279 @Override
280 public Iterator<ITimeEvent> getTimeEventsIterator() {
281 return null;
282 }
283
284 @Override
285 public <T extends ITimeEvent> Iterator<T> getTimeEventsIterator(long startTime, long stopTime, long visibleDuration) {
286 return null;
287 }
288
289 public int getThreadQuark() {
290 return fThreadQuark;
291 }
292
293 public ITmfTrace getTrace() {
294 return fThreadTrace;
295 }
296
297 public void addChild(CallStackEntry entry) {
298 entry.setParent(this);
299 fChildren.add(entry);
300 }
301 }
302
303 private class TreeContentProvider implements ITreeContentProvider {
304
305 @Override
306 public void dispose() {
307 }
308
309 @Override
310 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
311 }
312
313 @Override
314 public Object[] getElements(Object inputElement) {
315 return (ITimeGraphEntry[]) inputElement;
316 }
317
318 @Override
319 public Object[] getChildren(Object parentElement) {
320 ITimeGraphEntry entry = (ITimeGraphEntry) parentElement;
321 return entry.getChildren().toArray();
322 }
323
324 @Override
325 public Object getParent(Object element) {
326 ITimeGraphEntry entry = (ITimeGraphEntry) element;
327 return entry.getParent();
328 }
329
330 @Override
331 public boolean hasChildren(Object element) {
332 ITimeGraphEntry entry = (ITimeGraphEntry) element;
333 return entry.hasChildren();
334 }
335
336 }
337
338 private class TreeLabelProvider implements ITableLabelProvider {
339
340 @Override
341 public void addListener(ILabelProviderListener listener) {
342 }
343
344 @Override
345 public void dispose() {
346 }
347
348 @Override
349 public boolean isLabelProperty(Object element, String property) {
350 return false;
351 }
352
353 @Override
354 public void removeListener(ILabelProviderListener listener) {
355 }
356
357 @Override
358 public Image getColumnImage(Object element, int columnIndex) {
359 if (columnIndex == 0) {
360 if (element instanceof ThreadEntry) {
361 return THREAD_IMAGE;
362 } else if (element instanceof CallStackEntry) {
363 CallStackEntry entry = (CallStackEntry) element;
364 if (entry.getFunctionName().length() > 0) {
365 return STACKFRAME_IMAGE;
366 }
367 }
368 }
369 return null;
370 }
371
372 @Override
373 public String getColumnText(Object element, int columnIndex) {
374 if (element instanceof ThreadEntry) {
375 if (columnIndex == 0) {
376 return ((ThreadEntry) element).getName();
377 }
378 } else if (element instanceof CallStackEntry) {
379 CallStackEntry entry = (CallStackEntry) element;
380 if (columnIndex == 0) {
381 return entry.getFunctionName();
52974e38
PT
382 } else if (columnIndex == 1 && entry.getFunctionName().length() > 0) {
383 int depth = entry.getStackLevel();
384 return Integer.toString(depth);
385 } else if (columnIndex == 2 && entry.getFunctionName().length() > 0) {
386 ITmfTimestamp ts = new TmfTimestamp(entry.getStartTime(), ITmfTimestamp.NANOSECOND_SCALE);
387 return ts.toString();
388 } else if (columnIndex == 3 && entry.getFunctionName().length() > 0) {
389 ITmfTimestamp ts = new TmfTimestamp(entry.getEndTime(), ITmfTimestamp.NANOSECOND_SCALE);
390 return ts.toString();
391 } else if (columnIndex == 4 && entry.getFunctionName().length() > 0) {
392 ITmfTimestamp ts = new TmfTimestampDelta(entry.getEndTime() - entry.getStartTime(), ITmfTimestamp.NANOSECOND_SCALE);
393 return ts.toString();
e8251298
PT
394 }
395 }
396 return ""; //$NON-NLS-1$
397 }
398
399 }
400
401 private class BuildThread extends Thread {
402 private final ITmfTrace fBuildTrace;
403 private final IProgressMonitor fMonitor;
404
405 public BuildThread(ITmfTrace trace) {
406 super("CallStackView build"); //$NON-NLS-1$
407 fBuildTrace = trace;
408 fMonitor = new NullProgressMonitor();
409 }
410
411 @Override
412 public void run() {
413 buildThreadList(fBuildTrace, fMonitor);
414 synchronized (fBuildThreadMap) {
415 fBuildThreadMap.remove(this);
416 }
417 }
418
419 public void cancel() {
420 fMonitor.setCanceled(true);
421 }
422 }
423
424 private class ZoomThread extends Thread {
52974e38 425 private final List<ThreadEntry> fZoomEntryList;
e8251298
PT
426 private final long fZoomStartTime;
427 private final long fZoomEndTime;
428 private final IProgressMonitor fMonitor;
429
52974e38 430 public ZoomThread(List<ThreadEntry> entryList, long startTime, long endTime) {
e8251298
PT
431 super("ResourcesView zoom"); //$NON-NLS-1$
432 fZoomEntryList = entryList;
433 fZoomStartTime = startTime;
434 fZoomEndTime = endTime;
435 fMonitor = new NullProgressMonitor();
436 }
437
438 @Override
439 public void run() {
440 if (fZoomEntryList == null) {
441 return;
442 }
443 long resolution = Math.max(1, (fZoomEndTime - fZoomStartTime) / fDisplayWidth);
444 for (ThreadEntry threadEntry : fZoomEntryList) {
445 ITmfStateSystem ss = threadEntry.fThreadTrace.getStateSystems().get(CallStackStateProvider.ID);
446 if (ss == null || !ss.waitUntilBuilt()) {
447 continue;
448 }
449 for (ITimeGraphEntry child : threadEntry.getChildren()) {
450 if (fMonitor.isCanceled()) {
451 break;
452 }
453 CallStackEntry entry = (CallStackEntry) child;
454 if (fZoomStartTime <= fStartTime && fZoomEndTime >= fEndTime) {
455 entry.setZoomedEventList(null);
456 } else {
457 List<ITimeEvent> zoomedEventList = getEventList(entry, fZoomStartTime, fZoomEndTime, resolution, fMonitor);
458 if (zoomedEventList != null) {
459 entry.setZoomedEventList(zoomedEventList);
460 }
461 }
462 redraw();
463 }
464 }
465 }
466
467 public void cancel() {
468 fMonitor.setCanceled(true);
469 }
470 }
471
472 // ------------------------------------------------------------------------
473 // Constructors
474 // ------------------------------------------------------------------------
475
476 /**
477 * Default constructor
478 */
479 public CallStackView() {
480 super(ID);
481 fDisplayWidth = Display.getDefault().getBounds().width;
482 }
483
484 // ------------------------------------------------------------------------
485 // ViewPart
486 // ------------------------------------------------------------------------
487
488 @Override
489 public void createPartControl(Composite parent) {
490 fTimeGraphCombo = new TimeGraphCombo(parent, SWT.NONE);
491
492 fTimeGraphCombo.setTreeContentProvider(new TreeContentProvider());
493
494 fTimeGraphCombo.setTreeLabelProvider(new TreeLabelProvider());
495
496 fTimeGraphCombo.setTreeColumns(COLUMN_NAMES);
497
52974e38
PT
498 fTimeGraphCombo.getTreeViewer().getTree().getColumn(0).setWidth(COLUMN_WIDTHS[0]);
499 fTimeGraphCombo.getTreeViewer().getTree().getColumn(1).setWidth(COLUMN_WIDTHS[1]);
500 fTimeGraphCombo.getTreeViewer().getTree().getColumn(2).setWidth(COLUMN_WIDTHS[2]);
501 fTimeGraphCombo.getTreeViewer().getTree().getColumn(3).setWidth(COLUMN_WIDTHS[3]);
502 fTimeGraphCombo.getTreeViewer().getTree().getColumn(4).setWidth(COLUMN_WIDTHS[4]);
e8251298 503
5da83da5 504 fTimeGraphCombo.setTimeGraphProvider(new CallStackPresentationProvider(this));
e8251298
PT
505 fTimeGraphCombo.getTimeGraphViewer().setTimeFormat(TimeFormat.CALENDAR);
506
507 fTimeGraphCombo.getTimeGraphViewer().addRangeListener(new ITimeGraphRangeListener() {
508 @Override
509 public void timeRangeUpdated(TimeGraphRangeUpdateEvent event) {
510 long startTime = event.getStartTime();
511 long endTime = event.getEndTime();
f566d40a 512 TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(startTime), new TmfNanoTimestamp(endTime));
0fcf3b09 513 broadcast(new TmfRangeSynchSignal(CallStackView.this, range));
e8251298
PT
514 startZoomThread(startTime, endTime);
515 }
516 });
517
518 fTimeGraphCombo.getTimeGraphViewer().addTimeListener(new ITimeGraphTimeListener() {
519 @Override
520 public void timeSelected(TimeGraphTimeEvent event) {
0fcf3b09
PT
521 long beginTime = event.getBeginTime();
522 long endTime = event.getEndTime();
523 selectTime(beginTime);
f566d40a 524 broadcast(new TmfTimeSynchSignal(CallStackView.this, new TmfNanoTimestamp(beginTime), new TmfNanoTimestamp(endTime)));
e8251298
PT
525 }
526 });
527
528 fTimeGraphCombo.getTimeGraphViewer().getControl().addControlListener(new ControlAdapter() {
529 @Override
530 public void controlResized(ControlEvent e) {
531 fDisplayWidth = fTimeGraphCombo.getTimeGraphViewer().getControl().getSize().x;
532 if (fEntryList != null) {
533 startZoomThread(fTimeGraphCombo.getTimeGraphViewer().getTime0(), fTimeGraphCombo.getTimeGraphViewer().getTime1());
534 }
535 }
536 });
537
538 fTimeGraphCombo.getTreeViewer().addDoubleClickListener(new IDoubleClickListener() {
539 @Override
540 public void doubleClick(DoubleClickEvent event) {
541 Object selection = ((IStructuredSelection) event.getSelection()).getFirstElement();
542 if (selection instanceof CallStackEntry) {
543 CallStackEntry entry = (CallStackEntry) selection;
544 if (entry.getFunctionName().length() > 0) {
545 long startTime = entry.getStartTime();
546 long endTime = entry.getEndTime();
52974e38 547 long spacingTime = (long) ((endTime - startTime) * SPACING_RATIO);
e8251298
PT
548 startTime -= spacingTime;
549 endTime += spacingTime;
f566d40a 550 TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(startTime), new TmfNanoTimestamp(endTime));
0fcf3b09 551 broadcast(new TmfRangeSynchSignal(CallStackView.this, range));
e8251298
PT
552 fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
553 startZoomThread(startTime, endTime);
554 }
555 }
556 }
557 });
558
559 fTimeGraphCombo.getTimeGraphViewer().getTimeGraphControl().addMouseListener(new MouseAdapter() {
560 @Override
561 public void mouseDoubleClick(MouseEvent e) {
562 TimeGraphControl timeGraphControl = fTimeGraphCombo.getTimeGraphViewer().getTimeGraphControl();
563 ISelection selection = timeGraphControl.getSelection();
564 if (selection instanceof TimeGraphSelection) {
565 Object o = ((TimeGraphSelection) selection).getFirstElement();
566 if (o instanceof CallStackEvent) {
567 CallStackEvent event = (CallStackEvent) o;
568 long startTime = event.getTime();
569 long endTime = startTime + event.getDuration();
52974e38 570 long spacingTime = (long) ((endTime - startTime) * SPACING_RATIO);
e8251298
PT
571 startTime -= spacingTime;
572 endTime += spacingTime;
f566d40a 573 TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(startTime), new TmfNanoTimestamp(endTime));
0fcf3b09 574 broadcast(new TmfRangeSynchSignal(CallStackView.this, range));
e8251298
PT
575 fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
576 startZoomThread(startTime, endTime);
577 }
578 }
579 }
580 });
581
0fcf3b09
PT
582 IStatusLineManager statusLineManager = getViewSite().getActionBars().getStatusLineManager();
583 fTimeGraphCombo.getTimeGraphViewer().getTimeGraphControl().setStatusLineManager(statusLineManager);
584
e8251298
PT
585 // View Action Handling
586 makeActions();
587 contributeToActionBars();
588
589 IEditorPart editor = getSite().getPage().getActiveEditor();
590 if (editor instanceof ITmfTraceEditor) {
591 ITmfTrace trace = ((ITmfTraceEditor) editor).getTrace();
592 if (trace != null) {
593 traceSelected(new TmfTraceSelectedSignal(this, trace));
594 }
595 }
596 }
597
598 @Override
599 public void setFocus() {
600 fTimeGraphCombo.setFocus();
601 }
602
603 // ------------------------------------------------------------------------
604 // Signal handlers
605 // ------------------------------------------------------------------------
fec1ac0b
BH
606 /**
607 * Handler for the trace opened signal.
608 * @param signal
609 * The incoming signal
610 * @since 2.0
611 */
612 @TmfSignalHandler
613 public void traceOpened(TmfTraceOpenedSignal signal) {
614 fTrace = signal.getTrace();
615 loadTrace();
616 }
e8251298
PT
617
618 /**
619 * Handler for the trace selected signal
620 *
621 * @param signal
622 * The incoming signal
623 */
624 @TmfSignalHandler
625 public void traceSelected(final TmfTraceSelectedSignal signal) {
626 if (signal.getTrace() == fTrace) {
627 return;
628 }
629 fTrace = signal.getTrace();
fec1ac0b 630 loadTrace();
e8251298
PT
631 }
632
633 /**
634 * Trace is closed: clear the data structures and the view
635 *
636 * @param signal the signal received
637 */
638 @TmfSignalHandler
639 public void traceClosed(final TmfTraceClosedSignal signal) {
640 synchronized (fBuildThreadMap) {
641 BuildThread buildThread = fBuildThreadMap.remove(signal.getTrace());
642 if (buildThread != null) {
643 buildThread.cancel();
644 }
645 }
646 synchronized (fEntryListMap) {
647 fEntryListMap.remove(signal.getTrace());
648 }
649 fSelectedThreadMap.remove(signal.getTrace());
650 if (signal.getTrace() == fTrace) {
651 fTrace = null;
652 fStartTime = 0;
653 fEndTime = 0;
654 refresh();
655 }
656 }
657
658 /**
659 * Handler for the TimeSynch signal
660 *
661 * @param signal
662 * The incoming signal
663 */
664 @TmfSignalHandler
665 public void synchToTime(final TmfTimeSynchSignal signal) {
666
0fcf3b09 667 fSavedTimeSyncSignal = isPinned() ? new TmfTimeSynchSignal(signal.getSource(), signal.getBeginTime(), signal.getEndTime()) : null;
e8251298
PT
668
669 if (signal.getSource() == this || fTrace == null || isPinned()) {
670 return;
671 }
0fcf3b09
PT
672 final long beginTime = signal.getBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
673 final long endTime = signal.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
e8251298
PT
674 Display.getDefault().asyncExec(new Runnable() {
675 @Override
676 public void run() {
677 if (fTimeGraphCombo.isDisposed()) {
678 return;
679 }
0fcf3b09
PT
680 if (beginTime == endTime) {
681 fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(beginTime, true);
682 } else {
683 fTimeGraphCombo.getTimeGraphViewer().setSelectionRange(beginTime, endTime);
684 }
685 selectTime(beginTime);
e8251298
PT
686 startZoomThread(fTimeGraphCombo.getTimeGraphViewer().getTime0(), fTimeGraphCombo.getTimeGraphViewer().getTime1());
687 if (fEntryList == null) {
688 return;
689 }
690 TimeGraphViewer viewer = fTimeGraphCombo.getTimeGraphViewer();
691 for (ThreadEntry threadEntry : fEntryList) {
692 ITmfStateSystem ss = threadEntry.getTrace().getStateSystems().get(CallStackStateProvider.ID);
0fcf3b09 693 if (ss == null || beginTime < ss.getStartTime() || beginTime > ss.getCurrentEndTime()) {
e8251298
PT
694 continue;
695 }
696 try {
697 int quark = ss.getQuarkRelative(threadEntry.getThreadQuark(), CallStackStateProvider.CALL_STACK);
0fcf3b09
PT
698 ITmfStateInterval stackInterval = ss.querySingleState(beginTime, quark);
699 if (beginTime == stackInterval.getStartTime()) {
e8251298
PT
700 int stackLevel = stackInterval.getStateValue().unboxInt();
701 CallStackEntry selectedEntry = threadEntry.getChildren().get(Math.max(0, stackLevel - 1));
702 fTimeGraphCombo.setSelection(selectedEntry);
703 viewer.getTimeGraphControl().fireSelectionChanged();
704 break;
705 }
706 } catch (AttributeNotFoundException e) {
52974e38 707 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 708 } catch (TimeRangeException e) {
52974e38 709 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 710 } catch (StateSystemDisposedException e) {
52974e38 711 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 712 } catch (StateValueTypeException e) {
52974e38 713 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298
PT
714 }
715 }
716 }
717 });
718 }
719
720 /**
721 * Handler for the RangeSynch signal
722 *
723 * @param signal
724 * The incoming signal
725 */
726 @TmfSignalHandler
727 public void synchToRange(final TmfRangeSynchSignal signal) {
728
729 if (isPinned()) {
730 fSavedRangeSyncSignal =
0fcf3b09 731 new TmfRangeSynchSignal(signal.getSource(), new TmfTimeRange(signal.getCurrentRange().getStartTime(), signal.getCurrentRange().getEndTime()));
e8251298
PT
732
733 fSavedTimeSyncSignal = null;
734 }
735
736 if (signal.getSource() == this || fTrace == null || isPinned()) {
737 return;
738 }
739 if (signal.getCurrentRange().getIntersection(fTrace.getTimeRange()) == null) {
740 return;
741 }
742 final long startTime = signal.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
743 final long endTime = signal.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
e8251298
PT
744 Display.getDefault().asyncExec(new Runnable() {
745 @Override
746 public void run() {
747 if (fTimeGraphCombo.isDisposed()) {
748 return;
749 }
750 fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
e8251298
PT
751 startZoomThread(startTime, endTime);
752 }
753 });
754 }
755
756 // ------------------------------------------------------------------------
757 // Internal
758 // ------------------------------------------------------------------------
5da83da5 759
fec1ac0b
BH
760 private void loadTrace() {
761 synchronized (fEntryListMap) {
762 fEntryList = fEntryListMap.get(fTrace);
763 if (fEntryList == null) {
764 synchronized (fBuildThreadMap) {
765 BuildThread buildThread = new BuildThread(fTrace);
766 fBuildThreadMap.put(fTrace, buildThread);
767 buildThread.start();
768 }
769 } else {
770 fStartTime = fTrace.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
771 fEndTime = fTrace.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
772 refresh();
773 }
774 }
775 }
e8251298
PT
776
777 private void buildThreadList(final ITmfTrace trace, IProgressMonitor monitor) {
778 fStartTime = Long.MAX_VALUE;
779 fEndTime = Long.MIN_VALUE;
780 ITmfTrace[] traces;
781 if (trace instanceof TmfExperiment) {
782 TmfExperiment experiment = (TmfExperiment) trace;
783 traces = experiment.getTraces();
784 } else {
785 traces = new ITmfTrace[] { trace };
786 }
787 ArrayList<ThreadEntry> entryList = new ArrayList<ThreadEntry>();
788 for (ITmfTrace aTrace : traces) {
789 if (monitor.isCanceled()) {
790 return;
791 }
792 ITmfStateSystem ss = aTrace.getStateSystems().get(CallStackStateProvider.ID);
793 if (ss == null || !ss.waitUntilBuilt()) {
794 String threadName = Messages.CallStackView_StackInfoNotAvailable + ' ' + '(' + aTrace.getName() + ')';
795 ThreadEntry threadEntry = new ThreadEntry(aTrace, threadName, -1, 0, 0);
796 entryList.add(threadEntry);
797 continue;
798 }
799 long startTime = ss.getStartTime();
800 long endTime = ss.getCurrentEndTime() + 1;
801 fStartTime = Math.min(fStartTime, startTime);
802 fEndTime = Math.max(fEndTime, endTime);
803 List<Integer> threadQuarks = ss.getQuarks(CallStackStateProvider.THREADS, "*"); //$NON-NLS-1$
804 for (int i = 0; i < threadQuarks.size(); i++) {
805 if (monitor.isCanceled()) {
806 return;
807 }
808 int threadQuark = threadQuarks.get(i);
809 String thread = ss.getAttributeName(threadQuark);
810 String threadEntryName = thread + ' ' + '(' + aTrace.getName() + ')';
811 ThreadEntry threadEntry = new ThreadEntry(aTrace, threadEntryName, threadQuark, startTime, endTime);
812 entryList.add(threadEntry);
813 int eventStackQuark;
814 try {
815 eventStackQuark = ss.getQuarkRelative(threadQuark, CallStackStateProvider.CALL_STACK);
816 int level = 1;
817 for (int stackLevelQuark : ss.getSubAttributes(eventStackQuark, false)) {
818 CallStackEntry callStackEntry = new CallStackEntry(stackLevelQuark, level++, aTrace);
819 threadEntry.addChild(callStackEntry);
820 }
821 } catch (AttributeNotFoundException e) {
52974e38 822 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298
PT
823 }
824 }
825 }
826 synchronized (fEntryListMap) {
2f91d29c 827 fEntryListMap.put(trace, new ArrayList<ThreadEntry>(entryList));
e8251298
PT
828 }
829 if (trace == fTrace) {
830 refresh();
831 }
832 for (ThreadEntry threadEntry : entryList) {
833 for (CallStackEntry callStackEntry : threadEntry.getChildren()) {
834 if (monitor.isCanceled()) {
835 return;
836 }
837 buildStatusEvents(trace, callStackEntry, monitor);
838 }
839 }
840 }
841
842 private void buildStatusEvents(ITmfTrace trace, CallStackEntry entry, IProgressMonitor monitor) {
843 ITmfStateSystem ss = entry.getTrace().getStateSystems().get(CallStackStateProvider.ID);
844 long start = ss.getStartTime();
845 long end = ss.getCurrentEndTime() + 1;
846 long resolution = Math.max(1, (end - start) / fDisplayWidth);
847 List<ITimeEvent> eventList = getEventList(entry, start, end, resolution, monitor);
848 if (monitor.isCanceled()) {
849 return;
850 }
851 entry.setEventList(eventList);
852 if (trace == fTrace) {
853 redraw();
854 }
855 }
856
857 private static List<ITimeEvent> getEventList(CallStackEntry entry,
858 long startTime, long endTime, long resolution,
859 IProgressMonitor monitor) {
860 ITmfStateSystem ss = entry.getTrace().getStateSystems().get(CallStackStateProvider.ID);
861 long start = Math.max(startTime, ss.getStartTime());
862 long end = Math.min(endTime, ss.getCurrentEndTime() + 1);
863 if (end <= start) {
864 return null;
865 }
866 List<ITimeEvent> eventList = null;
867 try {
868 List<ITmfStateInterval> stackIntervals = ss.queryHistoryRange(entry.getQuark(), start, end - 1, resolution, monitor);
869 eventList = new ArrayList<ITimeEvent>(stackIntervals.size());
870 long lastEndTime = -1;
871 boolean lastIsNull = true;
872 for (ITmfStateInterval statusInterval : stackIntervals) {
873 if (monitor.isCanceled()) {
874 return null;
875 }
876 long time = statusInterval.getStartTime();
877 long duration = statusInterval.getEndTime() - time + 1;
878 if (!statusInterval.getStateValue().isNull()) {
52974e38
PT
879 final int modulo = CallStackPresentationProvider.NUM_COLORS / 2;
880 int value = statusInterval.getStateValue().toString().hashCode() % modulo + modulo;
e8251298
PT
881 eventList.add(new CallStackEvent(entry, time, duration, value));
882 lastIsNull = false;
883 } else {
beb1b921
PT
884 if (lastEndTime == -1) {
885 // add null event if it intersects the start time
886 eventList.add(new NullTimeEvent(entry, time, duration));
887 } else {
888 if (lastEndTime != time && lastIsNull) {
889 // add unknown event if between two null states
890 eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime));
891 }
892 if (time + duration >= endTime) {
893 // add null event if it intersects the end time
894 eventList.add(new NullTimeEvent(entry, time, duration));
895 }
e8251298 896 }
e8251298
PT
897 lastIsNull = true;
898 }
899 lastEndTime = time + duration;
900 }
901 } catch (AttributeNotFoundException e) {
52974e38 902 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 903 } catch (TimeRangeException e) {
52974e38 904 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298
PT
905 } catch (StateSystemDisposedException e) {
906 /* Ignored */
907 }
908 return eventList;
909 }
910
911 private void selectTime(long time) {
912 if (fEntryList == null) {
913 return;
914 }
e8251298
PT
915 for (ThreadEntry threadEntry : fEntryList) {
916 ITmfStateSystem ss = threadEntry.fThreadTrace.getStateSystems().get(CallStackStateProvider.ID);
917 if (ss == null || !ss.waitUntilBuilt()) {
918 continue;
919 }
920 long queryTime = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), time));
921 for (CallStackEntry callStackEntry : threadEntry.getChildren()) {
922 try {
923 ITmfStateInterval stackLevelInterval = ss.querySingleState(queryTime, callStackEntry.getQuark());
924 ITmfStateValue nameValue = stackLevelInterval.getStateValue();
925 String name = ""; //$NON-NLS-1$
926 try {
927 if (nameValue.getType() == Type.STRING) {
5da83da5
AM
928 String address = nameValue.unboxStr();
929 name = getFunctionName(address);
e8251298
PT
930 } else if (nameValue.getType() == Type.INTEGER) {
931 name = "0x" + Integer.toHexString(nameValue.unboxInt()); //$NON-NLS-1$
932 } else if (nameValue.getType() == Type.LONG) {
933 name = "0x" + Long.toHexString(nameValue.unboxLong()); //$NON-NLS-1$
934 }
935 } catch (StateValueTypeException e) {
936 }
937 callStackEntry.setFunctionName(name);
938 if (name.length() > 0) {
939 callStackEntry.setStartTime(stackLevelInterval.getStartTime());
940 callStackEntry.setEndTime(stackLevelInterval.getEndTime() + 1);
941 }
942 } catch (AttributeNotFoundException e) {
52974e38 943 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 944 } catch (TimeRangeException e) {
52974e38 945 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 946 } catch (StateSystemDisposedException e) {
52974e38 947 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298
PT
948 }
949 }
950 }
951 fTimeGraphCombo.refresh();
e8251298
PT
952 }
953
954 private void refresh() {
955 Display.getDefault().asyncExec(new Runnable() {
956 @Override
957 public void run() {
958 if (fTimeGraphCombo.isDisposed()) {
959 return;
960 }
961 ITimeGraphEntry[] entries = null;
962 synchronized (fEntryListMap) {
963 fEntryList = fEntryListMap.get(fTrace);
964 if (fEntryList == null) {
965 fEntryList = new ArrayList<ThreadEntry>();
966 }
967 entries = fEntryList.toArray(new ITimeGraphEntry[0]);
968 }
969 fTimeGraphCombo.setInput(entries);
970 fTimeGraphCombo.getTimeGraphViewer().setTimeBounds(fStartTime, fEndTime);
971
0fcf3b09
PT
972 long selectionBeginTime = fTrace == null ? 0 : fTraceManager.getSelectionBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
973 long selectionEndTime = fTrace == null ? 0 : fTraceManager.getSelectionEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
248af329
AM
974 long startTime = fTrace == null ? 0 : fTraceManager.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
975 long endTime = fTrace == null ? 0 : fTraceManager.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
e8251298
PT
976 startTime = Math.max(startTime, fStartTime);
977 endTime = Math.min(endTime, fEndTime);
0fcf3b09
PT
978 fTimeGraphCombo.getTimeGraphViewer().setSelectionRange(selectionBeginTime, selectionEndTime);
979 selectTime(selectionBeginTime);
e8251298
PT
980 fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
981 startZoomThread(startTime, endTime);
982 }
983 });
984 }
985
986 private void redraw() {
987 synchronized (fSyncObj) {
988 if (fRedrawState == State.IDLE) {
989 fRedrawState = State.BUSY;
990 } else {
991 fRedrawState = State.PENDING;
992 return;
993 }
994 }
995 Display.getDefault().asyncExec(new Runnable() {
996 @Override
997 public void run() {
998 if (fTimeGraphCombo.isDisposed()) {
999 return;
1000 }
1001 fTimeGraphCombo.redraw();
1002 fTimeGraphCombo.update();
1003 synchronized (fSyncObj) {
1004 if (fRedrawState == State.PENDING) {
1005 fRedrawState = State.IDLE;
1006 redraw();
1007 } else {
1008 fRedrawState = State.IDLE;
1009 }
1010 }
1011 }
1012 });
1013 }
1014
1015 private void startZoomThread(long startTime, long endTime) {
1016 if (fZoomThread != null) {
1017 fZoomThread.cancel();
1018 }
1019 fZoomThread = new ZoomThread(fEntryList, startTime, endTime);
1020 fZoomThread.start();
1021 }
1022
1023 private void makeActions() {
1024 fPreviousItemAction = fTimeGraphCombo.getTimeGraphViewer().getPreviousItemAction();
1025 fPreviousItemAction.setText(Messages.TmfTimeGraphViewer_PreviousItemActionNameText);
1026 fPreviousItemAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousItemActionToolTipText);
1027 fNextItemAction = fTimeGraphCombo.getTimeGraphViewer().getNextItemAction();
1028 fNextItemAction.setText(Messages.TmfTimeGraphViewer_NextItemActionNameText);
1029 fNextItemAction.setToolTipText(Messages.TmfTimeGraphViewer_NextItemActionToolTipText);
1030 }
1031
1032 private void contributeToActionBars() {
1033 IActionBars bars = getViewSite().getActionBars();
1034 fillLocalToolBar(bars.getToolBarManager());
1035
1036 // Create pin action
1037 contributePinActionToToolBar();
1038 fPinAction.addPropertyChangeListener(new IPropertyChangeListener(){
1039 @Override
1040 public void propertyChange(PropertyChangeEvent event) {
52974e38
PT
1041 if (IAction.CHECKED.equals(event.getProperty()) && !isPinned()) {
1042 if (fSavedRangeSyncSignal != null) {
1043 synchToRange(fSavedRangeSyncSignal);
1044 fSavedRangeSyncSignal = null;
1045 }
e8251298 1046
52974e38
PT
1047 if (fSavedTimeSyncSignal != null) {
1048 synchToTime(fSavedTimeSyncSignal);
1049 fSavedTimeSyncSignal = null;
e8251298
PT
1050 }
1051 }
1052 }
1053 });
1054 }
1055
1056 private void fillLocalToolBar(IToolBarManager manager) {
5da83da5 1057 manager.add(getImportMappingAction());
e8251298
PT
1058 manager.add(fTimeGraphCombo.getTimeGraphViewer().getResetScaleAction());
1059 manager.add(getPreviousEventAction());
1060 manager.add(getNextEventAction());
1061 manager.add(fPreviousItemAction);
1062 manager.add(fNextItemAction);
1063 manager.add(fTimeGraphCombo.getTimeGraphViewer().getZoomInAction());
1064 manager.add(fTimeGraphCombo.getTimeGraphViewer().getZoomOutAction());
1065 manager.add(new Separator());
1066 }
1067
1068 /**
1069 * Get the the next event action.
1070 *
1071 * @return The action object
1072 */
1073 private Action getNextEventAction() {
1074 if (fNextEventAction == null) {
1075 fNextEventAction = new Action() {
1076 @Override
1077 public void run() {
1078 TimeGraphViewer viewer = fTimeGraphCombo.getTimeGraphViewer();
1079 ITimeGraphEntry entry = viewer.getSelection();
1080 if (entry instanceof CallStackEntry) {
1081 try {
1082 CallStackEntry callStackEntry = (CallStackEntry) entry;
1083 ITmfTrace trace = callStackEntry.getTrace();
1084 ITmfStateSystem ss = trace.getStateSystems().get(CallStackStateProvider.ID);
0fcf3b09 1085 long time = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), viewer.getSelectionBegin()));
e8251298
PT
1086 ThreadEntry threadEntry = (ThreadEntry) callStackEntry.getParent();
1087 int quark = ss.getQuarkRelative(threadEntry.getThreadQuark(), CallStackStateProvider.CALL_STACK);
1088 ITmfStateInterval stackInterval = ss.querySingleState(time, quark);
1089 long newTime = stackInterval.getEndTime() + 1;
1090 viewer.setSelectedTimeNotify(newTime, true);
1091 stackInterval = ss.querySingleState(Math.min(ss.getCurrentEndTime(), newTime), quark);
1092 int stackLevel = stackInterval.getStateValue().unboxInt();
1093 CallStackEntry selectedEntry = threadEntry.getChildren().get(Math.max(0, stackLevel - 1));
1094 fTimeGraphCombo.setSelection(selectedEntry);
1095 viewer.getTimeGraphControl().fireSelectionChanged();
1096 startZoomThread(viewer.getTime0(), viewer.getTime1());
1097 } catch (AttributeNotFoundException e) {
52974e38 1098 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 1099 } catch (TimeRangeException e) {
52974e38 1100 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 1101 } catch (StateSystemDisposedException e) {
52974e38 1102 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 1103 } catch (StateValueTypeException e) {
52974e38 1104 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298
PT
1105 }
1106 }
1107 }
1108 };
1109
1110 fNextEventAction.setText(Messages.TmfTimeGraphViewer_NextEventActionNameText);
1111 fNextEventAction.setToolTipText(Messages.TmfTimeGraphViewer_NextEventActionToolTipText);
1112 fNextEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_EVENT));
1113 }
1114
1115 return fNextEventAction;
1116 }
1117
1118 /**
1119 * Get the previous event action.
1120 *
1121 * @return The Action object
1122 */
1123 private Action getPreviousEventAction() {
1124 if (fPrevEventAction == null) {
1125 fPrevEventAction = new Action() {
1126 @Override
1127 public void run() {
1128 TimeGraphViewer viewer = fTimeGraphCombo.getTimeGraphViewer();
1129 ITimeGraphEntry entry = viewer.getSelection();
1130 if (entry instanceof CallStackEntry) {
1131 try {
1132 CallStackEntry callStackEntry = (CallStackEntry) entry;
1133 ITmfTrace trace = callStackEntry.getTrace();
1134 ITmfStateSystem ss = trace.getStateSystems().get(CallStackStateProvider.ID);
0fcf3b09 1135 long time = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), viewer.getSelectionBegin()));
e8251298
PT
1136 ThreadEntry threadEntry = (ThreadEntry) callStackEntry.getParent();
1137 int quark = ss.getQuarkRelative(threadEntry.getThreadQuark(), CallStackStateProvider.CALL_STACK);
1138 ITmfStateInterval stackInterval = ss.querySingleState(time, quark);
1139 if (stackInterval.getStartTime() == time && time > ss.getStartTime()) {
1140 stackInterval = ss.querySingleState(time - 1, quark);
1141 }
1142 viewer.setSelectedTimeNotify(stackInterval.getStartTime(), true);
1143 int stackLevel = stackInterval.getStateValue().unboxInt();
1144 CallStackEntry selectedEntry = threadEntry.getChildren().get(Math.max(0, stackLevel - 1));
1145 fTimeGraphCombo.setSelection(selectedEntry);
1146 viewer.getTimeGraphControl().fireSelectionChanged();
1147 startZoomThread(viewer.getTime0(), viewer.getTime1());
1148 } catch (AttributeNotFoundException e) {
52974e38 1149 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 1150 } catch (TimeRangeException e) {
52974e38 1151 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 1152 } catch (StateSystemDisposedException e) {
52974e38 1153 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298 1154 } catch (StateValueTypeException e) {
52974e38 1155 Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
e8251298
PT
1156 }
1157 }
1158 }
1159 };
1160
1161 fPrevEventAction.setText(Messages.TmfTimeGraphViewer_PreviousEventActionNameText);
1162 fPrevEventAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousEventActionToolTipText);
1163 fPrevEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_EVENT));
1164 }
1165
1166 return fPrevEventAction;
1167 }
1168
5da83da5
AM
1169 // ------------------------------------------------------------------------
1170 // Methods related to function name mapping
1171 // ------------------------------------------------------------------------
1172
1173 /**
1174 * Toolbar icon to import the function address-to-name mapping file.
1175 */
1176 private Action getImportMappingAction() {
1177 if (fImportMappingAction != null) {
1178 return fImportMappingAction;
1179 }
1180 fImportMappingAction = new Action() {
1181 @Override
1182 public void run() {
1183 FileDialog dialog = new FileDialog(getViewSite().getShell());
1184 dialog.setText(Messages.CallStackView_ImportMappingDialogTitle);
1185 String filePath = dialog.open();
1186 if (filePath == null) {
1187 /* No file was selected, don't change anything */
1188 return;
1189 }
1190 /*
1191 * Start the mapping import in a separate thread (we do not want
1192 * to UI thread to do this).
1193 */
1194 Job job = new ImportMappingJob(new File(filePath));
1195 job.schedule();
1196 }
1197 };
1198
1199 fImportMappingAction.setText(Messages.CallStackView_ImportMappingButtonText);
1200 fImportMappingAction.setToolTipText(Messages.CallStackView_ImportMappingButtonTooltip);
1201 fImportMappingAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(IMPORT_MAPPING_ICON_PATH));
1202
1203 return fImportMappingAction;
1204 }
1205
1206 private class ImportMappingJob extends Job {
1207 private final File fMappingFile;
1208
1209 public ImportMappingJob(File mappingFile) {
1210 super(Messages.CallStackView_ImportMappingJobName);
1211 fMappingFile = mappingFile;
1212 }
1213
1214 @Override
1215 public IStatus run(IProgressMonitor monitor) {
1216 fNameMapping = FunctionNameMapper.mapFromNmTextFile(fMappingFile);
1217
1218 /* Refresh the time graph and the list of entries */
1219 buildThreadList(fTrace, new NullProgressMonitor());
1220 redraw();
1221
1222 return Status.OK_STATUS;
1223 }
1224 }
1225
1226 String getFunctionName(String address) {
1227 if (fNameMapping == null) {
1228 /* No mapping available, just print the addresses */
1229 return address;
1230 }
1231 String ret = fNameMapping.get(address);
1232 if (ret == null) {
1233 /* We didn't find this address in the mapping file, just use the address */
1234 return address;
1235 }
1236 return ret;
1237 }
1238
e8251298 1239}
This page took 0.082284 seconds and 5 git commands to generate.