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
.resources
;
13 import java
.util
.Arrays
;
15 import org
.eclipse
.jface
.action
.Action
;
16 import org
.eclipse
.jface
.action
.IMenuListener
;
17 import org
.eclipse
.jface
.action
.IMenuManager
;
18 import org
.eclipse
.jface
.action
.IToolBarManager
;
19 import org
.eclipse
.jface
.action
.MenuManager
;
20 import org
.eclipse
.jface
.action
.Separator
;
21 import org
.eclipse
.linuxtools
.lttng
.event
.LttngTimestamp
;
22 import org
.eclipse
.linuxtools
.lttng
.state
.StateDataRequest
;
23 import org
.eclipse
.linuxtools
.lttng
.state
.StateManager
;
24 import org
.eclipse
.linuxtools
.lttng
.state
.evProcessor
.EventProcessorProxy
;
25 import org
.eclipse
.linuxtools
.lttng
.state
.experiment
.StateExperimentManager
;
26 import org
.eclipse
.linuxtools
.lttng
.state
.experiment
.StateManagerFactory
;
27 import org
.eclipse
.linuxtools
.lttng
.ui
.TraceDebug
;
28 import org
.eclipse
.linuxtools
.lttng
.ui
.model
.trange
.TimeRangeEventResource
;
29 import org
.eclipse
.linuxtools
.lttng
.ui
.model
.trange
.TimeRangeViewerProvider
;
30 import org
.eclipse
.linuxtools
.lttng
.ui
.views
.common
.AbsTimeUpdateView
;
31 import org
.eclipse
.linuxtools
.lttng
.ui
.views
.common
.ParamsUpdater
;
32 import org
.eclipse
.linuxtools
.lttng
.ui
.views
.resources
.evProcessor
.ResourcesTRangeUpdateFactory
;
33 import org
.eclipse
.linuxtools
.lttng
.ui
.views
.resources
.model
.ResourceModelFactory
;
34 import org
.eclipse
.linuxtools
.tmf
.event
.TmfTimeRange
;
35 import org
.eclipse
.linuxtools
.tmf
.signal
.TmfRangeSynchSignal
;
36 import org
.eclipse
.linuxtools
.tmf
.signal
.TmfSignalHandler
;
37 import org
.eclipse
.linuxtools
.tmf
.signal
.TmfSignalManager
;
38 import org
.eclipse
.linuxtools
.tmf
.signal
.TmfTimeSynchSignal
;
39 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.TmfViewerFactory
;
40 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.ITimeAnalysisViewer
;
41 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.ITmfTimeScaleSelectionListener
;
42 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.ITmfTimeSelectionListener
;
43 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.TmfTimeScaleSelectionEvent
;
44 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.TmfTimeSelectionEvent
;
45 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.model
.ITmfTimeAnalysisEntry
;
46 import org
.eclipse
.swt
.SWT
;
47 import org
.eclipse
.swt
.layout
.FillLayout
;
48 import org
.eclipse
.swt
.widgets
.Composite
;
49 import org
.eclipse
.swt
.widgets
.Display
;
50 import org
.eclipse
.swt
.widgets
.Menu
;
51 import org
.eclipse
.ui
.IActionBars
;
52 import org
.eclipse
.ui
.IWorkbenchActionConstants
;
53 import org
.eclipse
.ui
.PlatformUI
;
54 import org
.eclipse
.ui
.plugin
.AbstractUIPlugin
;
60 public class ResourcesView
extends AbsTimeUpdateView
implements
61 ITmfTimeSelectionListener
, ITmfTimeScaleSelectionListener
{
63 // ========================================================================
65 // ========================================================================
66 public static final String ID
= "org.eclipse.linuxtools.lttng.ui.views.resources";
68 // private int totalNumItems = 0;
70 private Action resetScale
;
71 private Action nextEvent
;
72 private Action prevEvent
;
73 private Action nextTrace
;
74 private Action prevTrace
;
75 private Action showLegend
;
76 private Action filterTraces
;
77 private Action zoomIn
;
78 private Action zoomOut
;
79 private boolean synch
= true; // used to be an option
81 private ITimeAnalysisViewer tsfviewer
;
82 private Composite top
;
84 // private static SimpleDateFormat stimeformat = new SimpleDateFormat(
85 // "yy/MM/dd HH:mm:ss");
87 // private TraceModelImplFactory fact;
89 // ========================================================================
91 // ========================================================================
96 public ResourcesView() {
100 // ========================================================================
102 // ========================================================================
105 * This is a callback that will allow us to create the viewer and initialize
109 public void createPartControl(Composite parent
) {
110 top
= new Composite(parent
, SWT
.BORDER
);
112 top
.setLayout(new FillLayout());
113 tsfviewer
= TmfViewerFactory
.createViewer(top
,
114 new TimeRangeViewerProvider());
116 tsfviewer
.addWidgetSelectionListner(this);
117 tsfviewer
.addWidgetTimeScaleSelectionListner(this);
119 // Traces shall not be grouped to allow synchronisation
120 tsfviewer
.groupTraces(true);
121 tsfviewer
.setAcceptSelectionAPIcalls(true);
123 // Viewer to notify selection to this class
124 // This class will synchronise selections with table.
125 tsfviewer
.addWidgetSelectionListner(this);
126 tsfviewer
.addWidgetTimeScaleSelectionListner(this);
128 // Create the help context id for the viewer's control
129 // TODO: Associate with help system
130 PlatformUI
.getWorkbench().getHelpSystem().setHelp(
131 tsfviewer
.getControl(),
132 "org.eclipse.linuxtools.lttng.ui.views.resource.view"); //$NON-NLS-1$
136 contributeToActionBars();
138 // Register the updater in charge to refresh elements as we update the
140 // FlowParamsUpdater listener = FlowModelFactory.getParamsUpdater();
141 // tsfviewer.addWidgetTimeScaleSelectionListner(listener);
143 // TODO: re-factor registration / notification process
144 // Register this view to receive updates when the model is updated with
146 // ModelListenFactory.getRegister().addFlowModelUpdatesListener(this);
148 // Register the event processor factory in charge of event handling
149 EventProcessorProxy
.getInstance().addEventProcessorFactory(
150 ResourcesTRangeUpdateFactory
.getInstance());
152 // set the initial view parameter values
153 // Experiment start and end time
154 // as well as time space width in pixels, used by the time analysis
156 ParamsUpdater paramUpdater
= ResourceModelFactory
.getParamsUpdater();
157 StateExperimentManager experimentManger
= StateManagerFactory
158 .getExperimentManager();
159 // Read relevant values
160 int timeSpaceWidth
= tsfviewer
.getTimeSpace();
161 TmfTimeRange timeRange
= experimentManger
.getExperimentTimeRange();
162 if (timeRange
!= null) {
163 long time0
= timeRange
.getStartTime().getValue();
164 long time1
= timeRange
.getEndTime().getValue();
165 paramUpdater
.update(time0
, time1
, timeSpaceWidth
);
168 // Read current data if any available
169 StateManagerFactory
.getExperimentManager().readExperiment(
170 "resourceView", this);
173 private void hookContextMenu() {
174 MenuManager menuMgr
= new MenuManager("#PopupMenu"); //$NON-NLS-1$
175 menuMgr
.setRemoveAllWhenShown(true);
176 menuMgr
.addMenuListener(new IMenuListener() {
177 public void menuAboutToShow(IMenuManager manager
) {
178 ResourcesView
.this.fillContextMenu(manager
);
182 Menu menu
= menuMgr
.createContextMenu(tsfviewer
.getControl());
183 tsfviewer
.getControl().setMenu(menu
);
185 .registerContextMenu(menuMgr
, tsfviewer
.getSelectionProvider());
188 private void contributeToActionBars() {
189 IActionBars bars
= getViewSite().getActionBars();
190 fillLocalPullDown(bars
.getMenuManager());
191 fillLocalToolBar(bars
.getToolBarManager());
194 private void fillLocalPullDown(IMenuManager manager
) {
195 manager
.add(new Separator());
196 // manager.add(showLegend);
197 manager
.add(new Separator());
198 manager
.add(resetScale
);
199 manager
.add(nextEvent
);
200 manager
.add(prevEvent
);
201 manager
.add(nextTrace
);
202 manager
.add(prevTrace
);
203 // manager.add(filterTraces);
205 manager
.add(zoomOut
);
206 manager
.add(new Separator());
209 private void fillContextMenu(IMenuManager manager
) {
210 // manager.add(showLegend);
211 manager
.add(new Separator());
212 manager
.add(resetScale
);
213 manager
.add(nextEvent
);
214 manager
.add(prevEvent
);
215 manager
.add(nextTrace
);
216 manager
.add(prevTrace
);
217 // manager.add(showLegend);
218 // manager.add(filterTraces);
220 manager
.add(zoomOut
);
221 manager
.add(new Separator());
222 manager
.add(new Separator(IWorkbenchActionConstants
.MB_ADDITIONS
));
225 private void fillLocalToolBar(IToolBarManager manager
) {
226 // manager.add(showLegend);
227 manager
.add(new Separator());
228 manager
.add(resetScale
);
229 manager
.add(nextEvent
);
230 manager
.add(prevEvent
);
231 manager
.add(nextTrace
);
232 manager
.add(prevTrace
);
233 // manager.add(filterTraces);
235 manager
.add(zoomOut
);
236 manager
.add(new Separator());
239 private void makeActions() {
241 resetScale
= new Action() {
244 if (tsfviewer
!= null) {
245 tsfviewer
.resetStartFinishTime();
250 resetScale
.setText(Messages
.getString("ResourcesView.Action.Reset")); //$NON-NLS-1$
251 resetScale
.setToolTipText(Messages
252 .getString("ResourcesView.Action.Reset.ToolTip")); //$NON-NLS-1$
253 resetScale
.setImageDescriptor(AbstractUIPlugin
254 .imageDescriptorFromPlugin(Messages
255 .getString("ResourcesView.tmf.UI"),
256 "icons/home_nav.gif"));
259 nextEvent
= new Action() {
262 if (tsfviewer
!= null) {
263 tsfviewer
.selectNextEvent();
267 nextEvent
.setText(Messages
.getString("ResourcesView.Action.NextEvent")); //$NON-NLS-1$
268 nextEvent
.setToolTipText(Messages
269 .getString("ResourcesView.Action.NextEvent.Tooltip")); //$NON-NLS-1$
270 nextEvent
.setImageDescriptor(AbstractUIPlugin
271 .imageDescriptorFromPlugin(Messages
272 .getString("ResourcesView.tmf.UI"),
273 "icons/next_event.gif"));
276 prevEvent
= new Action() {
279 if (tsfviewer
!= null) {
280 tsfviewer
.selectPrevEvent();
284 prevEvent
.setText(Messages
.getString("ResourcesView.Action.PrevEvent")); //$NON-NLS-1$
285 prevEvent
.setToolTipText(Messages
286 .getString("ResourcesView.Action.PrevEvent.Tooltip")); //$NON-NLS-1$
287 prevEvent
.setImageDescriptor(AbstractUIPlugin
288 .imageDescriptorFromPlugin(Messages
289 .getString("ResourcesView.tmf.UI"),
290 "icons/prev_event.gif"));
293 nextTrace
= new Action() {
296 if (tsfviewer
!= null) {
297 tsfviewer
.selectNextTrace();
301 nextTrace
.setText(Messages
302 .getString("ResourcesView.Action.NextResource")); //$NON-NLS-1$
303 nextTrace
.setToolTipText(Messages
304 .getString("ResourcesView.Action.NextResource.ToolTip")); //$NON-NLS-1$
305 nextTrace
.setImageDescriptor(AbstractUIPlugin
306 .imageDescriptorFromPlugin(Messages
307 .getString("ResourcesView.tmf.UI"),
308 "icons/next_item.gif"));
311 prevTrace
= new Action() {
314 if (tsfviewer
!= null) {
315 tsfviewer
.selectPrevTrace();
319 prevTrace
.setText(Messages
320 .getString("ResourcesView.Action.PreviousResource")); //$NON-NLS-1$
321 prevTrace
.setToolTipText(Messages
322 .getString("ResourcesView.Action.PreviousResource.Tooltip")); //$NON-NLS-1$
323 prevTrace
.setImageDescriptor(AbstractUIPlugin
324 .imageDescriptorFromPlugin(Messages
325 .getString("ResourcesView.tmf.UI"),
326 "icons/prev_item.gif"));
329 showLegend
= new Action() {
332 if (tsfviewer
!= null) {
333 tsfviewer
.showLegend();
337 showLegend
.setText(Messages
.getString("ResourcesView.Action.Legend")); //$NON-NLS-1$
338 showLegend
.setToolTipText(Messages
339 .getString("ResourcesView.Action.Legend.ToolTip")); //$NON-NLS-1$
342 filterTraces
= new Action() {
345 if (tsfviewer
!= null) {
346 tsfviewer
.filterTraces();
350 filterTraces
.setText(Messages
.getString("ResourcesView.Action.Filter")); //$NON-NLS-1$
351 filterTraces
.setToolTipText(Messages
352 .getString("ResourcesView.Action.Filter.ToolTip")); //$NON-NLS-1$
353 filterTraces
.setImageDescriptor(AbstractUIPlugin
354 .imageDescriptorFromPlugin(Messages
355 .getString("ResourcesView.tmf.UI"),
356 "icons/filter_items.gif"));
359 zoomIn
= new Action() {
362 if (tsfviewer
!= null) {
367 zoomIn
.setText(Messages
.getString("ResourcesView.Action.ZoomIn")); //$NON-NLS-1$
368 zoomIn
.setToolTipText(Messages
369 .getString("ResourcesView.Action.ZoomIn.Tooltip")); //$NON-NLS-1$
370 zoomIn
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(
371 Messages
.getString("ResourcesView.tmf.UI"),
372 "icons/zoomin_nav.gif"));
375 zoomOut
= new Action() {
378 if (tsfviewer
!= null) {
383 zoomOut
.setText(Messages
.getString("ResourcesView.Action.ZoomOut")); //$NON-NLS-1$
384 zoomOut
.setToolTipText(Messages
385 .getString("ResourcesView.Action.ZoomOut.tooltip")); //$NON-NLS-1$
386 zoomOut
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(
387 Messages
.getString("ResourcesView.tmf.UI"),
388 "icons/zoomout_nav.gif"));
390 // PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_ELCL_SYNCED);
394 * Passing the focus request to the viewer's control.
397 public void setFocus() {
398 tsfviewer
.getControl().setFocus();
401 public void tsfTmProcessSelEvent(TmfTimeSelectionEvent event
) {
402 Object source
= event
.getSource();
403 if (source
== null) {
407 // TmfTimeAnalysisViewer rViewer = (TmfTimeAnalysisViewer)
408 // event.getSource();
409 // TmfTimeAnalysisViewer synchViewer = null;
410 // Synchronize viewer selections if Enabled,
411 // make sure the selection does not go in loops
412 // if (tsfviewer == rViewer) {
413 // synchViewer = tsfviewer2;
415 // synchViewer = tsfviewer;
417 // Notify listener views.
419 ParamsUpdater paramUpdater
= ResourceModelFactory
.getParamsUpdater();
420 Long savedSelTime
= paramUpdater
.getSelectedTime();
422 long selTimens
= event
.getSelectedTime();
424 // make sure the new selected time is different than saved before
426 if (savedSelTime
== null || savedSelTime
!= selTimens
) {
427 // Notify listener views.
428 synchTimeNotification(selTimens
, source
);
430 // Update the parameter updater to save the selected time
431 paramUpdater
.setSelectedTime(selTimens
);
433 if (TraceDebug
.isDEBUG()) {
434 // Object selection = event.getSelection();
435 TraceDebug
.debug("Selected Time in Resource View: "
436 + new LttngTimestamp(selTimens
));
444 * @seeorg.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.
445 * ITmfTimeScaleSelectionListener
446 * #tsfTmProcessTimeScaleEvent(org.eclipse.linuxtools
447 * .tmf.ui.viewers.timeAnalysis.TmfTimeScaleSelectionEvent)
449 public void tsfTmProcessTimeScaleEvent(TmfTimeScaleSelectionEvent event
) {
450 // source needed to keep track of source values
451 Object source
= event
.getSource();
453 if (source
!= null) {
454 // Update the parameter updater before carrying out a read request
455 ParamsUpdater paramUpdater
= ResourceModelFactory
457 boolean newParams
= paramUpdater
.processTimeScaleEvent(event
);
460 // Read the updated time window
461 TmfTimeRange trange
= paramUpdater
.getTrange();
462 if (trange
!= null) {
464 // Notify listener views. views to perform data requests
465 // upon the notification below
466 synchTimeRangeNotification(trange
, paramUpdater
467 .getSelectedTime(), source
);
474 * Obtains the remainder fraction on unit Seconds of the entered value in
475 * nanoseconds. e.g. input: 1241207054171080214 ns The number of seconds can
476 * be obtain by removing the last 9 digits: 1241207054 the fractional
477 * portion of seconds, expressed in ns is: 171080214
482 public String
formatNs(long v
) {
483 StringBuffer str
= new StringBuffer();
490 String strVal
= String
.valueOf(v
);
491 if (v
< 1000000000) {
495 // Extract the last nine digits (e.g. fraction of a S expressed in ns
496 return strVal
.substring(strVal
.length() - 9);
503 * @param timeUpdate - Time bounds updated needed e.g. if a new Experiment or trace is selected
505 public void resourceModelUpdates(final ITmfTimeAnalysisEntry
[] items
,
506 final long startTime
, final long endTime
, final boolean timeUpdate
) {
507 tsfviewer
.getControl().getDisplay().asyncExec(new Runnable() {
510 tsfviewer
.display(items
, startTime
, endTime
, timeUpdate
);
511 tsfviewer
.resizeControls();
517 public void dispose() {
518 // dispose parent resources
520 // Remove the event processor factory
521 EventProcessorProxy
.getInstance().removeEventProcessorFactory(
522 ResourcesTRangeUpdateFactory
.getInstance());
524 tsfviewer
.removeWidgetSelectionListner(this);
525 tsfviewer
.removeWidgetTimeScaleSelectionListner(this);
530 * Trigger time synchronisation to other views this method shall be called
531 * when a check has been performed to note that an actual change of time has
532 * been performed vs a pure re-selection of the same time
536 private void synchTimeNotification(long time
, Object source
) {
537 // if synchronisation selected
539 // Notify other views
540 TmfSignalManager
.dispatchSignal(new TmfTimeSynchSignal(source
,
541 new LttngTimestamp(time
)));
545 private void synchTimeRangeNotification(TmfTimeRange trange
,
546 Long selectedTime
, Object source
) {
547 // if synchronisation selected
549 // Notify other views
550 TmfSignalManager
.dispatchSignal(new TmfRangeSynchSignal(source
,
551 trange
, new LttngTimestamp(selectedTime
)));
556 * Registers as listener of time selection from other tmf views
561 public void synchToTime(TmfTimeSynchSignal signal
) {
563 Object source
= signal
.getSource();
564 if (signal
!= null && source
!= null && source
!= this) {
565 // Internal value is expected in nano seconds.
566 long selectedTime
= signal
.getCurrentTime().getValue();
567 if (tsfviewer
!= null) {
568 tsfviewer
.setSelectedTime(selectedTime
, true, source
);
575 * Annotation Registers as listener of time range selection from other views
576 * The implementation handles the entry of the signal.
581 public void synchToTimeRange(TmfRangeSynchSignal signal
) {
583 Object source
= signal
.getSource();
584 if (signal
!= null && source
!= null && source
!= this) {
585 // Internal value is expected in nano seconds.
586 TmfTimeRange trange
= signal
.getCurrentRange();
587 if (tsfviewer
!= null) {
589 .setSelectVisTimeWindow(trange
.getStartTime()
591 trange
.getEndTime().getValue(), source
);
593 // Request the data to populate the new selected time window
604 * org.eclipse.linuxtools.lttng.ui.views.common.LttngTimeUpdateView#waitCursor
608 protected void waitCursor(final boolean waitInd
) {
609 if (tsfviewer
!= null) {
610 Display display
= tsfviewer
.getControl().getDisplay();
612 // Perform the updates on the UI thread
613 display
.asyncExec(new Runnable() {
615 tsfviewer
.waitCursor(waitInd
);
624 * @seeorg.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#
625 * ModelUpdatePrep(java.lang.String, boolean)
628 public void ModelUpdatePrep(String traceId
, boolean clearAllData
,
629 TmfTimeRange trange
) {
631 ResourceModelFactory
.getResourceContainer().clearResources();
633 ResourceModelFactory
.getResourceContainer().clearChildren(traceId
);
636 ParamsUpdater updater
= ResourceModelFactory
.getParamsUpdater();
638 updater
.setEventsDiscarded(0);
640 // Update new visible time range if available
641 if (trange
!= null) {
642 updater
.update(trange
.getStartTime().getValue(), trange
643 .getEndTime().getValue());
650 * @seeorg.eclipse.linuxtools.lttng.ui.views.common.LttngTimeUpdateView#
651 * ModelUpdateComplete(org.eclipse.linuxtools.lttng.state.StateDataRequest)
654 public void ModelUpdateComplete(StateDataRequest request
) {
655 StateManager smanager
= request
.getStateManager();
656 long experimentStartTime
= -1;
657 long experimentEndTime
= -1;
658 TmfTimeRange experimentTimeRange
= smanager
.getExperimentTimeWindow();
659 if (experimentTimeRange
!= null) {
660 experimentStartTime
= experimentTimeRange
.getStartTime().getValue();
661 experimentEndTime
= experimentTimeRange
.getEndTime().getValue();
664 // Obtain the current resource list
665 TimeRangeEventResource
[] resourceArr
= ResourceModelFactory
666 .getResourceContainer().readResources();
668 // Sort the array by pid
669 Arrays
.sort(resourceArr
);
671 // Update the view part
672 resourceModelUpdates(resourceArr
, experimentStartTime
,
673 experimentEndTime
, request
.isclearDataInd());
675 // reselect to original time
676 ParamsUpdater paramUpdater
= ResourceModelFactory
.getParamsUpdater();
677 final Long selTime
= paramUpdater
.getSelectedTime();
678 if (selTime
!= null) {
679 Display display
= tsfviewer
.getControl().getDisplay();
680 display
.asyncExec(new Runnable() {
682 tsfviewer
.setSelectedTime(selTime
, false, this);
687 if (TraceDebug
.isDEBUG()) {
688 Long count
= smanager
.getEventCount();
690 for (TimeRangeEventResource resource
: resourceArr
) {
691 eventCount
+= resource
.getTraceEvents().size();
694 int discarded
= ResourceModelFactory
.getParamsUpdater()
695 .getEventsDiscarded();
696 int discardedOutofOrder
= ResourceModelFactory
.getParamsUpdater()
697 .getEventsDiscardedWrongOrder();
699 .debug("Events handled: "
701 + " Events loaded in Resource view: "
703 + " Number of events discarded: "
705 + "\n\tNumber of events discarded with start time earlier than next good time: "
706 + discardedOutofOrder
);