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);
523 int swtBugAjustment
= checkForSWTBugItemHeightAdjustement();
524 tsfviewer
.setItemHeight(itemHeight
+ swtBugAjustment
);
526 tsfviewer
.setBorderWidth(borderWidth
);
527 tsfviewer
.setHeaderHeight(headerHeight
);
528 tsfviewer
.setVisibleVerticalScroll(false);
529 // Names provided by the table
530 tsfviewer
.setNameWidthPref(0);
531 tsfviewer
.setAcceptSelectionAPIcalls(true);
533 // Viewer to notify selection to this class
534 // This class will synchronise selections with table.
535 tsfviewer
.addWidgetSelectionListner(this);
536 tsfviewer
.addFilterSelectionListner(this);
537 tsfviewer
.addWidgetTimeScaleSelectionListner(this);
539 sash
.setWeights(new int[] { 1, 1 });
540 // Create the help context id for the viewer's control
541 // TODO: Associate with help system
542 PlatformUI
.getWorkbench().getHelpSystem().setHelp(
543 tableViewer
.getControl(),
544 "org.eclipse.linuxtools.lttnng.ui.views.flow.viewer"); //$NON-NLS-1$
548 hookDoubleClickAction();
549 contributeToActionBars();
551 scrollFrame
.addControlListener(new ControlAdapter() {
553 public void controlResized(ControlEvent e
) {
554 tsfviewer
.resizeControls();
555 updateScrolls(scrollFrame
, wrapper
);
559 tableComposite
.addControlListener(new ControlListener() {
560 public void controlResized(ControlEvent e
) {
561 scrollFrame
.getParent().update();
564 public void controlMoved(ControlEvent e
) {
569 // Register the updater in charge to refresh elements as we update the
571 // FlowParamsUpdater listener = FlowModelFactory.getParamsUpdater();
572 // tsfviewer.addWidgetTimeScaleSelectionListner(listener);
574 // Register this view to receive updates when the model is updated with
576 // ModelListenFactory.getRegister().addFlowModelUpdatesListener(this);
578 // Register the event processor factory in charge of event handling
579 EventProcessorProxy
.getInstance().addEventProcessorFactory(
580 FlowTRangeUpdateFactory
.getInstance());
582 // set the initial view parameter values
583 // Experiment start and end time
584 // as well as time space width in pixels, used by the time analysis
586 ParamsUpdater paramUpdater
= FlowModelFactory
.getParamsUpdater();
587 StateExperimentManager experimentManger
= StateManagerFactory
588 .getExperimentManager();
589 // Read relevant values
590 int timeSpaceWidth
= tsfviewer
.getTimeSpace();
591 TmfTimeRange timeRange
= experimentManger
.getExperimentTimeRange();
592 if (timeRange
!= null) {
593 long time0
= timeRange
.getStartTime().getValue();
594 long time1
= timeRange
.getEndTime().getValue();
595 paramUpdater
.update(time0
, time1
, timeSpaceWidth
);
598 experimentManger
.readExperiment("flowView", this);
601 private void hookContextMenu() {
602 MenuManager menuMgr
= new MenuManager("#PopupMenu"); //$NON-NLS-1$
603 menuMgr
.setRemoveAllWhenShown(true);
604 menuMgr
.addMenuListener(new IMenuListener() {
605 public void menuAboutToShow(IMenuManager manager
) {
606 ControlFlowView
.this.fillContextMenu(manager
);
609 Menu menu
= menuMgr
.createContextMenu(tableViewer
.getControl());
610 tableViewer
.getControl().setMenu(menu
);
611 getSite().registerContextMenu(menuMgr
, tableViewer
);
614 private void contributeToActionBars() {
615 IActionBars bars
= getViewSite().getActionBars();
616 fillLocalPullDown(bars
.getMenuManager());
617 fillLocalToolBar(bars
.getToolBarManager());
620 private void fillLocalPullDown(IMenuManager manager
) {
621 manager
.add(new Separator());
622 // manager.add(showLegend);
623 manager
.add(new Separator());
624 manager
.add(resetScale
);
625 manager
.add(nextEvent
);
626 manager
.add(prevEvent
);
627 manager
.add(nextTrace
);
628 manager
.add(prevTrace
);
629 // manager.add(filterTraces);
631 manager
.add(zoomOut
);
633 manager
.add(new Separator());
636 private void fillContextMenu(IMenuManager manager
) {
637 // manager.add(showLegend);
638 manager
.add(new Separator());
639 manager
.add(resetScale
);
640 manager
.add(nextEvent
);
641 manager
.add(prevEvent
);
642 manager
.add(nextTrace
);
643 manager
.add(prevTrace
);
644 // manager.add(showLegend);
645 // manager.add(filterTraces);
647 manager
.add(zoomOut
);
649 manager
.add(new Separator());
650 manager
.add(new Separator(IWorkbenchActionConstants
.MB_ADDITIONS
));
653 private void fillLocalToolBar(IToolBarManager manager
) {
654 // manager.add(showLegend);
655 manager
.add(new Separator());
656 manager
.add(resetScale
);
657 manager
.add(nextEvent
);
658 manager
.add(prevEvent
);
659 manager
.add(nextTrace
);
660 manager
.add(prevTrace
);
661 // manager.add(filterTraces);
663 manager
.add(zoomOut
);
665 manager
.add(new Separator());
668 private void makeActions() {
670 resetScale
= new Action() {
673 if (tsfviewer
!= null) {
674 tsfviewer
.resetStartFinishTime();
679 resetScale
.setText(Messages
.getString("ControlFlowView.Action.Reset")); //$NON-NLS-1$
680 resetScale
.setToolTipText(Messages
681 .getString("ControlFlowView.Action.Reset.ToolTip")); //$NON-NLS-1$
682 resetScale
.setImageDescriptor(AbstractUIPlugin
683 .imageDescriptorFromPlugin(Messages
684 .getString("ControlFlowView.tmf.UI"),
685 "icons/home_nav.gif"));
688 nextEvent
= new Action() {
691 if (tsfviewer
!= null) {
692 tsfviewer
.selectNextEvent();
696 nextEvent
.setText(Messages
697 .getString("ControlFlowView.Action.NextEvent")); //$NON-NLS-1$
698 nextEvent
.setToolTipText(Messages
699 .getString("ControlFlowView.Action.NextEvent.Tooltip")); //$NON-NLS-1$
700 nextEvent
.setImageDescriptor(AbstractUIPlugin
701 .imageDescriptorFromPlugin(Messages
702 .getString("ControlFlowView.tmf.UI"),
703 "icons/next_event.gif"));
706 prevEvent
= new Action() {
709 if (tsfviewer
!= null) {
710 tsfviewer
.selectPrevEvent();
714 prevEvent
.setText(Messages
715 .getString("ControlFlowView.Action.PrevEvent")); //$NON-NLS-1$
716 prevEvent
.setToolTipText(Messages
717 .getString("ControlFlowView.Action.PrevEvent.Tooltip")); //$NON-NLS-1$
718 prevEvent
.setImageDescriptor(AbstractUIPlugin
719 .imageDescriptorFromPlugin(Messages
720 .getString("ControlFlowView.tmf.UI"),
721 "icons/prev_event.gif"));
724 nextTrace
= new Action() {
727 if (tsfviewer
!= null) {
728 tsfviewer
.selectNextTrace();
732 nextTrace
.setText(Messages
733 .getString("ControlFlowView.Action.NextProcess")); //$NON-NLS-1$
734 nextTrace
.setToolTipText(Messages
735 .getString("ControlFlowView.Action.NextProcess.ToolTip")); //$NON-NLS-1$
736 nextTrace
.setImageDescriptor(AbstractUIPlugin
737 .imageDescriptorFromPlugin(Messages
738 .getString("ControlFlowView.tmf.UI"),
739 "icons/next_item.gif"));
742 prevTrace
= new Action() {
745 if (tsfviewer
!= null) {
746 tsfviewer
.selectPrevTrace();
750 prevTrace
.setText(Messages
751 .getString("ControlFlowView.Action.PreviousProcess")); //$NON-NLS-1$
752 prevTrace
.setToolTipText(Messages
753 .getString("ControlFlowView.Action.PreviousProcess.Tooltip")); //$NON-NLS-1$
754 prevTrace
.setImageDescriptor(AbstractUIPlugin
755 .imageDescriptorFromPlugin(Messages
756 .getString("ControlFlowView.tmf.UI"),
757 "icons/prev_item.gif"));
760 showLegend
= new Action() {
763 if (tsfviewer
!= null) {
764 tsfviewer
.showLegend();
768 showLegend
.setText(Messages
.getString("ControlFlowView.Action.Legend")); //$NON-NLS-1$
769 showLegend
.setToolTipText(Messages
770 .getString("ControlFlowView.Action.Legend.ToolTip")); //$NON-NLS-1$
773 filterTraces
= new Action() {
776 if (tsfviewer
!= null) {
777 tsfviewer
.filterTraces();
781 filterTraces
.setText(Messages
782 .getString("ControlFlowView.Action.Filter")); //$NON-NLS-1$
783 filterTraces
.setToolTipText(Messages
784 .getString("ControlFlowView.Action.Filter.ToolTip")); //$NON-NLS-1$
785 filterTraces
.setImageDescriptor(AbstractUIPlugin
786 .imageDescriptorFromPlugin(Messages
787 .getString("ControlFlowView.tmf.UI"),
788 "icons/filter_items.gif"));
791 zoomIn
= new Action() {
794 if (tsfviewer
!= null) {
799 zoomIn
.setText(Messages
.getString("ControlFlowView.Action.ZoomIn")); //$NON-NLS-1$
800 zoomIn
.setToolTipText(Messages
801 .getString("ControlFlowView.Action.ZoomIn.Tooltip")); //$NON-NLS-1$
802 zoomIn
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(
803 Messages
.getString("ControlFlowView.tmf.UI"),
804 "icons/zoomin_nav.gif"));
807 zoomOut
= new Action() {
810 if (tsfviewer
!= null) {
815 zoomOut
.setText(Messages
.getString("ControlFlowView.Action.ZoomOut")); //$NON-NLS-1$
816 zoomOut
.setToolTipText(Messages
817 .getString("ControlFlowView.Action.ZoomOut.tooltip")); //$NON-NLS-1$
818 zoomOut
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(
819 Messages
.getString("ControlFlowView.tmf.UI"),
820 "icons/zoomout_nav.gif"));
823 synch
= new Action() {
826 // Note: No action since the synch flag is used by Control flow
828 // the actual viewer is set to accept api selections in
829 // createpartcontrol.
831 // if (synch.isChecked()) {
832 // tsfviewer.setAcceptSelectionAPIcalls(true);
834 // tsfviewer.setAcceptSelectionAPIcalls(false);
838 synch
.setText(Messages
.getString("ControlFlowView.Action.Synchronize")); //$NON-NLS-1$
839 synch
.setToolTipText(Messages
840 .getString("ControlFlowView.Action.Synchronize.ToolTip")); //$NON-NLS-1$
841 synch
.setChecked(false);
842 synch
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(
843 Messages
.getString("ControlFlowView.tmf.UI"),
844 "icons/synced.gif"));
845 // PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_ELCL_SYNCED);
847 doubleClickAction
= new Action() {
850 ISelection selection
= tableViewer
.getSelection();
851 Object obj
= ((IStructuredSelection
) selection
)
853 showMessage("Double-click detected on " + obj
.toString()); //$NON-NLS-1$
858 private void hookDoubleClickAction() {
859 tableViewer
.addDoubleClickListener(new IDoubleClickListener() {
860 public void doubleClick(DoubleClickEvent event
) {
861 doubleClickAction
.run();
866 private void showMessage(String message
) {
867 MessageDialog
.openInformation(tableViewer
.getControl().getShell(),
868 Messages
.getString("ControlFlowView.msgSlogan"), message
); //$NON-NLS-1$
872 * Passing the focus request to the viewer's control.
875 public void setFocus() {
876 tableViewer
.getControl().setFocus();
879 public void tsfTmProcessSelEvent(TmfTimeSelectionEvent event
) {
880 Object source
= event
.getSource();
881 if (source
== null) {
885 // Reselect the table viewer to widget selection
886 ISelection sel
= tsfviewer
.getSelectionTrace();
887 if (sel
!= null && !sel
.isEmpty()) {
888 tableViewer
.setSelection(sel
);
891 ParamsUpdater paramUpdater
= FlowModelFactory
.getParamsUpdater();
892 Long savedSelTime
= paramUpdater
.getSelectedTime();
894 long selTimens
= event
.getSelectedTime();
896 // make sure the new selected time is different than saved before
898 if (savedSelTime
== null || savedSelTime
!= selTimens
) {
899 // Notify listener views.
900 synchTimeNotification(selTimens
);
902 // Update the parameter updater to save the selected time
903 paramUpdater
.setSelectedTime(selTimens
);
905 if (TraceDebug
.isDEBUG()) {
906 // Object selection = event.getSelection();
907 TraceDebug
.debug("Selected Time in control Flow View: "
908 + new LttngTimestamp(selTimens
));
913 public synchronized void tsfTmProcessTimeScaleEvent(
914 TmfTimeScaleSelectionEvent event
) {
915 // source needed to keep track of source values
916 Object source
= event
.getSource();
918 if (source
!= null) {
919 // Update the parameter updater before carrying out a read request
920 ParamsUpdater paramUpdater
= FlowModelFactory
.getParamsUpdater();
921 boolean newParams
= paramUpdater
.processTimeScaleEvent(event
);
924 // Read the updated time window
925 TmfTimeRange trange
= paramUpdater
.getTrange();
926 if (trange
!= null) {
927 // Request new data for specified time range
935 * Obtains the remainder fraction on unit Seconds of the entered value in
936 * nanoseconds. e.g. input: 1241207054171080214 ns The number of seconds can
937 * be obtain by removing the last 9 digits: 1241207054 the fractional
938 * portion of seconds, expressed in ns is: 171080214
943 public String
formatNs(long v
) {
944 StringBuffer str
= new StringBuffer();
951 String strVal
= String
.valueOf(v
);
952 if (v
< 1000000000) {
956 // Extract the last nine digits (e.g. fraction of a S expressed in ns
957 return strVal
.substring(strVal
.length() - 9);
960 private void applyTableLayout(Table table
) {
961 for (int i
= 0; i
< columnNames
.length
; i
++) {
962 TableColumn tableColumn
= new TableColumn(table
, SWT
.LEFT
);
963 tableColumn
.setText(columnNames
[i
]);
966 table
.setHeaderVisible(true);
967 table
.setLinesVisible(true);
974 * @param updateTimeBounds - Update needed e.g. a new Experiment or trace selected
976 public void flowModelUpdates(final ITmfTimeAnalysisEntry
[] items
,
977 final long startTime
, final long endTime
,
978 final boolean updateTimeBounds
) {
979 final Table table
= tableViewer
.getTable();
980 Display display
= table
.getDisplay();
982 // Perform the updates on the UI thread)
983 display
.asyncExec(new Runnable() {
986 tableViewer
.setInput(items
); // This shall be the minimal
988 tableFilter
= new ViewProcessFilter(tableViewer
);
989 tableViewer
.setFilters(new ViewerFilter
[] { tableFilter
});
991 resizeTableColumns(table
);
993 tableViewer
.refresh();
995 tsfviewer
.display(items
, startTime
, endTime
, updateTimeBounds
);
996 tsfviewer
.resizeControls();
998 // Adjust the size of the vertical scroll bar to fit the
1000 if (scrollFrame
!= null && wrapper
!= null) {
1001 updateScrolls(scrollFrame
, wrapper
);
1002 // scrollFrame.update();
1009 public void dispose() {
1010 // dispose parent resources
1012 // Remove the event processor factory
1013 EventProcessorProxy
.getInstance().removeEventProcessorFactory(
1014 FlowTRangeUpdateFactory
.getInstance());
1016 // Remove listener to model updates
1017 // ModelListenFactory.getRegister().removeFlowModelUpdatesListener(this);
1018 tsfviewer
.removeFilterSelectionListner(this);
1019 tsfviewer
.removeWidgetSelectionListner(this);
1020 tsfviewer
.removeWidgetTimeScaleSelectionListner(this);
1026 * @param tableComposite
1029 private synchronized void resizeTableColumns(Table table
) {
1030 if (table
!= null) {
1031 Composite parent
= table
.getParent();
1032 int tableWidthSum
= parent
.getBorderWidth();
1034 TableColumn
[] columns
= table
.getColumns();
1035 for (TableColumn column
: columns
) {
1037 tableWidthSum
+= column
.getWidth();
1043 public void tmfTaProcessFilterSelection(TmfTimeFilterSelectionEvent event
) {
1044 if (tableFilter
!= null) {
1045 Vector
<ITmfTimeAnalysisEntry
> filteredout
= event
.getFilteredOut();
1046 if (filteredout
!= null) {
1047 tableFilter
.setFilter(filteredout
);
1049 tableFilter
.setFilter(new Vector
<ITmfTimeAnalysisEntry
>());
1051 tableViewer
.refresh();
1056 * @param scrollFrame
1059 private void updateScrolls(final ScrolledComposite scrollFrame
,
1060 final Composite wrapper
) {
1062 Point ptSize
= wrapper
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
);
1063 wrapper
.setSize(ptSize
);
1064 scrollFrame
.setMinSize(ptSize
);
1066 // calculate the increment area considering the table header height and
1068 Rectangle area
= top
.getBounds();
1069 int marginsHeight
= tableViewer
.getTable().getHeaderHeight();
1070 marginsHeight
-= top
.getBorderWidth() + wrapper
.getBorderWidth();
1071 area
.height
-= marginsHeight
;
1073 // set page vertical increment area
1074 ScrollBar verBar
= scrollFrame
.getVerticalBar();
1075 ScrollBar horBar
= scrollFrame
.getHorizontalBar();
1076 if (verBar
!= null) {
1077 verBar
.setPageIncrement(area
.height
);
1079 if (horBar
!= null) {
1080 horBar
.setPageIncrement(area
.width
);
1086 * Trigger time synchronisation to other views this method shall be called
1087 * when a check has been performed to note that an actual change of time has
1088 * been performed vs a pure re-selection of the same time
1092 private void synchTimeNotification(long time
) {
1093 // if synchronisation selected
1094 if (synch
.isChecked()) {
1095 // Notify other views
1096 TmfSignalManager
.dispatchSignal(new TmfTimeSynchSignal(this,
1097 new LttngTimestamp(time
)));
1102 * Registers as listener of time selection from other tmf views
1107 public void synchToTime(TmfTimeSynchSignal signal
) {
1108 if (synch
.isChecked()) {
1109 Object source
= signal
.getSource();
1110 if (signal
!= null && source
!= null && source
!= this) {
1111 // Internal value is expected in nano seconds.
1112 long selectedTime
= signal
.getCurrentTime().getValue();
1113 if (tsfviewer
!= null) {
1114 tsfviewer
.setSelectedTime(selectedTime
, true, source
);
1124 * org.eclipse.linuxtools.lttng.ui.views.common.LttngTimeUpdateView#waitCursor
1128 protected synchronized void waitCursor(final boolean waitInd
) {
1129 if (tsfviewer
!= null) {
1130 Display display
= tsfviewer
.getControl().getDisplay();
1132 // Perform the updates on the UI thread
1133 display
.asyncExec(new Runnable() {
1135 tsfviewer
.waitCursor(waitInd
);
1144 * @seeorg.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#
1145 * ModelUpdatePrep(java.lang.String, boolean)
1148 public void ModelUpdatePrep(String traceId
, boolean clearAllData
,
1149 TmfTimeRange trange
) {
1151 FlowModelFactory
.getProcContainer().clearProcesses();
1152 // Obtain the current process array
1153 TimeRangeEventProcess
[] processArr
= FlowModelFactory
1154 .getProcContainer().readProcesses();
1157 // initialise to an empty model
1158 flowModelUpdates(processArr
, -1, -1, false);
1160 FlowModelFactory
.getProcContainer().clearChildren(traceId
);
1163 ParamsUpdater updater
= FlowModelFactory
.getParamsUpdater();
1165 updater
.setEventsDiscarded(0);
1167 // Update new visible time range if available
1168 if (trange
!= null) {
1169 updater
.update(trange
.getStartTime().getValue(), trange
1170 .getEndTime().getValue());
1177 * @seeorg.eclipse.linuxtools.lttng.ui.views.common.LttngTimeUpdateView#
1178 * ModelUpdateComplete(org.eclipse.linuxtools.lttng.state.StateDataRequest)
1181 public void ModelUpdateComplete(StateDataRequest request
) {
1182 long experimentStartTime
= -1;
1183 long experimentEndTime
= -1;
1184 StateManager smanager
= request
.getStateManager();
1185 TmfTimeRange experimentTimeRange
= smanager
.getExperimentTimeWindow();
1186 if (experimentTimeRange
!= null) {
1187 experimentStartTime
= experimentTimeRange
.getStartTime().getValue();
1188 experimentEndTime
= experimentTimeRange
.getEndTime().getValue();
1190 // Obtain the current process array
1191 TimeRangeEventProcess
[] processArr
= FlowModelFactory
1192 .getProcContainer().readProcesses();
1193 // Sort the array by pid
1194 Arrays
.sort(processArr
);
1196 // Update the view part
1197 flowModelUpdates(processArr
, experimentStartTime
, experimentEndTime
,
1198 request
.isclearDataInd());
1200 // get back to user selected time if still within range
1201 ParamsUpdater paramUpdater
= FlowModelFactory
.getParamsUpdater();
1202 final Long selTime
= paramUpdater
.getSelectedTime();
1203 if (selTime
!= null) {
1204 Display display
= tsfviewer
.getControl().getDisplay();
1205 display
.asyncExec(new Runnable() {
1207 tsfviewer
.setSelectedTime(selTime
, false, this);
1212 if (TraceDebug
.isDEBUG()) {
1214 Long count
= smanager
.getEventCount();
1215 for ( int pos
= 0; pos
<processArr
.length
; pos
++ ) {
1216 eventCount
+= processArr
[pos
].getTraceEvents().size();
1219 int discarded
= FlowModelFactory
.getParamsUpdater()
1220 .getEventsDiscarded();
1221 int discardedOutofOrder
= FlowModelFactory
.getParamsUpdater()
1222 .getEventsDiscardedWrongOrder();
1223 TmfTimeRange range
= request
.getRange();
1224 StringBuilder sb
= new StringBuilder(
1227 + " Events loaded in Control Flow view: "
1229 + " Number of events discarded: "
1231 + "\n\tNumber of events discarded with start time earlier than next good time: "
1232 + discardedOutofOrder
);
1234 sb
.append("\n\t\tRequested Time Range: " + range
.getStartTime()
1235 + "-" + range
.getEndTime());
1236 sb
.append("\n\t\tExperiment Time Range: " + experimentStartTime
1237 + "-" + experimentEndTime
);
1238 TraceDebug
.debug(sb
.toString());
1246 public int checkForSWTBugItemHeightAdjustement() {
1247 int returnedAjustement
= 0;
1248 String desktopSessionName
= System
.getenv("DESKTOP_SESSION");
1250 // Gnome : most common case, no adjustement
1251 if ( desktopSessionName
.equals("gnome") ) {
1252 returnedAjustement
= 0;
1254 // Kde : ajustement of 2 is needed
1255 else if ( desktopSessionName
.equals("kde") ) {
1256 returnedAjustement
= 2;
1259 return returnedAjustement
;