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
.IStateDataRequestListener
;
38 import org
.eclipse
.linuxtools
.lttng
.state
.RequestCompletedSignal
;
39 import org
.eclipse
.linuxtools
.lttng
.state
.RequestStartedSignal
;
40 import org
.eclipse
.linuxtools
.lttng
.state
.StateDataRequest
;
41 import org
.eclipse
.linuxtools
.lttng
.state
.StateManager
;
42 import org
.eclipse
.linuxtools
.lttng
.state
.evProcessor
.EventProcessorProxy
;
43 import org
.eclipse
.linuxtools
.lttng
.state
.experiment
.StateExperimentManager
;
44 import org
.eclipse
.linuxtools
.lttng
.state
.experiment
.StateManagerFactory
;
45 import org
.eclipse
.linuxtools
.lttng
.ui
.TraceDebug
;
46 import org
.eclipse
.linuxtools
.lttng
.ui
.model
.trange
.TimeRangeEventProcess
;
47 import org
.eclipse
.linuxtools
.lttng
.ui
.model
.trange
.TimeRangeViewerProvider
;
48 import org
.eclipse
.linuxtools
.lttng
.ui
.views
.common
.ParamsUpdater
;
49 import org
.eclipse
.linuxtools
.lttng
.ui
.views
.controlflow
.evProcessor
.FlowTRangeUpdateFactory
;
50 import org
.eclipse
.linuxtools
.lttng
.ui
.views
.controlflow
.model
.FlowModelFactory
;
51 import org
.eclipse
.linuxtools
.lttng
.ui
.views
.resources
.model
.ResourceModelFactory
;
52 import org
.eclipse
.linuxtools
.tmf
.event
.TmfTimeRange
;
53 import org
.eclipse
.linuxtools
.tmf
.signal
.TmfSignalHandler
;
54 import org
.eclipse
.linuxtools
.tmf
.signal
.TmfSignalManager
;
55 import org
.eclipse
.linuxtools
.tmf
.signal
.TmfTimeSynchSignal
;
56 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.TmfViewerFactory
;
57 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.ITimeAnalysisViewer
;
58 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.ITmfTimeFilterSelectionListener
;
59 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.ITmfTimeScaleSelectionListener
;
60 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.ITmfTimeSelectionListener
;
61 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.TmfTimeFilterSelectionEvent
;
62 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.TmfTimeScaleSelectionEvent
;
63 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.TmfTimeSelectionEvent
;
64 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.model
.ITmfTimeAnalysisEntry
;
65 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.TmfView
;
66 import org
.eclipse
.swt
.SWT
;
67 import org
.eclipse
.swt
.custom
.SashForm
;
68 import org
.eclipse
.swt
.custom
.ScrolledComposite
;
69 import org
.eclipse
.swt
.events
.ControlAdapter
;
70 import org
.eclipse
.swt
.events
.ControlEvent
;
71 import org
.eclipse
.swt
.events
.ControlListener
;
72 import org
.eclipse
.swt
.events
.KeyEvent
;
73 import org
.eclipse
.swt
.events
.KeyListener
;
74 import org
.eclipse
.swt
.graphics
.Image
;
75 import org
.eclipse
.swt
.graphics
.Point
;
76 import org
.eclipse
.swt
.graphics
.Rectangle
;
77 import org
.eclipse
.swt
.layout
.FillLayout
;
78 import org
.eclipse
.swt
.widgets
.Composite
;
79 import org
.eclipse
.swt
.widgets
.Display
;
80 import org
.eclipse
.swt
.widgets
.Menu
;
81 import org
.eclipse
.swt
.widgets
.ScrollBar
;
82 import org
.eclipse
.swt
.widgets
.Table
;
83 import org
.eclipse
.swt
.widgets
.TableColumn
;
84 import org
.eclipse
.swt
.widgets
.TableItem
;
85 import org
.eclipse
.ui
.IActionBars
;
86 import org
.eclipse
.ui
.IWorkbenchActionConstants
;
87 import org
.eclipse
.ui
.PlatformUI
;
88 import org
.eclipse
.ui
.plugin
.AbstractUIPlugin
;
91 * <b><u>ControlFlowView</u></b>
93 * TODO: Implement me. Please.
95 public class ControlFlowView
extends TmfView
implements
96 ITmfTimeSelectionListener
, ITmfTimeScaleSelectionListener
,
97 ITmfTimeFilterSelectionListener
, IStateDataRequestListener
{
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 Vector
<StateDataRequest
> pendingDataRequests
= new Vector
<StateDataRequest
>();
130 private TableViewer tableViewer
;
131 // private int totalNumItems = 0;
133 private Action doubleClickAction
;
134 private Action resetScale
;
135 private Action nextEvent
;
136 private Action prevEvent
;
137 private Action nextTrace
;
138 private Action prevTrace
;
139 private Action showLegend
;
140 private Action filterTraces
;
141 private Action zoomIn
;
142 private Action zoomOut
;
143 private Action synch
;
145 private ITimeAnalysisViewer tsfviewer
;
146 private ViewProcessFilter tableFilter
= null;
147 private ScrolledComposite scrollFrame
= null;
148 private Composite wrapper
= null;
149 private Composite top
;
151 // private static SimpleDateFormat stimeformat = new SimpleDateFormat(
152 // "yy/MM/dd HH:mm:ss");
154 // private TraceModelImplFactory fact;
156 // ========================================================================
158 // ========================================================================
160 * The content provider class is responsible for providing objects to the
161 * view. It can wrap existing objects in adapters or simply return objects
162 * as-is. These objects may be sensitive to the current input of the view,
163 * or ignore it and always show the same content (like Task List, for
167 class ViewContentProvider
implements
168 /* ILazyContentProvider, */IStructuredContentProvider
{
169 private TableViewer cviewer
= null;
170 private ITmfTimeAnalysisEntry
[] elements
= null;
172 public ViewContentProvider(TableViewer v
) {
176 public void inputChanged(Viewer v
, Object oldInput
, Object newInput
) {
177 this.elements
= (ITmfTimeAnalysisEntry
[]) newInput
;
178 if (elements
!= null) {
180 .debug("Total number of processes provided to Control Flow view: "
183 TraceDebug
.debug("New input = null");
187 public void dispose() {
191 // Needed with the use of virtual tables in order to initialize items
192 // which were not initially visible.
193 public void updateElement(int index
) {
194 cviewer
.replace(elements
[index
], index
);
198 public Object
[] getElements(Object inputElement
) {
199 // TODO Auto-generated method stub
204 class ViewLabelProvider
extends LabelProvider
implements
205 ITableLabelProvider
{
206 public String
getColumnText(Object obj
, int index
) {
207 String strRes
= ""; //$NON-NLS-1$
209 if (obj
instanceof TimeRangeEventProcess
) {
210 TimeRangeEventProcess process
= (TimeRangeEventProcess
) obj
;
213 strRes
= process
.getName();
216 strRes
= process
.getBrand();
219 strRes
= process
.getPid().toString();
222 strRes
= process
.getTgid().toString();
225 strRes
= process
.getPpid().toString();
228 strRes
= process
.getCpu().toString();
231 time
= new LttngTimestamp(process
.getCreationTime()
233 strRes
= time
.getSeconds();
236 time
= new LttngTimestamp(process
.getCreationTime()
238 strRes
= time
.getNanoSeconds();
241 strRes
= process
.getTraceID();
253 public Image
getColumnImage(Object obj
, int index
) {
254 return getImage(obj
);
258 public Image
getImage(Object obj
) {
259 // No image needed for the time being
260 // return PlatformUI.getWorkbench().getSharedImages().getImage(
261 // ISharedImages.IMG_OBJ_ELEMENT);
266 class ViewProcessFilter
extends ViewerFilter
{
268 private Vector
<ITmfTimeAnalysisEntry
> filteredSet
= new Vector
<ITmfTimeAnalysisEntry
>();
269 StructuredViewer viewer
;
271 public ViewProcessFilter(StructuredViewer rviewer
) {
272 this.viewer
= rviewer
;
275 public void setFilter(Vector
<ITmfTimeAnalysisEntry
> filtered
) {
276 if (filtered
!= null) {
277 this.filteredSet
= filtered
;
283 public boolean select(Viewer viewer
, Object parentElement
,
285 boolean filteredIn
= true;
286 if (element
instanceof ITmfTimeAnalysisEntry
) {
287 ITmfTimeAnalysisEntry process
= (ITmfTimeAnalysisEntry
) element
;
288 if (filteredSet
.contains(process
)) {
289 // The element is marked to be filtered out
293 TraceDebug
.debug("Unexpected type of filter element received: "
294 + element
.toString());
296 // Compare element versus a list of filtered out
304 public ControlFlowView() {
308 * This is a callback that will allow us to create the viewer and initialize
312 public void createPartControl(Composite parent
) {
313 top
= new Composite(parent
, SWT
.BORDER
);
315 top
.setLayout(new FillLayout());
317 scrollFrame
= new ScrolledComposite(top
, SWT
.V_SCROLL
| SWT
.H_SCROLL
);
318 scrollFrame
.setBounds(top
.getClientArea());
320 wrapper
= new Composite(scrollFrame
, SWT
.NONE
);
321 scrollFrame
.setEnabled(true);
322 scrollFrame
.setRedraw(true);
323 scrollFrame
.setExpandVertical(true);
324 scrollFrame
.setExpandHorizontal(true);
325 scrollFrame
.setContent(wrapper
);
326 scrollFrame
.setAlwaysShowScrollBars(true);
327 wrapper
.setLayout(new FillLayout());
329 SashForm sash
= new SashForm(wrapper
, SWT
.NONE
);
330 final Composite tableComposite
= new Composite(sash
, SWT
.NO_SCROLL
);
331 FillLayout layout
= new FillLayout();
332 tableComposite
.setLayout(layout
);
333 tableViewer
= new TableViewer(tableComposite
, SWT
.FULL_SELECTION
335 tableViewer
.setContentProvider(new ViewContentProvider(tableViewer
));
336 tableViewer
.setLabelProvider(new ViewLabelProvider());
337 Table table
= tableViewer
.getTable();
339 .addSelectionChangedListener(new ISelectionChangedListener() {
340 public void selectionChanged(SelectionChangedEvent event
) {
341 ISelection sel
= event
.getSelection();
342 if (!sel
.isEmpty()) {
343 Object firstSel
= null;
344 if (sel
instanceof IStructuredSelection
) {
345 firstSel
= ((IStructuredSelection
) sel
)
348 // Make sure the selection is visible
349 updateScrollOrigin();
351 if (firstSel
instanceof ITmfTimeAnalysisEntry
) {
352 ITmfTimeAnalysisEntry trace
= (ITmfTimeAnalysisEntry
) firstSel
;
353 tsfviewer
.setSelectedTrace(trace
);
360 * Make sure the selected item is visible
362 private void updateScrollOrigin() {
363 Table table
= tableViewer
.getTable();
364 if (table
!= null && table
.getItemCount() > 0) {
365 TableItem item
= table
.getSelection()[0];
367 // no selected reference to go up or down
371 Rectangle itemRect
= item
.getBounds();
372 int step
= itemRect
.height
;
374 // calculate height of horizontal bar
376 ScrollBar hbar
= scrollFrame
.getHorizontalBar();
378 hscrolly
= hbar
.getSize().y
;
381 int visibleHeight
= scrollFrame
.getSize().y
384 // the current scrollbar offset to adjust i.e. start
386 // the visible window
387 Point origin
= scrollFrame
.getOrigin();
388 // end of visible window
389 int endy
= origin
.y
+ visibleHeight
;
391 int itemStartPos
= itemRect
.y
392 + table
.getHeaderHeight()
393 + table
.getBorderWidth()
394 + table
.getParent().getBorderWidth();
397 int itemEndPos
= itemStartPos
+ step
;
399 // check if need to go up
400 if (origin
.y
>= step
&& itemStartPos
< origin
.y
) {
403 .setOrigin(origin
.x
, origin
.y
- step
);
407 // check if it needs to go down
408 if (itemEndPos
> endy
) {
411 .setOrigin(origin
.x
, origin
.y
+ step
);
418 // Listen to page up /down and Home / Enc keys
419 tableViewer
.getTable().addKeyListener(new KeyListener() {
420 public void keyPressed(KeyEvent e
) {
421 Table table
= tableViewer
.getTable();
422 Point origin
= scrollFrame
.getOrigin();
423 if (table
== null || table
.getItemCount() < 1) {
433 updateScrollPageDown();
440 count
= table
.getItemCount();
441 item
= table
.getItem(0);
443 scrollFrame
.setOrigin(origin
.x
, 0);
447 count
= table
.getItemCount();
448 item
= table
.getItem(count
- 1);
449 int itemStartPos
= item
.getBounds().y
;
451 scrollFrame
.setOrigin(origin
.x
, itemStartPos
);
458 public void keyReleased(KeyEvent e
) {
464 * Scroll one page down
466 private void updateScrollPageDown() {
467 // null protection before calling private method
468 Table table
= tableViewer
.getTable();
469 int step
= table
.getItemHeight();
472 ScrollBar hbar
= scrollFrame
.getHorizontalBar();
474 hscrolly
= hbar
.getSize().y
;
477 Point origin
= scrollFrame
.getOrigin();
478 int visibleHeight
= scrollFrame
.getSize().y
- hscrolly
;
479 int endy
= origin
.y
+ visibleHeight
;
481 scrollFrame
.setOrigin(origin
.x
, endy
- step
);
487 private void updateScrollUp() {
488 // null protection before calling private method
489 Table table
= tableViewer
.getTable();
490 int step
= table
.getItemHeight();
493 ScrollBar hbar
= scrollFrame
.getHorizontalBar();
495 hscrolly
= hbar
.getSize().y
;
498 Point origin
= scrollFrame
.getOrigin();
499 int visibleHeight
= scrollFrame
.getSize().y
- hscrolly
;
500 int pageUpPos
= origin
.y
- visibleHeight
+ step
;
501 pageUpPos
= pageUpPos
> 0 ? pageUpPos
: 0;
502 scrollFrame
.setOrigin(origin
.x
, pageUpPos
);
507 applyTableLayout(table
);
509 int borderWidth
= table
.getBorderWidth();
511 int itemHeight
= table
.getItemHeight();
512 int headerHeight
= table
.getHeaderHeight();
513 table
.getVerticalBar().setVisible(false);
515 tsfviewer
= TmfViewerFactory
.createViewer(sash
,
516 new TimeRangeViewerProvider());
518 tsfviewer
.addWidgetSelectionListner(this);
519 tsfviewer
.addWidgetTimeScaleSelectionListner(this);
521 // Traces shall not be grouped to allow synchronization
522 tsfviewer
.groupTraces(false);
523 tsfviewer
.setItemHeight(itemHeight
);
524 tsfviewer
.setBorderWidth(borderWidth
);
525 tsfviewer
.setHeaderHeight(headerHeight
);
526 tsfviewer
.setVisibleVerticalScroll(false);
527 // Names provided by the table
528 tsfviewer
.setNameWidthPref(0);
529 tsfviewer
.setAcceptSelectionAPIcalls(true);
531 // Viewer to notify selection to this class
532 // This class will synchronize selections with table.
533 tsfviewer
.addWidgetSelectionListner(this);
534 tsfviewer
.addFilterSelectionListner(this);
535 tsfviewer
.addWidgetTimeScaleSelectionListner(this);
537 sash
.setWeights(new int[] { 1, 1 });
538 // Create the help context id for the viewer's control
539 // TODO: Associate with help system
540 PlatformUI
.getWorkbench().getHelpSystem().setHelp(
541 tableViewer
.getControl(),
542 "org.eclipse.linuxtools.lttnng.ui.views.flow.viewer"); //$NON-NLS-1$
546 hookDoubleClickAction();
547 contributeToActionBars();
549 scrollFrame
.addControlListener(new ControlAdapter() {
551 public void controlResized(ControlEvent e
) {
552 tsfviewer
.resizeControls();
553 updateScrolls(scrollFrame
, wrapper
);
557 tableComposite
.addControlListener(new ControlListener() {
558 public void controlResized(ControlEvent e
) {
559 scrollFrame
.getParent().update();
562 public void controlMoved(ControlEvent e
) {
567 // Register the updater in charge to refresh elements as we update the
569 // FlowParamsUpdater listener = FlowModelFactory.getParamsUpdater();
570 // tsfviewer.addWidgetTimeScaleSelectionListner(listener);
572 // Register this view to receive updates when the model is updated with
574 // ModelListenFactory.getRegister().addFlowModelUpdatesListener(this);
576 // Register the event processor factory in charge of event handling
577 EventProcessorProxy
.getInstance().addEventProcessorFactory(
578 FlowTRangeUpdateFactory
.getInstance());
580 // set the initial view parameter values
581 // Experiment start and end time
582 // as well as time space width in pixels, used by the time analysis
584 ParamsUpdater paramUpdater
= FlowModelFactory
.getParamsUpdater();
585 StateExperimentManager experimentManger
= StateManagerFactory
586 .getExperimentManager();
587 // Read relevant values
588 int timeSpaceWidth
= tsfviewer
.getTimeSpace();
589 TmfTimeRange timeRange
= experimentManger
.getExperimentTimeRange();
590 if (timeRange
!= null) {
591 long time0
= timeRange
.getStartTime().getValue();
592 long time1
= timeRange
.getEndTime().getValue();
593 paramUpdater
.update(time0
, time1
, timeSpaceWidth
);
596 experimentManger
.readExperiment("flowView", this);
599 private void hookContextMenu() {
600 MenuManager menuMgr
= new MenuManager("#PopupMenu"); //$NON-NLS-1$
601 menuMgr
.setRemoveAllWhenShown(true);
602 menuMgr
.addMenuListener(new IMenuListener() {
603 public void menuAboutToShow(IMenuManager manager
) {
604 ControlFlowView
.this.fillContextMenu(manager
);
607 Menu menu
= menuMgr
.createContextMenu(tableViewer
.getControl());
608 tableViewer
.getControl().setMenu(menu
);
609 getSite().registerContextMenu(menuMgr
, tableViewer
);
612 private void contributeToActionBars() {
613 IActionBars bars
= getViewSite().getActionBars();
614 fillLocalPullDown(bars
.getMenuManager());
615 fillLocalToolBar(bars
.getToolBarManager());
618 private void fillLocalPullDown(IMenuManager manager
) {
619 manager
.add(new Separator());
620 // manager.add(showLegend);
621 manager
.add(new Separator());
622 manager
.add(resetScale
);
623 manager
.add(nextEvent
);
624 manager
.add(prevEvent
);
625 manager
.add(nextTrace
);
626 manager
.add(prevTrace
);
627 // manager.add(filterTraces);
629 manager
.add(zoomOut
);
631 manager
.add(new Separator());
634 private void fillContextMenu(IMenuManager manager
) {
635 // manager.add(showLegend);
636 manager
.add(new Separator());
637 manager
.add(resetScale
);
638 manager
.add(nextEvent
);
639 manager
.add(prevEvent
);
640 manager
.add(nextTrace
);
641 manager
.add(prevTrace
);
642 // manager.add(showLegend);
643 // manager.add(filterTraces);
645 manager
.add(zoomOut
);
647 manager
.add(new Separator());
648 manager
.add(new Separator(IWorkbenchActionConstants
.MB_ADDITIONS
));
651 private void fillLocalToolBar(IToolBarManager manager
) {
652 // manager.add(showLegend);
653 manager
.add(new Separator());
654 manager
.add(resetScale
);
655 manager
.add(nextEvent
);
656 manager
.add(prevEvent
);
657 manager
.add(nextTrace
);
658 manager
.add(prevTrace
);
659 // manager.add(filterTraces);
661 manager
.add(zoomOut
);
663 manager
.add(new Separator());
666 private void makeActions() {
668 resetScale
= new Action() {
671 if (tsfviewer
!= null) {
672 tsfviewer
.resetStartFinishTime();
677 resetScale
.setText(Messages
.getString("ControlFlowView.Action.Reset")); //$NON-NLS-1$
678 resetScale
.setToolTipText(Messages
679 .getString("ControlFlowView.Action.Reset.ToolTip")); //$NON-NLS-1$
680 resetScale
.setImageDescriptor(AbstractUIPlugin
681 .imageDescriptorFromPlugin(Messages
682 .getString("ControlFlowView.tmf.UI"),
683 "icons/home_nav.gif"));
686 nextEvent
= new Action() {
689 if (tsfviewer
!= null) {
690 tsfviewer
.selectNextEvent();
694 nextEvent
.setText(Messages
695 .getString("ControlFlowView.Action.NextEvent")); //$NON-NLS-1$
696 nextEvent
.setToolTipText(Messages
697 .getString("ControlFlowView.Action.NextEvent.Tooltip")); //$NON-NLS-1$
698 nextEvent
.setImageDescriptor(AbstractUIPlugin
699 .imageDescriptorFromPlugin(Messages
700 .getString("ControlFlowView.tmf.UI"),
701 "icons/next_event.gif"));
704 prevEvent
= new Action() {
707 if (tsfviewer
!= null) {
708 tsfviewer
.selectPrevEvent();
712 prevEvent
.setText(Messages
713 .getString("ControlFlowView.Action.PrevEvent")); //$NON-NLS-1$
714 prevEvent
.setToolTipText(Messages
715 .getString("ControlFlowView.Action.PrevEvent.Tooltip")); //$NON-NLS-1$
716 prevEvent
.setImageDescriptor(AbstractUIPlugin
717 .imageDescriptorFromPlugin(Messages
718 .getString("ControlFlowView.tmf.UI"),
719 "icons/prev_event.gif"));
722 nextTrace
= new Action() {
725 if (tsfviewer
!= null) {
726 tsfviewer
.selectNextTrace();
730 nextTrace
.setText(Messages
731 .getString("ControlFlowView.Action.NextProcess")); //$NON-NLS-1$
732 nextTrace
.setToolTipText(Messages
733 .getString("ControlFlowView.Action.NextProcess.ToolTip")); //$NON-NLS-1$
734 nextTrace
.setImageDescriptor(AbstractUIPlugin
735 .imageDescriptorFromPlugin(Messages
736 .getString("ControlFlowView.tmf.UI"),
737 "icons/next_item.gif"));
740 prevTrace
= new Action() {
743 if (tsfviewer
!= null) {
744 tsfviewer
.selectPrevTrace();
748 prevTrace
.setText(Messages
749 .getString("ControlFlowView.Action.PreviousProcess")); //$NON-NLS-1$
750 prevTrace
.setToolTipText(Messages
751 .getString("ControlFlowView.Action.PreviousProcess.Tooltip")); //$NON-NLS-1$
752 prevTrace
.setImageDescriptor(AbstractUIPlugin
753 .imageDescriptorFromPlugin(Messages
754 .getString("ControlFlowView.tmf.UI"),
755 "icons/prev_item.gif"));
758 showLegend
= new Action() {
761 if (tsfviewer
!= null) {
762 tsfviewer
.showLegend();
766 showLegend
.setText(Messages
.getString("ControlFlowView.Action.Legend")); //$NON-NLS-1$
767 showLegend
.setToolTipText(Messages
768 .getString("ControlFlowView.Action.Legend.ToolTip")); //$NON-NLS-1$
771 filterTraces
= new Action() {
774 if (tsfviewer
!= null) {
775 tsfviewer
.filterTraces();
779 filterTraces
.setText(Messages
780 .getString("ControlFlowView.Action.Filter")); //$NON-NLS-1$
781 filterTraces
.setToolTipText(Messages
782 .getString("ControlFlowView.Action.Filter.ToolTip")); //$NON-NLS-1$
783 filterTraces
.setImageDescriptor(AbstractUIPlugin
784 .imageDescriptorFromPlugin(Messages
785 .getString("ControlFlowView.tmf.UI"),
786 "icons/filter_items.gif"));
789 zoomIn
= new Action() {
792 if (tsfviewer
!= null) {
797 zoomIn
.setText(Messages
.getString("ControlFlowView.Action.ZoomIn")); //$NON-NLS-1$
798 zoomIn
.setToolTipText(Messages
799 .getString("ControlFlowView.Action.ZoomIn.Tooltip")); //$NON-NLS-1$
800 zoomIn
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(
801 Messages
.getString("ControlFlowView.tmf.UI"),
802 "icons/zoomin_nav.gif"));
805 zoomOut
= new Action() {
808 if (tsfviewer
!= null) {
813 zoomOut
.setText(Messages
.getString("ControlFlowView.Action.ZoomOut")); //$NON-NLS-1$
814 zoomOut
.setToolTipText(Messages
815 .getString("ControlFlowView.Action.ZoomOut.tooltip")); //$NON-NLS-1$
816 zoomOut
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(
817 Messages
.getString("ControlFlowView.tmf.UI"),
818 "icons/zoomout_nav.gif"));
821 synch
= new Action() {
824 // Note: No action since the synch flag is used by Control flow
826 // the actual viewer is set to accept api selections in
827 // createpartcontrol.
829 // if (synch.isChecked()) {
830 // tsfviewer.setAcceptSelectionAPIcalls(true);
832 // tsfviewer.setAcceptSelectionAPIcalls(false);
836 synch
.setText(Messages
.getString("ControlFlowView.Action.Synchronize")); //$NON-NLS-1$
837 synch
.setToolTipText(Messages
838 .getString("ControlFlowView.Action.Synchronize.ToolTip")); //$NON-NLS-1$
839 synch
.setChecked(false);
840 synch
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(
841 Messages
.getString("ControlFlowView.tmf.UI"),
842 "icons/synced.gif"));
843 // PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_ELCL_SYNCED);
845 doubleClickAction
= new Action() {
848 ISelection selection
= tableViewer
.getSelection();
849 Object obj
= ((IStructuredSelection
) selection
)
851 showMessage("Double-click detected on " + obj
.toString()); //$NON-NLS-1$
856 private void hookDoubleClickAction() {
857 tableViewer
.addDoubleClickListener(new IDoubleClickListener() {
858 public void doubleClick(DoubleClickEvent event
) {
859 doubleClickAction
.run();
864 private void showMessage(String message
) {
865 MessageDialog
.openInformation(tableViewer
.getControl().getShell(),
866 Messages
.getString("ControlFlowView.msgSlogan"), message
); //$NON-NLS-1$
870 * Passing the focus request to the viewer's control.
873 public void setFocus() {
874 tableViewer
.getControl().setFocus();
877 public void tsfTmProcessSelEvent(TmfTimeSelectionEvent event
) {
878 Object source
= event
.getSource();
879 if (source
== null) {
883 // Reselect the table viewer to widget selection
884 ISelection sel
= tsfviewer
.getSelectionTrace();
885 if (sel
!= null && !sel
.isEmpty()) {
886 tableViewer
.setSelection(sel
);
889 ParamsUpdater paramUpdater
= ResourceModelFactory
.getParamsUpdater();
890 Long savedSelTime
= paramUpdater
.getSelectedTime();
892 long selTimens
= event
.getSelectedTime();
894 // make sure the new selected time is different than saved before
896 if (savedSelTime
== null || savedSelTime
!= selTimens
) {
897 // Notify listener views.
898 synchTimeNotification(selTimens
);
900 // Update the parameter updater to save the selected time
901 paramUpdater
.setSelectedTime(selTimens
);
903 if (TraceDebug
.isDEBUG()) {
904 // Object selection = event.getSelection();
905 TraceDebug
.debug("Selected Time in control Flow View: "
906 + new LttngTimestamp(selTimens
));
911 public void tsfTmProcessTimeScaleEvent(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 StateManagerFactory
.getExperimentManager()
925 .readExperimentTimeWindow(trange
, "flowView", this);
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);
968 public void flowModelUpdates(final ITmfTimeAnalysisEntry
[] items
,
969 final long startTime
, final long endTime
) {
970 final Table table
= tableViewer
.getTable();
971 Display display
= table
.getDisplay();
973 // Perform the updates on the UI thread
974 display
.asyncExec(new Runnable() {
976 tableViewer
.setInput(items
); // This shall be the minimal
978 tableFilter
= new ViewProcessFilter(tableViewer
);
979 tableViewer
.setFilters(new ViewerFilter
[] { tableFilter
});
981 resizeTableColumns(table
);
983 tableViewer
.refresh();
985 tsfviewer
.display(items
, startTime
, endTime
);
986 tsfviewer
.resizeControls();
988 // Adjust the size of the vertical scroll bar to fit the
990 if (scrollFrame
!= null && wrapper
!= null) {
991 updateScrolls(scrollFrame
, wrapper
);
992 // scrollFrame.update();
999 public void dispose() {
1000 // dispose parent resources
1002 // Remove the event processor factory
1003 EventProcessorProxy
.getInstance().removeEventProcessorFactory(
1004 FlowTRangeUpdateFactory
.getInstance());
1006 // Remove listener to model updates
1007 // ModelListenFactory.getRegister().removeFlowModelUpdatesListener(this);
1008 tsfviewer
.removeFilterSelectionListner(this);
1009 tsfviewer
.removeWidgetSelectionListner(this);
1010 tsfviewer
.removeWidgetTimeScaleSelectionListner(this);
1016 * @param tableComposite
1019 private synchronized void resizeTableColumns(Table table
) {
1020 if (table
!= null) {
1021 Composite parent
= table
.getParent();
1022 int tableWidthSum
= parent
.getBorderWidth();
1024 TableColumn
[] columns
= table
.getColumns();
1025 for (TableColumn column
: columns
) {
1027 tableWidthSum
+= column
.getWidth();
1033 public void tmfTaProcessFilterSelection(TmfTimeFilterSelectionEvent event
) {
1034 if (tableFilter
!= null) {
1035 Vector
<ITmfTimeAnalysisEntry
> filteredout
= event
.getFilteredOut();
1036 if (filteredout
!= null) {
1037 tableFilter
.setFilter(filteredout
);
1039 tableFilter
.setFilter(new Vector
<ITmfTimeAnalysisEntry
>());
1041 tableViewer
.refresh();
1048 * @seeorg.eclipse.linuxtools.lttng.state.IStateDataRequestListener#
1049 * processingCompleted(org.eclipse.linuxtools.lttng.state.StateDataRequest)
1052 public void processingCompleted(RequestCompletedSignal signal
) {
1053 StateDataRequest request
= signal
.getRequest();
1055 if (request
== null) {
1058 // Remove from the pending requests record
1059 pendingDataRequests
.remove(request
);
1062 // No data refresh actions for cancelled requests.
1063 if (request
.isCancelled() || request
.isFailed()) {
1064 if (TraceDebug
.isDEBUG()) {
1065 TmfTimeRange range
= request
.getRange();
1066 TraceDebug
.debug("Request cancelled: "
1067 + range
.getStartTime().toString() + " - "
1068 + range
.getEndTime().toString());
1074 long experimentStartTime
= -1;
1075 long experimentEndTime
= -1;
1076 StateManager smanager
= request
.getStateManager();
1077 TmfTimeRange experimentTimeRange
= smanager
.getExperimentTimeWindow();
1078 if (experimentTimeRange
!= null) {
1079 experimentStartTime
= experimentTimeRange
.getStartTime().getValue();
1080 experimentEndTime
= experimentTimeRange
.getEndTime().getValue();
1083 // Obtain the current process list
1084 Vector
<TimeRangeEventProcess
> processList
= FlowModelFactory
1085 .getProcContainer().readProcesses();
1086 // convert it to an Array as expected by the widget
1087 TimeRangeEventProcess
[] processArr
= processList
1088 .toArray(new TimeRangeEventProcess
[processList
.size()]);
1089 // Sort the array by pid
1090 Arrays
.sort(processArr
);
1092 // Update the view part
1093 flowModelUpdates(processArr
, experimentStartTime
, experimentEndTime
);
1095 // reselect to original time
1096 ParamsUpdater paramUpdater
= ResourceModelFactory
.getParamsUpdater();
1097 final Long selTime
= paramUpdater
.getSelectedTime();
1098 if (selTime
!= null) {
1099 Display display
= tsfviewer
.getControl().getDisplay();
1100 display
.asyncExec(new Runnable() {
1102 tsfviewer
.setSelectedTime(selTime
, false, this);
1107 if (TraceDebug
.isDEBUG()) {
1109 Long count
= smanager
.getEventCount();
1110 for (TimeRangeEventProcess process
: processList
) {
1111 eventCount
+= process
.getTraceEvents().size();
1114 int discarded
= FlowModelFactory
.getParamsUpdater()
1115 .getEventsDiscarded();
1116 int discardedOutofOrder
= ResourceModelFactory
.getParamsUpdater()
1117 .getEventsDiscardedWrongOrder();
1119 .debug("Events handled: "
1121 + " Events loaded in Control Flow view: "
1123 + " Number of events discarded: "
1125 + "\n\tNumber of events discarded with start time earlier than next good time: "
1126 + discardedOutofOrder
);
1133 * @seeorg.eclipse.linuxtools.lttng.state.IStateDataRequestListener#
1134 * processingStarted(org.eclipse.linuxtools.lttng.state.StateDataRequest)
1137 public void processingStarted(RequestStartedSignal signal
) {
1138 StateDataRequest request
= signal
.getRequest();
1139 cancelPendingRequests();
1140 if (request
!= null) {
1141 // make sure there are no duplicates
1142 if (!pendingDataRequests
.contains(request
)) {
1143 pendingDataRequests
.add(request
);
1145 pendingDataRequests
.add(request
);
1146 StateManager smanager
= request
.getStateManager();
1147 // Clear the children on the Processes related to this manager.
1148 // Leave the GUI in charge of the updated data.
1149 String traceId
= smanager
.getEventLog().getName();
1150 FlowModelFactory
.getProcContainer().clearChildren(traceId
);
1152 FlowModelFactory
.getParamsUpdater().setEventsDiscarded(0);
1157 * Orders cancellation of any pending data requests
1159 private void cancelPendingRequests() {
1160 for (StateDataRequest request
: pendingDataRequests
) {
1163 pendingDataRequests
.clear();
1167 * @param scrollFrame
1170 private void updateScrolls(final ScrolledComposite scrollFrame
,
1171 final Composite wrapper
) {
1173 Point ptSize
= wrapper
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
);
1174 wrapper
.setSize(ptSize
);
1175 scrollFrame
.setMinSize(ptSize
);
1177 // calculate the increment area considering the table header height and
1179 Rectangle area
= top
.getBounds();
1180 int marginsHeight
= tableViewer
.getTable().getHeaderHeight();
1181 marginsHeight
-= top
.getBorderWidth() + wrapper
.getBorderWidth();
1182 area
.height
-= marginsHeight
;
1184 // set page vertical increment area
1185 ScrollBar verBar
= scrollFrame
.getVerticalBar();
1186 ScrollBar horBar
= scrollFrame
.getHorizontalBar();
1187 if (verBar
!= null) {
1188 verBar
.setPageIncrement(area
.height
);
1190 if (horBar
!= null) {
1191 horBar
.setPageIncrement(area
.width
);
1197 * Trigger time synchronisation to other views this method shall be called
1198 * when a check has been performed to note that an actual change of time has
1199 * been performed vs a pure re-selection of the same time
1203 private void synchTimeNotification(long time
) {
1204 // if synchronisation selected
1205 if (synch
.isChecked()) {
1206 // Notify other views
1207 TmfSignalManager
.dispatchSignal(new TmfTimeSynchSignal(this,
1208 new LttngTimestamp(time
)));
1213 * Registers as listener of time selection from other tmf views
1218 public void synchToTime(TmfTimeSynchSignal signal
) {
1219 if (synch
.isChecked()) {
1220 Object source
= signal
.getSource();
1221 if (signal
!= null && source
!= null && source
!= this) {
1222 // Internal value is expected in nano seconds.
1223 long selectedTime
= signal
.getCurrentTime().getValue();
1224 if (tsfviewer
!= null) {
1225 tsfviewer
.setSelectedTime(selectedTime
, true, source
);