1 /*******************************************************************************
2 * Copyright (c) 2009 Ericsson
4 * All rights reserved. This program and the accompanying materials are made
5 * 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
9 * Contributors: Alvaro Sanchez-Leon - Initial implementation
10 *******************************************************************************/
11 package org
.eclipse
.linuxtools
.lttng
.ui
.views
.controlflow
;
13 import java
.util
.Arrays
;
14 import java
.util
.Vector
;
16 import org
.eclipse
.jface
.action
.Action
;
17 import org
.eclipse
.jface
.action
.IMenuListener
;
18 import org
.eclipse
.jface
.action
.IMenuManager
;
19 import org
.eclipse
.jface
.action
.IToolBarManager
;
20 import org
.eclipse
.jface
.action
.MenuManager
;
21 import org
.eclipse
.jface
.action
.Separator
;
22 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
23 import org
.eclipse
.jface
.viewers
.DoubleClickEvent
;
24 import org
.eclipse
.jface
.viewers
.IDoubleClickListener
;
25 import org
.eclipse
.jface
.viewers
.ISelection
;
26 import org
.eclipse
.jface
.viewers
.ISelectionChangedListener
;
27 import org
.eclipse
.jface
.viewers
.IStructuredContentProvider
;
28 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
29 import org
.eclipse
.jface
.viewers
.ITableLabelProvider
;
30 import org
.eclipse
.jface
.viewers
.LabelProvider
;
31 import org
.eclipse
.jface
.viewers
.SelectionChangedEvent
;
32 import org
.eclipse
.jface
.viewers
.StructuredViewer
;
33 import org
.eclipse
.jface
.viewers
.TableViewer
;
34 import org
.eclipse
.jface
.viewers
.Viewer
;
35 import org
.eclipse
.jface
.viewers
.ViewerFilter
;
36 import org
.eclipse
.linuxtools
.lttng
.event
.LttngTimestamp
;
37 import org
.eclipse
.linuxtools
.lttng
.state
.StateDataRequest
;
38 import org
.eclipse
.linuxtools
.lttng
.state
.StateManager
;
39 import org
.eclipse
.linuxtools
.lttng
.state
.evProcessor
.EventProcessorProxy
;
40 import org
.eclipse
.linuxtools
.lttng
.state
.experiment
.StateExperimentManager
;
41 import org
.eclipse
.linuxtools
.lttng
.state
.experiment
.StateManagerFactory
;
42 import org
.eclipse
.linuxtools
.lttng
.ui
.TraceDebug
;
43 import org
.eclipse
.linuxtools
.lttng
.ui
.model
.trange
.TimeRangeEventProcess
;
44 import org
.eclipse
.linuxtools
.lttng
.ui
.model
.trange
.TimeRangeViewerProvider
;
45 import org
.eclipse
.linuxtools
.lttng
.ui
.views
.common
.AbsTimeUpdateView
;
46 import org
.eclipse
.linuxtools
.lttng
.ui
.views
.common
.ParamsUpdater
;
47 import org
.eclipse
.linuxtools
.lttng
.ui
.views
.controlflow
.evProcessor
.FlowTRangeUpdateFactory
;
48 import org
.eclipse
.linuxtools
.lttng
.ui
.views
.controlflow
.model
.FlowModelFactory
;
49 import org
.eclipse
.linuxtools
.tmf
.event
.TmfTimeRange
;
50 import org
.eclipse
.linuxtools
.tmf
.signal
.TmfSignalHandler
;
51 import org
.eclipse
.linuxtools
.tmf
.signal
.TmfSignalManager
;
52 import org
.eclipse
.linuxtools
.tmf
.signal
.TmfTimeSynchSignal
;
53 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.TmfViewerFactory
;
54 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.ITimeAnalysisViewer
;
55 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.ITmfTimeFilterSelectionListener
;
56 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.ITmfTimeScaleSelectionListener
;
57 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.ITmfTimeSelectionListener
;
58 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.TmfTimeFilterSelectionEvent
;
59 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.TmfTimeScaleSelectionEvent
;
60 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.TmfTimeSelectionEvent
;
61 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.model
.ITmfTimeAnalysisEntry
;
62 import org
.eclipse
.swt
.SWT
;
63 import org
.eclipse
.swt
.custom
.SashForm
;
64 import org
.eclipse
.swt
.custom
.ScrolledComposite
;
65 import org
.eclipse
.swt
.events
.ControlAdapter
;
66 import org
.eclipse
.swt
.events
.ControlEvent
;
67 import org
.eclipse
.swt
.events
.ControlListener
;
68 import org
.eclipse
.swt
.events
.KeyEvent
;
69 import org
.eclipse
.swt
.events
.KeyListener
;
70 import org
.eclipse
.swt
.graphics
.Image
;
71 import org
.eclipse
.swt
.graphics
.Point
;
72 import org
.eclipse
.swt
.graphics
.Rectangle
;
73 import org
.eclipse
.swt
.layout
.FillLayout
;
74 import org
.eclipse
.swt
.widgets
.Composite
;
75 import org
.eclipse
.swt
.widgets
.Display
;
76 import org
.eclipse
.swt
.widgets
.Menu
;
77 import org
.eclipse
.swt
.widgets
.ScrollBar
;
78 import org
.eclipse
.swt
.widgets
.Table
;
79 import org
.eclipse
.swt
.widgets
.TableColumn
;
80 import org
.eclipse
.swt
.widgets
.TableItem
;
81 import org
.eclipse
.ui
.IActionBars
;
82 import org
.eclipse
.ui
.IWorkbenchActionConstants
;
83 import org
.eclipse
.ui
.PlatformUI
;
84 import org
.eclipse
.ui
.plugin
.AbstractUIPlugin
;
87 * <b><u>ControlFlowView</u></b>
89 * TODO: Implement me. Please.
95 public class ControlFlowView
extends AbsTimeUpdateView
implements
96 ITmfTimeSelectionListener
, ITmfTimeScaleSelectionListener
,
97 ITmfTimeFilterSelectionListener
{
99 public static final String ID
= "org.eclipse.linuxtools.lttng.ui.views.controlflow";
101 // ========================================================================
103 // ========================================================================
104 private final String PROCESS_COLUMN
= "Process";
105 private final String BRAND_COLUMN
= "Brand";
106 private final String PID_COLUMN
= "PID";
107 private final String TGID_COLUMN
= "TGID";
108 private final String PPID_COLUMN
= "PPID";
109 private final String CPU_COLUMN
= "CPU";
110 private final String BIRTH_SEC_COLUMN
= "Birth sec";
111 private final String BIRTH_NSEC_COLUMN
= "Birth nsec";
112 private final String TRACE
= "TRACE";
114 private final String
[] columnNames
= new String
[] { PROCESS_COLUMN
, /* */
120 BIRTH_SEC_COLUMN
,/* */
121 BIRTH_NSEC_COLUMN
,/* */
125 // ========================================================================
127 // ========================================================================
128 private TableViewer tableViewer
;
129 // private int totalNumItems = 0;
131 private Action doubleClickAction
;
132 private Action resetScale
;
133 private Action nextEvent
;
134 private Action prevEvent
;
135 private Action nextTrace
;
136 private Action prevTrace
;
137 private Action showLegend
;
138 private Action filterTraces
;
139 private Action zoomIn
;
140 private Action zoomOut
;
141 private Action synch
;
143 private ITimeAnalysisViewer tsfviewer
;
144 private ViewProcessFilter tableFilter
= null;
145 private ScrolledComposite scrollFrame
= null;
146 private Composite wrapper
= null;
147 private Composite top
;
149 // private static SimpleDateFormat stimeformat = new SimpleDateFormat(
150 // "yy/MM/dd HH:mm:ss");
152 // private TraceModelImplFactory fact;
154 // ========================================================================
156 // ========================================================================
158 * The content provider class is responsible for providing objects to the
159 * view. It can wrap existing objects in adapters or simply return objects
160 * as-is. These objects may be sensitive to the current input of the view,
161 * or ignore it and always show the same content (like Task List, for
165 class ViewContentProvider
implements
166 /* ILazyContentProvider, */IStructuredContentProvider
{
167 private TableViewer cviewer
= null;
168 private ITmfTimeAnalysisEntry
[] elements
= null;
170 public ViewContentProvider(TableViewer v
) {
174 public void inputChanged(Viewer v
, Object oldInput
, Object newInput
) {
175 this.elements
= (ITmfTimeAnalysisEntry
[]) newInput
;
176 if (elements
!= null) {
178 .debug("Total number of processes provided to Control Flow view: "
181 TraceDebug
.debug("New input = null");
185 public void dispose() {
189 // Needed with the use of virtual tables in order to initialize items
190 // which were not initially visible.
191 public void updateElement(int index
) {
192 cviewer
.replace(elements
[index
], index
);
196 public Object
[] getElements(Object inputElement
) {
197 // TODO Auto-generated method stub
202 class ViewLabelProvider
extends LabelProvider
implements
203 ITableLabelProvider
{
204 public String
getColumnText(Object obj
, int index
) {
205 String strRes
= ""; //$NON-NLS-1$
207 if (obj
instanceof TimeRangeEventProcess
) {
208 TimeRangeEventProcess process
= (TimeRangeEventProcess
) obj
;
211 strRes
= process
.getName();
214 strRes
= process
.getBrand();
217 strRes
= process
.getPid().toString();
220 strRes
= process
.getTgid().toString();
223 strRes
= process
.getPpid().toString();
226 strRes
= process
.getCpu().toString();
229 time
= new LttngTimestamp(process
.getCreationTime()
231 strRes
= time
.getSeconds();
234 time
= new LttngTimestamp(process
.getCreationTime()
236 strRes
= time
.getNanoSeconds();
239 strRes
= process
.getTraceID();
251 public Image
getColumnImage(Object obj
, int index
) {
252 return getImage(obj
);
256 public Image
getImage(Object obj
) {
257 // No image needed for the time being
258 // return PlatformUI.getWorkbench().getSharedImages().getImage(
259 // ISharedImages.IMG_OBJ_ELEMENT);
264 class ViewProcessFilter
extends ViewerFilter
{
266 private Vector
<ITmfTimeAnalysisEntry
> filteredSet
= new Vector
<ITmfTimeAnalysisEntry
>();
267 StructuredViewer viewer
;
269 public ViewProcessFilter(StructuredViewer rviewer
) {
270 this.viewer
= rviewer
;
273 public void setFilter(Vector
<ITmfTimeAnalysisEntry
> filtered
) {
274 if (filtered
!= null) {
275 this.filteredSet
= filtered
;
281 public boolean select(Viewer viewer
, Object parentElement
,
283 boolean filteredIn
= true;
284 if (element
instanceof ITmfTimeAnalysisEntry
) {
285 ITmfTimeAnalysisEntry process
= (ITmfTimeAnalysisEntry
) element
;
286 if (filteredSet
.contains(process
)) {
287 // The element is marked to be filtered out
291 TraceDebug
.debug("Unexpected type of filter element received: "
292 + element
.toString());
294 // Compare element versus a list of filtered out
302 public ControlFlowView() {
307 * This is a callback that will allow us to create the viewer and initialize
311 public void createPartControl(Composite parent
) {
312 top
= new Composite(parent
, SWT
.BORDER
);
314 top
.setLayout(new FillLayout());
316 scrollFrame
= new ScrolledComposite(top
, SWT
.V_SCROLL
| SWT
.H_SCROLL
);
317 scrollFrame
.setBounds(top
.getClientArea());
319 wrapper
= new Composite(scrollFrame
, SWT
.NONE
);
320 scrollFrame
.setEnabled(true);
321 scrollFrame
.setRedraw(true);
322 scrollFrame
.setExpandVertical(true);
323 scrollFrame
.setExpandHorizontal(true);
324 scrollFrame
.setContent(wrapper
);
325 scrollFrame
.setAlwaysShowScrollBars(true);
326 wrapper
.setLayout(new FillLayout());
328 SashForm sash
= new SashForm(wrapper
, SWT
.NONE
);
329 final Composite tableComposite
= new Composite(sash
, SWT
.NO_SCROLL
);
330 FillLayout layout
= new FillLayout();
331 tableComposite
.setLayout(layout
);
332 tableViewer
= new TableViewer(tableComposite
, SWT
.FULL_SELECTION
334 tableViewer
.setContentProvider(new ViewContentProvider(tableViewer
));
335 tableViewer
.setLabelProvider(new ViewLabelProvider());
336 Table table
= tableViewer
.getTable();
338 .addSelectionChangedListener(new ISelectionChangedListener() {
339 public void selectionChanged(SelectionChangedEvent event
) {
340 ISelection sel
= event
.getSelection();
341 if (!sel
.isEmpty()) {
342 Object firstSel
= null;
343 if (sel
instanceof IStructuredSelection
) {
344 firstSel
= ((IStructuredSelection
) sel
)
347 // Make sure the selection is visible
348 updateScrollOrigin();
350 if (firstSel
instanceof ITmfTimeAnalysisEntry
) {
351 ITmfTimeAnalysisEntry trace
= (ITmfTimeAnalysisEntry
) firstSel
;
352 tsfviewer
.setSelectedTrace(trace
);
359 * Make sure the selected item is visible
361 private void updateScrollOrigin() {
362 Table table
= tableViewer
.getTable();
363 if (table
!= null && table
.getItemCount() > 0) {
364 TableItem item
= table
.getSelection()[0];
366 // no selected reference to go up or down
370 Rectangle itemRect
= item
.getBounds();
371 int step
= itemRect
.height
;
373 // calculate height of horizontal bar
375 ScrollBar hbar
= scrollFrame
.getHorizontalBar();
377 hscrolly
= hbar
.getSize().y
;
380 int visibleHeight
= scrollFrame
.getSize().y
383 // the current scrollbar offset to adjust i.e. start
385 // the visible window
386 Point origin
= scrollFrame
.getOrigin();
387 // end of visible window
388 int endy
= origin
.y
+ visibleHeight
;
390 int itemStartPos
= itemRect
.y
391 + table
.getHeaderHeight()
392 + table
.getBorderWidth()
393 + table
.getParent().getBorderWidth();
396 int itemEndPos
= itemStartPos
+ step
;
398 // check if need to go up
399 if (origin
.y
>= step
&& itemStartPos
< origin
.y
) {
402 .setOrigin(origin
.x
, origin
.y
- step
);
406 // check if it needs to go down
407 if (itemEndPos
> endy
) {
410 .setOrigin(origin
.x
, origin
.y
+ step
);
417 // Listen to page up /down and Home / Enc keys
418 tableViewer
.getTable().addKeyListener(new KeyListener() {
419 public void keyPressed(KeyEvent e
) {
420 Table table
= tableViewer
.getTable();
421 Point origin
= scrollFrame
.getOrigin();
422 if (table
== null || table
.getItemCount() < 1) {
432 updateScrollPageDown();
439 count
= table
.getItemCount();
440 item
= table
.getItem(0);
442 scrollFrame
.setOrigin(origin
.x
, 0);
446 count
= table
.getItemCount();
447 item
= table
.getItem(count
- 1);
448 int itemStartPos
= item
.getBounds().y
;
450 scrollFrame
.setOrigin(origin
.x
, itemStartPos
);
457 public void keyReleased(KeyEvent e
) {
463 * Scroll one page down
465 private void updateScrollPageDown() {
466 // null protection before calling private method
467 Table table
= tableViewer
.getTable();
468 int step
= table
.getItemHeight();
471 ScrollBar hbar
= scrollFrame
.getHorizontalBar();
473 hscrolly
= hbar
.getSize().y
;
476 Point origin
= scrollFrame
.getOrigin();
477 int visibleHeight
= scrollFrame
.getSize().y
- hscrolly
;
478 int endy
= origin
.y
+ visibleHeight
;
480 scrollFrame
.setOrigin(origin
.x
, endy
- step
);
486 private void updateScrollUp() {
487 // null protection before calling private method
488 Table table
= tableViewer
.getTable();
489 int step
= table
.getItemHeight();
492 ScrollBar hbar
= scrollFrame
.getHorizontalBar();
494 hscrolly
= hbar
.getSize().y
;
497 Point origin
= scrollFrame
.getOrigin();
498 int visibleHeight
= scrollFrame
.getSize().y
- hscrolly
;
499 int pageUpPos
= origin
.y
- visibleHeight
+ step
;
500 pageUpPos
= pageUpPos
> 0 ? pageUpPos
: 0;
501 scrollFrame
.setOrigin(origin
.x
, pageUpPos
);
506 applyTableLayout(table
);
508 int borderWidth
= table
.getBorderWidth();
510 int itemHeight
= table
.getItemHeight();
511 int headerHeight
= table
.getHeaderHeight();
512 table
.getVerticalBar().setVisible(false);
514 tsfviewer
= TmfViewerFactory
.createViewer(sash
,
515 new TimeRangeViewerProvider());
517 tsfviewer
.addWidgetSelectionListner(this);
518 tsfviewer
.addWidgetTimeScaleSelectionListner(this);
520 // Traces shall not be grouped to allow synchronisation
521 tsfviewer
.groupTraces(false);
522 tsfviewer
.setItemHeight(itemHeight
);
523 tsfviewer
.setBorderWidth(borderWidth
);
524 tsfviewer
.setHeaderHeight(headerHeight
);
525 tsfviewer
.setVisibleVerticalScroll(false);
526 // Names provided by the table
527 tsfviewer
.setNameWidthPref(0);
528 tsfviewer
.setAcceptSelectionAPIcalls(true);
530 // Viewer to notify selection to this class
531 // This class will synchronise selections with table.
532 tsfviewer
.addWidgetSelectionListner(this);
533 tsfviewer
.addFilterSelectionListner(this);
534 tsfviewer
.addWidgetTimeScaleSelectionListner(this);
536 sash
.setWeights(new int[] { 1, 1 });
537 // Create the help context id for the viewer's control
538 // TODO: Associate with help system
539 PlatformUI
.getWorkbench().getHelpSystem().setHelp(
540 tableViewer
.getControl(),
541 "org.eclipse.linuxtools.lttnng.ui.views.flow.viewer"); //$NON-NLS-1$
545 hookDoubleClickAction();
546 contributeToActionBars();
548 scrollFrame
.addControlListener(new ControlAdapter() {
550 public void controlResized(ControlEvent e
) {
551 tsfviewer
.resizeControls();
552 updateScrolls(scrollFrame
, wrapper
);
556 tableComposite
.addControlListener(new ControlListener() {
557 public void controlResized(ControlEvent e
) {
558 scrollFrame
.getParent().update();
561 public void controlMoved(ControlEvent e
) {
566 // Register the updater in charge to refresh elements as we update the
568 // FlowParamsUpdater listener = FlowModelFactory.getParamsUpdater();
569 // tsfviewer.addWidgetTimeScaleSelectionListner(listener);
571 // Register this view to receive updates when the model is updated with
573 // ModelListenFactory.getRegister().addFlowModelUpdatesListener(this);
575 // Register the event processor factory in charge of event handling
576 EventProcessorProxy
.getInstance().addEventProcessorFactory(
577 FlowTRangeUpdateFactory
.getInstance());
579 // set the initial view parameter values
580 // Experiment start and end time
581 // as well as time space width in pixels, used by the time analysis
583 ParamsUpdater paramUpdater
= FlowModelFactory
.getParamsUpdater();
584 StateExperimentManager experimentManger
= StateManagerFactory
585 .getExperimentManager();
586 // Read relevant values
587 int timeSpaceWidth
= tsfviewer
.getTimeSpace();
588 TmfTimeRange timeRange
= experimentManger
.getExperimentTimeRange();
589 if (timeRange
!= null) {
590 long time0
= timeRange
.getStartTime().getValue();
591 long time1
= timeRange
.getEndTime().getValue();
592 paramUpdater
.update(time0
, time1
, timeSpaceWidth
);
595 experimentManger
.readExperiment("flowView", this);
598 private void hookContextMenu() {
599 MenuManager menuMgr
= new MenuManager("#PopupMenu"); //$NON-NLS-1$
600 menuMgr
.setRemoveAllWhenShown(true);
601 menuMgr
.addMenuListener(new IMenuListener() {
602 public void menuAboutToShow(IMenuManager manager
) {
603 ControlFlowView
.this.fillContextMenu(manager
);
606 Menu menu
= menuMgr
.createContextMenu(tableViewer
.getControl());
607 tableViewer
.getControl().setMenu(menu
);
608 getSite().registerContextMenu(menuMgr
, tableViewer
);
611 private void contributeToActionBars() {
612 IActionBars bars
= getViewSite().getActionBars();
613 fillLocalPullDown(bars
.getMenuManager());
614 fillLocalToolBar(bars
.getToolBarManager());
617 private void fillLocalPullDown(IMenuManager manager
) {
618 manager
.add(new Separator());
619 // manager.add(showLegend);
620 manager
.add(new Separator());
621 manager
.add(resetScale
);
622 manager
.add(nextEvent
);
623 manager
.add(prevEvent
);
624 manager
.add(nextTrace
);
625 manager
.add(prevTrace
);
626 // manager.add(filterTraces);
628 manager
.add(zoomOut
);
630 manager
.add(new Separator());
633 private void fillContextMenu(IMenuManager manager
) {
634 // manager.add(showLegend);
635 manager
.add(new Separator());
636 manager
.add(resetScale
);
637 manager
.add(nextEvent
);
638 manager
.add(prevEvent
);
639 manager
.add(nextTrace
);
640 manager
.add(prevTrace
);
641 // manager.add(showLegend);
642 // manager.add(filterTraces);
644 manager
.add(zoomOut
);
646 manager
.add(new Separator());
647 manager
.add(new Separator(IWorkbenchActionConstants
.MB_ADDITIONS
));
650 private void fillLocalToolBar(IToolBarManager manager
) {
651 // manager.add(showLegend);
652 manager
.add(new Separator());
653 manager
.add(resetScale
);
654 manager
.add(nextEvent
);
655 manager
.add(prevEvent
);
656 manager
.add(nextTrace
);
657 manager
.add(prevTrace
);
658 // manager.add(filterTraces);
660 manager
.add(zoomOut
);
662 manager
.add(new Separator());
665 private void makeActions() {
667 resetScale
= new Action() {
670 if (tsfviewer
!= null) {
671 tsfviewer
.resetStartFinishTime();
676 resetScale
.setText(Messages
.getString("ControlFlowView.Action.Reset")); //$NON-NLS-1$
677 resetScale
.setToolTipText(Messages
678 .getString("ControlFlowView.Action.Reset.ToolTip")); //$NON-NLS-1$
679 resetScale
.setImageDescriptor(AbstractUIPlugin
680 .imageDescriptorFromPlugin(Messages
681 .getString("ControlFlowView.tmf.UI"),
682 "icons/home_nav.gif"));
685 nextEvent
= new Action() {
688 if (tsfviewer
!= null) {
689 tsfviewer
.selectNextEvent();
693 nextEvent
.setText(Messages
694 .getString("ControlFlowView.Action.NextEvent")); //$NON-NLS-1$
695 nextEvent
.setToolTipText(Messages
696 .getString("ControlFlowView.Action.NextEvent.Tooltip")); //$NON-NLS-1$
697 nextEvent
.setImageDescriptor(AbstractUIPlugin
698 .imageDescriptorFromPlugin(Messages
699 .getString("ControlFlowView.tmf.UI"),
700 "icons/next_event.gif"));
703 prevEvent
= new Action() {
706 if (tsfviewer
!= null) {
707 tsfviewer
.selectPrevEvent();
711 prevEvent
.setText(Messages
712 .getString("ControlFlowView.Action.PrevEvent")); //$NON-NLS-1$
713 prevEvent
.setToolTipText(Messages
714 .getString("ControlFlowView.Action.PrevEvent.Tooltip")); //$NON-NLS-1$
715 prevEvent
.setImageDescriptor(AbstractUIPlugin
716 .imageDescriptorFromPlugin(Messages
717 .getString("ControlFlowView.tmf.UI"),
718 "icons/prev_event.gif"));
721 nextTrace
= new Action() {
724 if (tsfviewer
!= null) {
725 tsfviewer
.selectNextTrace();
729 nextTrace
.setText(Messages
730 .getString("ControlFlowView.Action.NextProcess")); //$NON-NLS-1$
731 nextTrace
.setToolTipText(Messages
732 .getString("ControlFlowView.Action.NextProcess.ToolTip")); //$NON-NLS-1$
733 nextTrace
.setImageDescriptor(AbstractUIPlugin
734 .imageDescriptorFromPlugin(Messages
735 .getString("ControlFlowView.tmf.UI"),
736 "icons/next_item.gif"));
739 prevTrace
= new Action() {
742 if (tsfviewer
!= null) {
743 tsfviewer
.selectPrevTrace();
747 prevTrace
.setText(Messages
748 .getString("ControlFlowView.Action.PreviousProcess")); //$NON-NLS-1$
749 prevTrace
.setToolTipText(Messages
750 .getString("ControlFlowView.Action.PreviousProcess.Tooltip")); //$NON-NLS-1$
751 prevTrace
.setImageDescriptor(AbstractUIPlugin
752 .imageDescriptorFromPlugin(Messages
753 .getString("ControlFlowView.tmf.UI"),
754 "icons/prev_item.gif"));
757 showLegend
= new Action() {
760 if (tsfviewer
!= null) {
761 tsfviewer
.showLegend();
765 showLegend
.setText(Messages
.getString("ControlFlowView.Action.Legend")); //$NON-NLS-1$
766 showLegend
.setToolTipText(Messages
767 .getString("ControlFlowView.Action.Legend.ToolTip")); //$NON-NLS-1$
770 filterTraces
= new Action() {
773 if (tsfviewer
!= null) {
774 tsfviewer
.filterTraces();
778 filterTraces
.setText(Messages
779 .getString("ControlFlowView.Action.Filter")); //$NON-NLS-1$
780 filterTraces
.setToolTipText(Messages
781 .getString("ControlFlowView.Action.Filter.ToolTip")); //$NON-NLS-1$
782 filterTraces
.setImageDescriptor(AbstractUIPlugin
783 .imageDescriptorFromPlugin(Messages
784 .getString("ControlFlowView.tmf.UI"),
785 "icons/filter_items.gif"));
788 zoomIn
= new Action() {
791 if (tsfviewer
!= null) {
796 zoomIn
.setText(Messages
.getString("ControlFlowView.Action.ZoomIn")); //$NON-NLS-1$
797 zoomIn
.setToolTipText(Messages
798 .getString("ControlFlowView.Action.ZoomIn.Tooltip")); //$NON-NLS-1$
799 zoomIn
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(
800 Messages
.getString("ControlFlowView.tmf.UI"),
801 "icons/zoomin_nav.gif"));
804 zoomOut
= new Action() {
807 if (tsfviewer
!= null) {
812 zoomOut
.setText(Messages
.getString("ControlFlowView.Action.ZoomOut")); //$NON-NLS-1$
813 zoomOut
.setToolTipText(Messages
814 .getString("ControlFlowView.Action.ZoomOut.tooltip")); //$NON-NLS-1$
815 zoomOut
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(
816 Messages
.getString("ControlFlowView.tmf.UI"),
817 "icons/zoomout_nav.gif"));
820 synch
= new Action() {
823 // Note: No action since the synch flag is used by Control flow
825 // the actual viewer is set to accept api selections in
826 // createpartcontrol.
828 // if (synch.isChecked()) {
829 // tsfviewer.setAcceptSelectionAPIcalls(true);
831 // tsfviewer.setAcceptSelectionAPIcalls(false);
835 synch
.setText(Messages
.getString("ControlFlowView.Action.Synchronize")); //$NON-NLS-1$
836 synch
.setToolTipText(Messages
837 .getString("ControlFlowView.Action.Synchronize.ToolTip")); //$NON-NLS-1$
838 synch
.setChecked(false);
839 synch
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(
840 Messages
.getString("ControlFlowView.tmf.UI"),
841 "icons/synced.gif"));
842 // PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_ELCL_SYNCED);
844 doubleClickAction
= new Action() {
847 ISelection selection
= tableViewer
.getSelection();
848 Object obj
= ((IStructuredSelection
) selection
)
850 showMessage("Double-click detected on " + obj
.toString()); //$NON-NLS-1$
855 private void hookDoubleClickAction() {
856 tableViewer
.addDoubleClickListener(new IDoubleClickListener() {
857 public void doubleClick(DoubleClickEvent event
) {
858 doubleClickAction
.run();
863 private void showMessage(String message
) {
864 MessageDialog
.openInformation(tableViewer
.getControl().getShell(),
865 Messages
.getString("ControlFlowView.msgSlogan"), message
); //$NON-NLS-1$
869 * Passing the focus request to the viewer's control.
872 public void setFocus() {
873 tableViewer
.getControl().setFocus();
876 public void tsfTmProcessSelEvent(TmfTimeSelectionEvent event
) {
877 Object source
= event
.getSource();
878 if (source
== null) {
882 // Reselect the table viewer to widget selection
883 ISelection sel
= tsfviewer
.getSelectionTrace();
884 if (sel
!= null && !sel
.isEmpty()) {
885 tableViewer
.setSelection(sel
);
888 ParamsUpdater paramUpdater
= FlowModelFactory
.getParamsUpdater();
889 Long savedSelTime
= paramUpdater
.getSelectedTime();
891 long selTimens
= event
.getSelectedTime();
893 // make sure the new selected time is different than saved before
895 if (savedSelTime
== null || savedSelTime
!= selTimens
) {
896 // Notify listener views.
897 synchTimeNotification(selTimens
);
899 // Update the parameter updater to save the selected time
900 paramUpdater
.setSelectedTime(selTimens
);
902 if (TraceDebug
.isDEBUG()) {
903 // Object selection = event.getSelection();
904 TraceDebug
.debug("Selected Time in control Flow View: "
905 + new LttngTimestamp(selTimens
));
910 public synchronized void tsfTmProcessTimeScaleEvent(
911 TmfTimeScaleSelectionEvent event
) {
912 // source needed to keep track of source values
913 Object source
= event
.getSource();
915 if (source
!= null) {
916 // Update the parameter updater before carrying out a read request
917 ParamsUpdater paramUpdater
= FlowModelFactory
.getParamsUpdater();
918 boolean newParams
= paramUpdater
.processTimeScaleEvent(event
);
921 // Read the updated time window
922 TmfTimeRange trange
= paramUpdater
.getTrange();
923 if (trange
!= null) {
924 // Request new data for specified time range
932 * Obtains the remainder fraction on unit Seconds of the entered value in
933 * nanoseconds. e.g. input: 1241207054171080214 ns The number of seconds can
934 * be obtain by removing the last 9 digits: 1241207054 the fractional
935 * portion of seconds, expressed in ns is: 171080214
940 public String
formatNs(long v
) {
941 StringBuffer str
= new StringBuffer();
948 String strVal
= String
.valueOf(v
);
949 if (v
< 1000000000) {
953 // Extract the last nine digits (e.g. fraction of a S expressed in ns
954 return strVal
.substring(strVal
.length() - 9);
957 private void applyTableLayout(Table table
) {
958 for (int i
= 0; i
< columnNames
.length
; i
++) {
959 TableColumn tableColumn
= new TableColumn(table
, SWT
.LEFT
);
960 tableColumn
.setText(columnNames
[i
]);
963 table
.setHeaderVisible(true);
964 table
.setLinesVisible(true);
971 * @param updateTimeBounds - Update needed e.g. a new Experiment or trace selected
973 public void flowModelUpdates(final ITmfTimeAnalysisEntry
[] items
,
974 final long startTime
, final long endTime
,
975 final boolean updateTimeBounds
) {
976 final Table table
= tableViewer
.getTable();
977 Display display
= table
.getDisplay();
979 // Perform the updates on the UI thread)
980 display
.asyncExec(new Runnable() {
983 tableViewer
.setInput(items
); // This shall be the minimal
985 tableFilter
= new ViewProcessFilter(tableViewer
);
986 tableViewer
.setFilters(new ViewerFilter
[] { tableFilter
});
988 resizeTableColumns(table
);
990 tableViewer
.refresh();
992 tsfviewer
.display(items
, startTime
, endTime
, updateTimeBounds
);
993 tsfviewer
.resizeControls();
995 // Adjust the size of the vertical scroll bar to fit the
997 if (scrollFrame
!= null && wrapper
!= null) {
998 updateScrolls(scrollFrame
, wrapper
);
999 // scrollFrame.update();
1006 public void dispose() {
1007 // dispose parent resources
1009 // Remove the event processor factory
1010 EventProcessorProxy
.getInstance().removeEventProcessorFactory(
1011 FlowTRangeUpdateFactory
.getInstance());
1013 // Remove listener to model updates
1014 // ModelListenFactory.getRegister().removeFlowModelUpdatesListener(this);
1015 tsfviewer
.removeFilterSelectionListner(this);
1016 tsfviewer
.removeWidgetSelectionListner(this);
1017 tsfviewer
.removeWidgetTimeScaleSelectionListner(this);
1023 * @param tableComposite
1026 private synchronized void resizeTableColumns(Table table
) {
1027 if (table
!= null) {
1028 Composite parent
= table
.getParent();
1029 int tableWidthSum
= parent
.getBorderWidth();
1031 TableColumn
[] columns
= table
.getColumns();
1032 for (TableColumn column
: columns
) {
1034 tableWidthSum
+= column
.getWidth();
1040 public void tmfTaProcessFilterSelection(TmfTimeFilterSelectionEvent event
) {
1041 if (tableFilter
!= null) {
1042 Vector
<ITmfTimeAnalysisEntry
> filteredout
= event
.getFilteredOut();
1043 if (filteredout
!= null) {
1044 tableFilter
.setFilter(filteredout
);
1046 tableFilter
.setFilter(new Vector
<ITmfTimeAnalysisEntry
>());
1048 tableViewer
.refresh();
1053 * @param scrollFrame
1056 private void updateScrolls(final ScrolledComposite scrollFrame
,
1057 final Composite wrapper
) {
1059 Point ptSize
= wrapper
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
);
1060 wrapper
.setSize(ptSize
);
1061 scrollFrame
.setMinSize(ptSize
);
1063 // calculate the increment area considering the table header height and
1065 Rectangle area
= top
.getBounds();
1066 int marginsHeight
= tableViewer
.getTable().getHeaderHeight();
1067 marginsHeight
-= top
.getBorderWidth() + wrapper
.getBorderWidth();
1068 area
.height
-= marginsHeight
;
1070 // set page vertical increment area
1071 ScrollBar verBar
= scrollFrame
.getVerticalBar();
1072 ScrollBar horBar
= scrollFrame
.getHorizontalBar();
1073 if (verBar
!= null) {
1074 verBar
.setPageIncrement(area
.height
);
1076 if (horBar
!= null) {
1077 horBar
.setPageIncrement(area
.width
);
1083 * Trigger time synchronisation to other views this method shall be called
1084 * when a check has been performed to note that an actual change of time has
1085 * been performed vs a pure re-selection of the same time
1089 private void synchTimeNotification(long time
) {
1090 // if synchronisation selected
1091 if (synch
.isChecked()) {
1092 // Notify other views
1093 TmfSignalManager
.dispatchSignal(new TmfTimeSynchSignal(this,
1094 new LttngTimestamp(time
)));
1099 * Registers as listener of time selection from other tmf views
1104 public void synchToTime(TmfTimeSynchSignal signal
) {
1105 if (synch
.isChecked()) {
1106 Object source
= signal
.getSource();
1107 if (signal
!= null && source
!= null && source
!= this) {
1108 // Internal value is expected in nano seconds.
1109 long selectedTime
= signal
.getCurrentTime().getValue();
1110 if (tsfviewer
!= null) {
1111 tsfviewer
.setSelectedTime(selectedTime
, true, source
);
1121 * org.eclipse.linuxtools.lttng.ui.views.common.LttngTimeUpdateView#waitCursor
1125 protected synchronized void waitCursor(final boolean waitInd
) {
1126 if (tsfviewer
!= null) {
1127 Display display
= tsfviewer
.getControl().getDisplay();
1129 // Perform the updates on the UI thread
1130 display
.asyncExec(new Runnable() {
1132 tsfviewer
.waitCursor(waitInd
);
1141 * @seeorg.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#
1142 * ModelUpdatePrep(java.lang.String, boolean)
1145 public void ModelUpdatePrep(String traceId
, boolean clearAllData
,
1146 TmfTimeRange trange
) {
1148 FlowModelFactory
.getProcContainer().clearProcesses();
1149 // Obtain the current process list
1150 Vector
<TimeRangeEventProcess
> processList
= FlowModelFactory
1151 .getProcContainer().readProcesses();
1152 // convert it to an Array as expected by the widget
1153 TimeRangeEventProcess
[] processArr
= processList
1154 .toArray(new TimeRangeEventProcess
[processList
.size()]);
1156 // initialise to an empty model
1157 flowModelUpdates(processArr
, -1, -1, false);
1159 FlowModelFactory
.getProcContainer().clearChildren(traceId
);
1162 ParamsUpdater updater
= FlowModelFactory
.getParamsUpdater();
1164 updater
.setEventsDiscarded(0);
1166 // Update new visible time range if available
1167 if (trange
!= null) {
1168 updater
.update(trange
.getStartTime().getValue(), trange
1169 .getEndTime().getValue());
1176 * @seeorg.eclipse.linuxtools.lttng.ui.views.common.LttngTimeUpdateView#
1177 * ModelUpdateComplete(org.eclipse.linuxtools.lttng.state.StateDataRequest)
1180 public void ModelUpdateComplete(StateDataRequest request
) {
1181 long experimentStartTime
= -1;
1182 long experimentEndTime
= -1;
1183 StateManager smanager
= request
.getStateManager();
1184 TmfTimeRange experimentTimeRange
= smanager
.getExperimentTimeWindow();
1185 if (experimentTimeRange
!= null) {
1186 experimentStartTime
= experimentTimeRange
.getStartTime().getValue();
1187 experimentEndTime
= experimentTimeRange
.getEndTime().getValue();
1189 // Obtain the current process list
1190 Vector
<TimeRangeEventProcess
> processList
= FlowModelFactory
1191 .getProcContainer().readProcesses();
1192 // convert it to an Array as expected by the widget
1193 TimeRangeEventProcess
[] processArr
= processList
1194 .toArray(new TimeRangeEventProcess
[processList
.size()]);
1195 // Sort the array by pid
1196 Arrays
.sort(processArr
);
1198 // Update the view part
1199 flowModelUpdates(processArr
, experimentStartTime
, experimentEndTime
,
1200 request
.isclearDataInd());
1202 // get back to user selected time if still within range
1203 ParamsUpdater paramUpdater
= FlowModelFactory
.getParamsUpdater();
1204 final Long selTime
= paramUpdater
.getSelectedTime();
1205 if (selTime
!= null) {
1206 Display display
= tsfviewer
.getControl().getDisplay();
1207 display
.asyncExec(new Runnable() {
1209 tsfviewer
.setSelectedTime(selTime
, false, this);
1214 if (TraceDebug
.isDEBUG()) {
1216 Long count
= smanager
.getEventCount();
1217 for (TimeRangeEventProcess process
: processList
) {
1218 eventCount
+= process
.getTraceEvents().size();
1221 int discarded
= FlowModelFactory
.getParamsUpdater()
1222 .getEventsDiscarded();
1223 int discardedOutofOrder
= FlowModelFactory
.getParamsUpdater()
1224 .getEventsDiscardedWrongOrder();
1225 TmfTimeRange range
= request
.getRange();
1226 StringBuilder sb
= new StringBuilder(
1229 + " Events loaded in Control Flow view: "
1231 + " Number of events discarded: "
1233 + "\n\tNumber of events discarded with start time earlier than next good time: "
1234 + discardedOutofOrder
);
1236 sb
.append("\n\t\tRequested Time Range: " + range
.getStartTime()
1237 + "-" + range
.getEndTime());
1238 sb
.append("\n\t\tExperiment Time Range: " + experimentStartTime
1239 + "-" + experimentEndTime
);
1240 TraceDebug
.debug(sb
.toString());