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
.TmfSignalHandler
;
36 import org
.eclipse
.linuxtools
.tmf
.signal
.TmfSignalManager
;
37 import org
.eclipse
.linuxtools
.tmf
.signal
.TmfTimeSynchSignal
;
38 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.TmfViewerFactory
;
39 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.ITimeAnalysisViewer
;
40 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.ITmfTimeScaleSelectionListener
;
41 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.ITmfTimeSelectionListener
;
42 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.TmfTimeScaleSelectionEvent
;
43 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.TmfTimeSelectionEvent
;
44 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.model
.ITmfTimeAnalysisEntry
;
45 import org
.eclipse
.swt
.SWT
;
46 import org
.eclipse
.swt
.layout
.FillLayout
;
47 import org
.eclipse
.swt
.widgets
.Composite
;
48 import org
.eclipse
.swt
.widgets
.Display
;
49 import org
.eclipse
.swt
.widgets
.Menu
;
50 import org
.eclipse
.ui
.IActionBars
;
51 import org
.eclipse
.ui
.IWorkbenchActionConstants
;
52 import org
.eclipse
.ui
.PlatformUI
;
53 import org
.eclipse
.ui
.plugin
.AbstractUIPlugin
;
59 public class ResourcesView
extends AbsTimeUpdateView
implements
60 ITmfTimeSelectionListener
, ITmfTimeScaleSelectionListener
{
62 // ========================================================================
64 // ========================================================================
65 public static final String ID
= "org.eclipse.linuxtools.lttng.ui.views.resources";
67 // private int totalNumItems = 0;
69 private Action resetScale
;
70 private Action nextEvent
;
71 private Action prevEvent
;
72 private Action nextTrace
;
73 private Action prevTrace
;
74 private Action showLegend
;
75 private Action filterTraces
;
76 private Action zoomIn
;
77 private Action zoomOut
;
80 private ITimeAnalysisViewer tsfviewer
;
81 private Composite top
;
83 // private static SimpleDateFormat stimeformat = new SimpleDateFormat(
84 // "yy/MM/dd HH:mm:ss");
86 // private TraceModelImplFactory fact;
88 // ========================================================================
90 // ========================================================================
95 public ResourcesView() {
99 // ========================================================================
101 // ========================================================================
104 * This is a callback that will allow us to create the viewer and initialize
108 public void createPartControl(Composite parent
) {
109 top
= new Composite(parent
, SWT
.BORDER
);
111 top
.setLayout(new FillLayout());
112 tsfviewer
= TmfViewerFactory
.createViewer(top
,
113 new TimeRangeViewerProvider());
115 tsfviewer
.addWidgetSelectionListner(this);
116 tsfviewer
.addWidgetTimeScaleSelectionListner(this);
118 // Traces shall not be grouped to allow synchronisation
119 tsfviewer
.groupTraces(true);
120 tsfviewer
.setAcceptSelectionAPIcalls(true);
122 // Viewer to notify selection to this class
123 // This class will synchronise selections with table.
124 tsfviewer
.addWidgetSelectionListner(this);
125 tsfviewer
.addWidgetTimeScaleSelectionListner(this);
127 // Create the help context id for the viewer's control
128 // TODO: Associate with help system
129 PlatformUI
.getWorkbench().getHelpSystem().setHelp(
130 tsfviewer
.getControl(),
131 "org.eclipse.linuxtools.lttng.ui.views.resource.view"); //$NON-NLS-1$
135 contributeToActionBars();
137 // Register the updater in charge to refresh elements as we update the
139 // FlowParamsUpdater listener = FlowModelFactory.getParamsUpdater();
140 // tsfviewer.addWidgetTimeScaleSelectionListner(listener);
142 // TODO: re-factor registration / notification process
143 // Register this view to receive updates when the model is updated with
145 // ModelListenFactory.getRegister().addFlowModelUpdatesListener(this);
147 // Register the event processor factory in charge of event handling
148 EventProcessorProxy
.getInstance().addEventProcessorFactory(
149 ResourcesTRangeUpdateFactory
.getInstance());
151 // set the initial view parameter values
152 // Experiment start and end time
153 // as well as time space width in pixels, used by the time analysis
155 ParamsUpdater paramUpdater
= ResourceModelFactory
.getParamsUpdater();
156 StateExperimentManager experimentManger
= StateManagerFactory
157 .getExperimentManager();
158 // Read relevant values
159 int timeSpaceWidth
= tsfviewer
.getTimeSpace();
160 TmfTimeRange timeRange
= experimentManger
.getExperimentTimeRange();
161 if (timeRange
!= null) {
162 long time0
= timeRange
.getStartTime().getValue();
163 long time1
= timeRange
.getEndTime().getValue();
164 paramUpdater
.update(time0
, time1
, timeSpaceWidth
);
167 // Read current data if any available
168 StateManagerFactory
.getExperimentManager().readExperiment(
169 "resourceView", this);
172 private void hookContextMenu() {
173 MenuManager menuMgr
= new MenuManager("#PopupMenu"); //$NON-NLS-1$
174 menuMgr
.setRemoveAllWhenShown(true);
175 menuMgr
.addMenuListener(new IMenuListener() {
176 public void menuAboutToShow(IMenuManager manager
) {
177 ResourcesView
.this.fillContextMenu(manager
);
181 Menu menu
= menuMgr
.createContextMenu(tsfviewer
.getControl());
182 tsfviewer
.getControl().setMenu(menu
);
184 .registerContextMenu(menuMgr
, tsfviewer
.getSelectionProvider());
187 private void contributeToActionBars() {
188 IActionBars bars
= getViewSite().getActionBars();
189 fillLocalPullDown(bars
.getMenuManager());
190 fillLocalToolBar(bars
.getToolBarManager());
193 private void fillLocalPullDown(IMenuManager manager
) {
194 manager
.add(new Separator());
195 // manager.add(showLegend);
196 manager
.add(new Separator());
197 manager
.add(resetScale
);
198 manager
.add(nextEvent
);
199 manager
.add(prevEvent
);
200 manager
.add(nextTrace
);
201 manager
.add(prevTrace
);
202 // manager.add(filterTraces);
204 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
);
222 manager
.add(new Separator());
223 manager
.add(new Separator(IWorkbenchActionConstants
.MB_ADDITIONS
));
226 private void fillLocalToolBar(IToolBarManager manager
) {
227 // manager.add(showLegend);
228 manager
.add(new Separator());
229 manager
.add(resetScale
);
230 manager
.add(nextEvent
);
231 manager
.add(prevEvent
);
232 manager
.add(nextTrace
);
233 manager
.add(prevTrace
);
234 // manager.add(filterTraces);
236 manager
.add(zoomOut
);
238 manager
.add(new Separator());
241 private void makeActions() {
243 resetScale
= new Action() {
246 if (tsfviewer
!= null) {
247 tsfviewer
.resetStartFinishTime();
252 resetScale
.setText(Messages
.getString("ResourcesView.Action.Reset")); //$NON-NLS-1$
253 resetScale
.setToolTipText(Messages
254 .getString("ResourcesView.Action.Reset.ToolTip")); //$NON-NLS-1$
255 resetScale
.setImageDescriptor(AbstractUIPlugin
256 .imageDescriptorFromPlugin(Messages
257 .getString("ResourcesView.tmf.UI"),
258 "icons/home_nav.gif"));
261 nextEvent
= new Action() {
264 if (tsfviewer
!= null) {
265 tsfviewer
.selectNextEvent();
269 nextEvent
.setText(Messages
.getString("ResourcesView.Action.NextEvent")); //$NON-NLS-1$
270 nextEvent
.setToolTipText(Messages
271 .getString("ResourcesView.Action.NextEvent.Tooltip")); //$NON-NLS-1$
272 nextEvent
.setImageDescriptor(AbstractUIPlugin
273 .imageDescriptorFromPlugin(Messages
274 .getString("ResourcesView.tmf.UI"),
275 "icons/next_event.gif"));
278 prevEvent
= new Action() {
281 if (tsfviewer
!= null) {
282 tsfviewer
.selectPrevEvent();
286 prevEvent
.setText(Messages
.getString("ResourcesView.Action.PrevEvent")); //$NON-NLS-1$
287 prevEvent
.setToolTipText(Messages
288 .getString("ResourcesView.Action.PrevEvent.Tooltip")); //$NON-NLS-1$
289 prevEvent
.setImageDescriptor(AbstractUIPlugin
290 .imageDescriptorFromPlugin(Messages
291 .getString("ResourcesView.tmf.UI"),
292 "icons/prev_event.gif"));
295 nextTrace
= new Action() {
298 if (tsfviewer
!= null) {
299 tsfviewer
.selectNextTrace();
303 nextTrace
.setText(Messages
304 .getString("ResourcesView.Action.NextResource")); //$NON-NLS-1$
305 nextTrace
.setToolTipText(Messages
306 .getString("ResourcesView.Action.NextResource.ToolTip")); //$NON-NLS-1$
307 nextTrace
.setImageDescriptor(AbstractUIPlugin
308 .imageDescriptorFromPlugin(Messages
309 .getString("ResourcesView.tmf.UI"),
310 "icons/next_item.gif"));
313 prevTrace
= new Action() {
316 if (tsfviewer
!= null) {
317 tsfviewer
.selectPrevTrace();
321 prevTrace
.setText(Messages
322 .getString("ResourcesView.Action.PreviousResource")); //$NON-NLS-1$
323 prevTrace
.setToolTipText(Messages
324 .getString("ResourcesView.Action.PreviousResource.Tooltip")); //$NON-NLS-1$
325 prevTrace
.setImageDescriptor(AbstractUIPlugin
326 .imageDescriptorFromPlugin(Messages
327 .getString("ResourcesView.tmf.UI"),
328 "icons/prev_item.gif"));
331 showLegend
= new Action() {
334 if (tsfviewer
!= null) {
335 tsfviewer
.showLegend();
339 showLegend
.setText(Messages
.getString("ResourcesView.Action.Legend")); //$NON-NLS-1$
340 showLegend
.setToolTipText(Messages
341 .getString("ResourcesView.Action.Legend.ToolTip")); //$NON-NLS-1$
344 filterTraces
= new Action() {
347 if (tsfviewer
!= null) {
348 tsfviewer
.filterTraces();
352 filterTraces
.setText(Messages
.getString("ResourcesView.Action.Filter")); //$NON-NLS-1$
353 filterTraces
.setToolTipText(Messages
354 .getString("ResourcesView.Action.Filter.ToolTip")); //$NON-NLS-1$
355 filterTraces
.setImageDescriptor(AbstractUIPlugin
356 .imageDescriptorFromPlugin(Messages
357 .getString("ResourcesView.tmf.UI"),
358 "icons/filter_items.gif"));
361 zoomIn
= new Action() {
364 if (tsfviewer
!= null) {
369 zoomIn
.setText(Messages
.getString("ResourcesView.Action.ZoomIn")); //$NON-NLS-1$
370 zoomIn
.setToolTipText(Messages
371 .getString("ResourcesView.Action.ZoomIn.Tooltip")); //$NON-NLS-1$
372 zoomIn
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(
373 Messages
.getString("ResourcesView.tmf.UI"),
374 "icons/zoomin_nav.gif"));
377 zoomOut
= new Action() {
380 if (tsfviewer
!= null) {
385 zoomOut
.setText(Messages
.getString("ResourcesView.Action.ZoomOut")); //$NON-NLS-1$
386 zoomOut
.setToolTipText(Messages
387 .getString("ResourcesView.Action.ZoomOut.tooltip")); //$NON-NLS-1$
388 zoomOut
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(
389 Messages
.getString("ResourcesView.tmf.UI"),
390 "icons/zoomout_nav.gif"));
393 synch
= new Action() {
396 // Note: No action since the synch flag is used by Control flow
398 // the actual viewer is set to accept api selections in
399 // createpartcontrol.
401 // if (synch.isChecked()) {
402 // tsfviewer.setAcceptSelectionAPIcalls(true);
404 // tsfviewer.setAcceptSelectionAPIcalls(false);
408 synch
.setText(Messages
.getString("ResourcesView.Action.Synchronize")); //$NON-NLS-1$
409 synch
.setToolTipText(Messages
410 .getString("ResourcesView.Action.Synchronize.ToolTip")); //$NON-NLS-1$
411 synch
.setChecked(false);
412 synch
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(
413 Messages
.getString("ResourcesView.tmf.UI"),
414 "icons/synced.gif"));
415 // PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_ELCL_SYNCED);
419 * Passing the focus request to the viewer's control.
422 public void setFocus() {
423 tsfviewer
.getControl().setFocus();
426 public void tsfTmProcessSelEvent(TmfTimeSelectionEvent event
) {
427 Object source
= event
.getSource();
428 if (source
== null) {
432 // TmfTimeAnalysisViewer rViewer = (TmfTimeAnalysisViewer)
433 // event.getSource();
434 // TmfTimeAnalysisViewer synchViewer = null;
435 // Synchronize viewer selections if Enabled,
436 // make sure the selection does not go in loops
437 // if (tsfviewer == rViewer) {
438 // synchViewer = tsfviewer2;
440 // synchViewer = tsfviewer;
442 // Notify listener views.
444 ParamsUpdater paramUpdater
= ResourceModelFactory
.getParamsUpdater();
445 Long savedSelTime
= paramUpdater
.getSelectedTime();
447 long selTimens
= event
.getSelectedTime();
449 // make sure the new selected time is different than saved before
451 if (savedSelTime
== null || savedSelTime
!= selTimens
) {
452 // Notify listener views.
453 synchTimeNotification(selTimens
);
455 // Update the parameter updater to save the selected time
456 paramUpdater
.setSelectedTime(selTimens
);
458 if (TraceDebug
.isDEBUG()) {
459 // Object selection = event.getSelection();
460 TraceDebug
.debug("Selected Time in Resource View: "
461 + new LttngTimestamp(selTimens
));
469 * @seeorg.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.
470 * ITmfTimeScaleSelectionListener
471 * #tsfTmProcessTimeScaleEvent(org.eclipse.linuxtools
472 * .tmf.ui.viewers.timeAnalysis.TmfTimeScaleSelectionEvent)
474 public void tsfTmProcessTimeScaleEvent(TmfTimeScaleSelectionEvent event
) {
475 // source needed to keep track of source values
476 Object source
= event
.getSource();
478 if (source
!= null) {
479 // Update the parameter updater before carrying out a read request
480 ParamsUpdater paramUpdater
= ResourceModelFactory
482 boolean newParams
= paramUpdater
.processTimeScaleEvent(event
);
485 // Read the updated time window
486 TmfTimeRange trange
= paramUpdater
.getTrange();
487 // Either send a new request or queue for next opportunity
494 * Obtains the remainder fraction on unit Seconds of the entered value in
495 * nanoseconds. e.g. input: 1241207054171080214 ns The number of seconds can
496 * be obtain by removing the last 9 digits: 1241207054 the fractional
497 * portion of seconds, expressed in ns is: 171080214
502 public String
formatNs(long v
) {
503 StringBuffer str
= new StringBuffer();
510 String strVal
= String
.valueOf(v
);
511 if (v
< 1000000000) {
515 // Extract the last nine digits (e.g. fraction of a S expressed in ns
516 return strVal
.substring(strVal
.length() - 9);
523 * @param timeUpdate - Time bounds updated needed e.g. if a new Experiment or trace is selected
525 public void resourceModelUpdates(final ITmfTimeAnalysisEntry
[] items
,
526 final long startTime
, final long endTime
, final boolean timeUpdate
) {
527 tsfviewer
.getControl().getDisplay().asyncExec(new Runnable() {
530 tsfviewer
.display(items
, startTime
, endTime
, timeUpdate
);
531 tsfviewer
.resizeControls();
537 public void dispose() {
538 // dispose parent resources
540 // Remove the event processor factory
541 EventProcessorProxy
.getInstance().removeEventProcessorFactory(
542 ResourcesTRangeUpdateFactory
.getInstance());
544 tsfviewer
.removeWidgetSelectionListner(this);
545 tsfviewer
.removeWidgetTimeScaleSelectionListner(this);
550 * Trigger time synchronisation to other views this method shall be called
551 * when a check has been performed to note that an actual change of time has
552 * been performed vs a pure re-selection of the same time
556 private void synchTimeNotification(long time
) {
557 // if synchronisation selected
558 if (synch
.isChecked()) {
559 // Notify other views
560 TmfSignalManager
.dispatchSignal(new TmfTimeSynchSignal(this,
561 new LttngTimestamp(time
)));
566 * Registers as listener of time selection from other tmf views
571 public void synchToTime(TmfTimeSynchSignal signal
) {
572 if (synch
.isChecked()) {
573 Object source
= signal
.getSource();
574 if (signal
!= null && source
!= null && source
!= this) {
575 // Internal value is expected in nano seconds.
576 long selectedTime
= signal
.getCurrentTime().getValue();
577 if (tsfviewer
!= null) {
578 tsfviewer
.setSelectedTime(selectedTime
, true, source
);
588 * org.eclipse.linuxtools.lttng.ui.views.common.LttngTimeUpdateView#waitCursor
592 protected void waitCursor(final boolean waitInd
) {
593 if (tsfviewer
!= null) {
594 Display display
= tsfviewer
.getControl().getDisplay();
596 // Perform the updates on the UI thread
597 display
.asyncExec(new Runnable() {
599 tsfviewer
.waitCursor(waitInd
);
608 * @seeorg.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#
609 * ModelUpdatePrep(java.lang.String, boolean)
612 public void ModelUpdatePrep(String traceId
, boolean clearAllData
,
613 TmfTimeRange trange
) {
615 ResourceModelFactory
.getResourceContainer().clearResources();
617 ResourceModelFactory
.getResourceContainer().clearChildren(traceId
);
620 ParamsUpdater updater
= ResourceModelFactory
.getParamsUpdater();
622 updater
.setEventsDiscarded(0);
624 // Update new visible time range if available
625 if (trange
!= null) {
626 updater
.update(trange
.getStartTime().getValue(), trange
627 .getEndTime().getValue());
634 * @seeorg.eclipse.linuxtools.lttng.ui.views.common.LttngTimeUpdateView#
635 * ModelUpdateComplete(org.eclipse.linuxtools.lttng.state.StateDataRequest)
638 public void ModelUpdateComplete(StateDataRequest request
) {
639 StateManager smanager
= request
.getStateManager();
640 long experimentStartTime
= -1;
641 long experimentEndTime
= -1;
642 TmfTimeRange experimentTimeRange
= smanager
.getExperimentTimeWindow();
643 if (experimentTimeRange
!= null) {
644 experimentStartTime
= experimentTimeRange
.getStartTime().getValue();
645 experimentEndTime
= experimentTimeRange
.getEndTime().getValue();
648 // Obtain the current resource list
649 TimeRangeEventResource
[] resourceArr
= ResourceModelFactory
650 .getResourceContainer().readResources();
652 // Sort the array by pid
653 Arrays
.sort(resourceArr
);
655 // Update the view part
656 resourceModelUpdates(resourceArr
, experimentStartTime
,
657 experimentEndTime
, request
.isclearDataInd());
659 // reselect to original time
660 ParamsUpdater paramUpdater
= ResourceModelFactory
.getParamsUpdater();
661 final Long selTime
= paramUpdater
.getSelectedTime();
662 if (selTime
!= null) {
663 Display display
= tsfviewer
.getControl().getDisplay();
664 display
.asyncExec(new Runnable() {
666 tsfviewer
.setSelectedTime(selTime
, false, this);
671 if (TraceDebug
.isDEBUG()) {
672 Long count
= smanager
.getEventCount();
674 for (TimeRangeEventResource resource
: resourceArr
) {
675 eventCount
+= resource
.getTraceEvents().size();
678 int discarded
= ResourceModelFactory
.getParamsUpdater()
679 .getEventsDiscarded();
680 int discardedOutofOrder
= ResourceModelFactory
.getParamsUpdater()
681 .getEventsDiscardedWrongOrder();
683 .debug("Events handled: "
685 + " Events loaded in Resource view: "
687 + " Number of events discarded: "
689 + "\n\tNumber of events discarded with start time earlier than next good time: "
690 + discardedOutofOrder
);