1 /*******************************************************************************
2 * Copyright (c) 2009, 2015 Ericsson
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
10 * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
11 * Patrick Tasse - Support selection range
12 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.test
.stub
.views
;
15 import java
.text
.SimpleDateFormat
;
16 import java
.util
.ArrayList
;
17 import java
.util
.Date
;
19 import org
.eclipse
.core
.runtime
.PlatformObject
;
20 import org
.eclipse
.jface
.action
.Action
;
21 import org
.eclipse
.jface
.action
.IMenuListener
;
22 import org
.eclipse
.jface
.action
.IMenuManager
;
23 import org
.eclipse
.jface
.action
.IToolBarManager
;
24 import org
.eclipse
.jface
.action
.MenuManager
;
25 import org
.eclipse
.jface
.action
.Separator
;
26 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
27 import org
.eclipse
.jface
.viewers
.DoubleClickEvent
;
28 import org
.eclipse
.jface
.viewers
.IDoubleClickListener
;
29 import org
.eclipse
.jface
.viewers
.ISelection
;
30 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
31 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
32 import org
.eclipse
.jface
.viewers
.LabelProvider
;
33 import org
.eclipse
.jface
.viewers
.TreeViewer
;
34 import org
.eclipse
.jface
.viewers
.Viewer
;
35 import org
.eclipse
.jface
.viewers
.ViewerComparator
;
36 import org
.eclipse
.swt
.SWT
;
37 import org
.eclipse
.swt
.custom
.SashForm
;
38 import org
.eclipse
.swt
.graphics
.Image
;
39 import org
.eclipse
.swt
.widgets
.Composite
;
40 import org
.eclipse
.swt
.widgets
.Menu
;
41 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.ITimeGraphRangeListener
;
42 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.ITimeGraphSelectionListener
;
43 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.ITimeGraphTimeListener
;
44 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.TimeGraphRangeUpdateEvent
;
45 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.TimeGraphSelectionEvent
;
46 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.TimeGraphTimeEvent
;
47 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.TimeGraphViewer
;
48 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ITimeGraphEntry
;
49 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.test
.stub
.adaption
.TsfImplProvider
;
50 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.test
.stub
.model
.EventImpl
;
51 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.test
.stub
.model
.TraceImpl
;
52 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.test
.stub
.model
.TraceModelImplFactory
;
53 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
.TimeFormat
;
54 import org
.eclipse
.ui
.IActionBars
;
55 import org
.eclipse
.ui
.ISharedImages
;
56 import org
.eclipse
.ui
.IWorkbenchActionConstants
;
57 import org
.eclipse
.ui
.PlatformUI
;
58 import org
.eclipse
.ui
.part
.DrillDownAdapter
;
59 import org
.eclipse
.ui
.part
.ViewPart
;
61 @SuppressWarnings("javadoc")
62 public class TsfTraceAnalysisView
extends ViewPart
implements
63 ITimeGraphSelectionListener
, ITimeGraphTimeListener
, ITimeGraphRangeListener
{
65 // ========================================================================
67 // ========================================================================
69 private TreeViewer viewer
;
70 private DrillDownAdapter drillDownAdapter
;
71 private Action action1
;
72 private Action action2
;
73 private Action resetScale
;
74 private Action nextEvent
;
75 private Action prevEvent
;
76 private Action nextTrace
;
77 private Action prevTrace
;
78 private Action showLegent
;
79 private Action zoomIn
;
80 private Action zoomOut
;
81 private Action events300K
;
83 private Action doubleClickAction
;
84 private TimeGraphViewer tsfviewer
;
85 private TimeGraphViewer tsfviewer2
;
87 private static SimpleDateFormat stimeformat
= new SimpleDateFormat(
89 private TraceModelImplFactory fact
;
91 // ========================================================================
93 // ========================================================================
95 * The content provider class is responsible for providing objects to the
96 * view. It can wrap existing objects in adapters or simply return objects
97 * as-is. These objects may be sensitive to the current input of the view,
98 * or ignore it and always show the same content (like Task List, for
102 class TreeObject
extends PlatformObject
{
103 private final String name
;
104 private TreeParent parent
;
106 public TreeObject(String name
) {
110 public String
getName() {
114 public void setParent(TreeParent parent
) {
115 this.parent
= parent
;
118 public TreeParent
getParent() {
123 public String
toString() {
128 class TreeParent
extends TreeObject
{
129 private final ArrayList
<TreeObject
> children
;
131 public TreeParent(String name
) {
133 children
= new ArrayList
<>();
136 public void addChild(TreeObject child
) {
138 child
.setParent(this);
141 public void removeChild(TreeObject child
) {
142 children
.remove(child
);
143 child
.setParent(null);
146 public TreeObject
[] getChildren() {
147 return children
.toArray(new TreeObject
[children
151 public boolean hasChildren() {
152 return children
.size() > 0;
156 class ViewContentProvider
implements ITreeContentProvider
{
157 private TreeParent invisibleRoot
;
160 public void inputChanged(Viewer v
, Object oldInput
, Object newInput
) {
164 public void dispose() {
168 public Object
[] getElements(Object parent
) {
169 if (parent
.equals(getViewSite())) {
170 if (invisibleRoot
== null) {
173 return getChildren(invisibleRoot
);
175 return getChildren(parent
);
179 public Object
getParent(Object child
) {
180 if (child
instanceof TreeObject
) {
181 return ((TreeObject
) child
).getParent();
187 public Object
[] getChildren(Object parent
) {
188 if (parent
instanceof TreeParent
) {
189 return ((TreeParent
) parent
).getChildren();
191 return new Object
[0];
195 public boolean hasChildren(Object parent
) {
196 if (parent
instanceof TreeParent
) {
197 return ((TreeParent
) parent
).hasChildren();
203 * We will set up a dummy model to initialize tree heararchy. In a real
204 * code, you will connect to a real model and expose its hierarchy.
206 private void initialize() {
207 TreeObject to1
= new TreeObject("Leaf 1");
208 TreeObject to2
= new TreeObject("Leaf 2");
209 TreeObject to3
= new TreeObject("Leaf 3");
210 TreeParent p1
= new TreeParent("Parent 1");
215 TreeObject to4
= new TreeObject("Leaf 4");
216 TreeParent p2
= new TreeParent("Parent 2");
219 TreeParent root
= new TreeParent("Root");
223 invisibleRoot
= new TreeParent("");
224 invisibleRoot
.addChild(root
);
228 static class ViewLabelProvider
extends LabelProvider
{
231 public String
getText(Object obj
) {
232 return obj
.toString();
236 public Image
getImage(Object obj
) {
237 String imageKey
= ISharedImages
.IMG_OBJ_ELEMENT
;
238 if (obj
instanceof TreeParent
) {
239 imageKey
= ISharedImages
.IMG_OBJ_FOLDER
;
241 return PlatformUI
.getWorkbench().getSharedImages().getImage(
246 // ========================================================================
248 // ========================================================================
250 * This is a callback that will allow us to create the viewer and initialize
254 public void createPartControl(Composite parent
) {
255 final SashForm sashForm
= new SashForm(parent
, SWT
.NONE
);
256 final SashForm sashForm2
= new SashForm(sashForm
, SWT
.NONE
);
258 tsfviewer
= new TimeGraphViewer(sashForm2
, SWT
.NONE
);
259 tsfviewer
.setTimeGraphProvider(new TsfImplProvider());
260 tsfviewer2
= new TimeGraphViewer(sashForm2
, SWT
.NONE
);
261 tsfviewer2
.setTimeGraphProvider(new TsfImplProvider());
263 viewer
= new TreeViewer(sashForm
, SWT
.MULTI
| SWT
.H_SCROLL
265 drillDownAdapter
= new DrillDownAdapter(viewer
);
266 viewer
.setContentProvider(new ViewContentProvider());
267 viewer
.setLabelProvider(new ViewLabelProvider());
268 viewer
.setComparator(new ViewerComparator());
269 viewer
.setInput(getViewSite());
271 sashForm
.setWeights(new int[] { 5, 1 });
272 sashForm2
.setWeights(new int[] { 1, 1 });
274 fact
= new TraceModelImplFactory();
275 ITimeGraphEntry
[] traceArr
= fact
.createTraces();
276 tsfviewer
.setInput(traceArr
);
277 tsfviewer
.addSelectionListener(this);
278 tsfviewer
.addRangeListener(this);
279 tsfviewer
.setTimeFormat(TimeFormat
.CALENDAR
);
281 tsfviewer2
.setInput(traceArr
);
282 tsfviewer2
.addSelectionListener(this);
283 tsfviewer2
.addRangeListener(this);
284 // tsfviewer2.setTimeFormat(TimeGraphViewer.timeFormat.epoch);
288 hookDoubleClickAction();
289 contributeToActionBars();
292 private void hookContextMenu() {
293 MenuManager menuMgr
= new MenuManager("#PopupMenu");
294 menuMgr
.setRemoveAllWhenShown(true);
295 menuMgr
.addMenuListener(new IMenuListener() {
297 public void menuAboutToShow(IMenuManager manager
) {
298 TsfTraceAnalysisView
.this.fillContextMenu(manager
);
301 Menu menu
= menuMgr
.createContextMenu(viewer
.getControl());
302 viewer
.getControl().setMenu(menu
);
303 getSite().registerContextMenu(menuMgr
, viewer
);
306 private void contributeToActionBars() {
307 IActionBars bars
= getViewSite().getActionBars();
308 fillLocalPullDown(bars
.getMenuManager());
309 fillLocalToolBar(bars
.getToolBarManager());
312 private void fillLocalPullDown(IMenuManager manager
) {
313 manager
.add(action1
);
314 manager
.add(new Separator());
315 manager
.add(action2
);
318 private void fillContextMenu(IMenuManager manager
) {
319 manager
.add(action1
);
320 manager
.add(action2
);
321 manager
.add(new Separator());
322 drillDownAdapter
.addNavigationActions(manager
);
323 // Other plug-ins can contribute there actions here
324 manager
.add(new Separator(IWorkbenchActionConstants
.MB_ADDITIONS
));
327 private void fillLocalToolBar(IToolBarManager manager
) {
328 manager
.add(new Separator());
329 manager
.add(resetScale
);
330 manager
.add(nextEvent
);
331 manager
.add(prevEvent
);
332 manager
.add(nextTrace
);
333 manager
.add(prevTrace
);
334 manager
.add(showLegent
);
336 manager
.add(zoomOut
);
337 manager
.add(events300K
);
338 manager
.add(new Separator());
340 drillDownAdapter
.addNavigationActions(manager
);
343 private TimeGraphViewer
getActiveTsfCtrl() {
344 TimeGraphViewer inFocusViewer
= null;
345 if (tsfviewer
.isInFocus()) {
346 inFocusViewer
= tsfviewer
;
347 } else if (tsfviewer2
.isInFocus()) {
348 inFocusViewer
= tsfviewer2
;
350 return inFocusViewer
;
353 private void makeActions() {
355 action1
= new Action() {
358 showMessage("Action 1 executed");
361 action1
.setText("Action 1");
362 action1
.setToolTipText("Action 1 tooltip");
363 action1
.setImageDescriptor(PlatformUI
.getWorkbench().getSharedImages()
364 .getImageDescriptor(ISharedImages
.IMG_OBJS_INFO_TSK
));
367 action2
= new Action() {
370 showMessage("Action 2 executed");
373 action2
.setText("Action 2");
374 action2
.setToolTipText("Action 2 tooltip");
375 action2
.setImageDescriptor(PlatformUI
.getWorkbench().getSharedImages()
376 .getImageDescriptor(ISharedImages
.IMG_OBJS_INFO_TSK
));
379 resetScale
= new Action() {
382 TimeGraphViewer inFocusViewer
= getActiveTsfCtrl();
383 if (inFocusViewer
!= null) {
384 inFocusViewer
.resetStartFinishTime();
389 resetScale
.setText("Reset");
390 resetScale
.setToolTipText("Reset the Time Scale to Default");
393 nextEvent
= new Action() {
396 TimeGraphViewer inFocusViewer
= getActiveTsfCtrl();
397 if (inFocusViewer
!= null) {
398 inFocusViewer
.selectNextEvent(false);
402 nextEvent
.setText("NextEv");
403 nextEvent
.setToolTipText("Next Event");
406 prevEvent
= new Action() {
409 TimeGraphViewer inFocusViewer
= getActiveTsfCtrl();
410 if (inFocusViewer
!= null) {
411 inFocusViewer
.selectPrevEvent(false);
415 prevEvent
.setText("PrevEv");
416 prevEvent
.setToolTipText("Previous Event");
419 nextTrace
= new Action() {
422 TimeGraphViewer inFocusViewer
= getActiveTsfCtrl();
423 if (inFocusViewer
!= null) {
424 inFocusViewer
.selectNextItem();
428 nextTrace
.setText("NextTrace");
429 nextTrace
.setToolTipText("Select Next Event");
432 prevTrace
= new Action() {
435 TimeGraphViewer inFocusViewer
= getActiveTsfCtrl();
436 if (inFocusViewer
!= null) {
437 inFocusViewer
.selectPrevItem();
441 prevTrace
.setText("PrevTrace");
442 prevTrace
.setToolTipText("Select Previous Trace");
445 showLegent
= new Action() {
448 TimeGraphViewer inFocusViewer
= getActiveTsfCtrl();
449 if (inFocusViewer
!= null) {
450 inFocusViewer
.showLegend();
454 showLegent
.setText("Legend");
455 showLegent
.setToolTipText("Show Legend");
458 zoomIn
= new Action() {
461 TimeGraphViewer inFocusViewer
= getActiveTsfCtrl();
462 if (inFocusViewer
!= null) {
463 inFocusViewer
.zoomIn();
467 zoomIn
.setText("Zoom In");
468 zoomIn
.setToolTipText("Zoom In");
471 zoomOut
= new Action() {
474 TimeGraphViewer inFocusViewer
= getActiveTsfCtrl();
475 if (inFocusViewer
!= null) {
476 inFocusViewer
.zoomOut();
478 // ISelection selection = inFocusViewer.getSelection();
479 // Object sel = null;
480 // if (selection != null && !selection.isEmpty()) {
481 // sel = ((IStructuredSelection) selection)
482 // .getFirstElement();
483 // if (sel instanceof EventImpl) {
484 // EventImpl event = (EventImpl) sel;
485 // inFocusViewer.selectNextEvent();
490 zoomOut
.setText("Zoom Out");
491 zoomOut
.setToolTipText("Zoom Out");
494 events300K
= new Action() {
497 TimeGraphViewer inFocusViewer
= getActiveTsfCtrl();
498 if (inFocusViewer
!= null) {
499 ITimeGraphEntry
[] traceArr
= fact
500 .createLargeTraces(60);
501 inFocusViewer
.setInput(traceArr
);
505 events300K
.setText("300K Events");
506 events300K
.setToolTipText("Add 300K Events");
508 doubleClickAction
= new Action() {
511 ISelection selection
= viewer
.getSelection();
512 Object obj
= ((IStructuredSelection
) selection
)
514 showMessage("Double-click detected on " + obj
.toString());
519 private void hookDoubleClickAction() {
520 viewer
.addDoubleClickListener(new IDoubleClickListener() {
522 public void doubleClick(DoubleClickEvent event
) {
523 doubleClickAction
.run();
528 private void showMessage(String message
) {
529 MessageDialog
.openInformation(viewer
.getControl().getShell(),
530 "TsfTrace Analysis View", message
);
534 * Passing the focus request to the viewer's control.
537 public void setFocus() {
538 viewer
.getControl().setFocus();
542 public void selectionChanged(TimeGraphSelectionEvent event
) {
543 Object source
= event
.getSource();
544 if (source
== null || !(source
instanceof TimeGraphViewer
)) {
548 TimeGraphViewer rViewer
= (TimeGraphViewer
) event
.getSource();
549 TimeGraphViewer synchViewer
= null;
550 // Synchronize viewer selections if Enabled,
551 // make sure the selection does not go in loops
552 if (tsfviewer
== rViewer
) {
553 synchViewer
= tsfviewer2
;
555 synchViewer
= tsfviewer
;
557 Object selection
= event
.getSelection();
559 if (selection
instanceof EventImpl
) {
560 EventImpl selEvent
= (EventImpl
) selection
;
562 .println("TsfTraceAnalysisView.selectionChanged() Selected Event: \nType: "
563 + selEvent
.getType().toString()
567 + selEvent
.getEntry().getName());
569 synchViewer
.setSelectedEvent(selEvent
, source
);
571 } else if (selection
instanceof TraceImpl
) {
572 TraceImpl selTrace
= (TraceImpl
) selection
;
574 .println("TsfTraceAnalysisView.selectionChanged() Selected Trace: \nName: "
575 + selTrace
.getName().toString()
577 + selTrace
.getClassName());
579 synchViewer
.setSelection(selTrace
);
582 .println("TsfTmIncubatorListener.tsfTmProcessEvent() Unexpected event source received: "
583 + selection
.getClass().getName());
589 public void timeSelected(TimeGraphTimeEvent event
) {
590 TimeGraphViewer rViewer
= (TimeGraphViewer
) event
.getSource();
591 TimeGraphViewer synchViewer
= null;
592 // Synchronize viewer selections if Enabled,
593 // make sure the selection does not go in loops
594 if (tsfviewer
== rViewer
) {
595 synchViewer
= tsfviewer2
;
597 synchViewer
= tsfviewer
;
599 long selTimens
= event
.getBeginTime();
600 long tms
= (long) (selTimens
* 1E-6);
601 Date date
= new Date(tms
);
602 String fDate
= stimeformat
.format(date
);
603 String ns
= formatNs(selTimens
);
605 System
.out
.println("TsfTraceAnalysisView.timeSelected() Selected Event: \nTime: "
606 + event
.getBeginTime()
607 + "\nSelected Time: "
608 + selTimens
+ " " + fDate
+ " " + ns
);
610 synchViewer
.setSelectedTime(event
.getBeginTime(), true);
614 public void timeRangeUpdated(TimeGraphRangeUpdateEvent event
) {
618 Object source
= event
.getSource();
619 if (source
== null || !(source
instanceof TimeGraphViewer
)) {
623 TimeGraphRangeUpdateEvent rEvent
= event
;
624 TimeGraphViewer rViewer
= (TimeGraphViewer
) event
626 TimeGraphViewer synchViewer
= null;
627 // Synchronize viewer selections if Enabled,
628 // make sure the selection does not go in loops
629 if (tsfviewer
== rViewer
) {
630 synchViewer
= tsfviewer2
;
632 synchViewer
= tsfviewer
;
635 synchViewer
.setSelectVisTimeWindow(rEvent
.getStartTime(), rEvent
.getEndTime(), source
);
639 * Obtains the remainder fraction on unit Seconds of the entered value in
640 * nanoseconds. e.g. input: 1241207054171080214 ns The number of seconds can
641 * be obtain by removing the last 9 digits: 1241207054 the fractional
642 * portion of seconds, expressed in ns is: 171080214
647 public String
formatNs(long v
) {
648 StringBuffer str
= new StringBuffer();
650 boolean neg
= val
< 0;
656 String strVal
= String
.valueOf(val
);
657 if (val
< 1000000000) {
661 // Extract the last nine digits (e.g. fraction of a S expressed in ns
662 return strVal
.substring(strVal
.length() - 9);