1 /*******************************************************************************
2 * Copyright (c) 2010, 2011 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made 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
10 * Philippe Sawicki (INF4990.A2010@gmail.com) - Initial API and implementation
11 * Mathieu Denis (mathieu.denis55@gmail.com) - Refactored code
12 * Bernd Hufmann - Adapted to new model-view-controller design
13 *******************************************************************************/
14 package org
.eclipse
.linuxtools
.lttng
.ui
.views
.latency
;
16 import org
.eclipse
.jface
.action
.Action
;
17 import org
.eclipse
.jface
.action
.IMenuManager
;
18 import org
.eclipse
.jface
.action
.IToolBarManager
;
19 import org
.eclipse
.jface
.action
.Separator
;
20 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.event
.LttngEvent
;
21 import org
.eclipse
.linuxtools
.lttng
.ui
.views
.latency
.dialogs
.AddDialog
;
22 import org
.eclipse
.linuxtools
.lttng
.ui
.views
.latency
.dialogs
.DeleteDialog
;
23 import org
.eclipse
.linuxtools
.lttng
.ui
.views
.latency
.dialogs
.ListDialog
;
24 import org
.eclipse
.linuxtools
.lttng
.ui
.views
.latency
.model
.Config
;
25 import org
.eclipse
.linuxtools
.lttng
.ui
.views
.latency
.model
.IGraphModelListener
;
26 import org
.eclipse
.linuxtools
.lttng
.ui
.views
.latency
.model
.LatencyController
;
27 import org
.eclipse
.linuxtools
.lttng
.ui
.views
.latency
.model
.LatencyGraphModel
;
28 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfTimestamp
;
29 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfEvent
;
30 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfTimeRange
;
31 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfTimestamp
;
32 import org
.eclipse
.linuxtools
.tmf
.core
.experiment
.TmfExperiment
;
33 import org
.eclipse
.linuxtools
.tmf
.core
.request
.ITmfDataRequest
.ExecutionType
;
34 import org
.eclipse
.linuxtools
.tmf
.core
.request
.TmfEventRequest
;
35 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfExperimentDisposedSignal
;
36 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfExperimentRangeUpdatedSignal
;
37 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfExperimentSelectedSignal
;
38 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfRangeSynchSignal
;
39 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfSignalHandler
;
40 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTimeSynchSignal
;
41 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.TmfView
;
42 import org
.eclipse
.swt
.SWT
;
43 import org
.eclipse
.swt
.events
.ControlEvent
;
44 import org
.eclipse
.swt
.events
.ControlListener
;
45 import org
.eclipse
.swt
.layout
.FillLayout
;
46 import org
.eclipse
.swt
.widgets
.Composite
;
47 import org
.eclipse
.ui
.IActionBars
;
48 import org
.eclipse
.ui
.plugin
.AbstractUIPlugin
;
51 * <b><u>LatencyView</u></b>
53 * TmfView displaying the latency views (i.e. the two latency charts).
55 * @author Philippe Sawicki
57 public class LatencyView
extends TmfView
implements IGraphModelListener
{
59 // ------------------------------------------------------------------------
61 // ------------------------------------------------------------------------
63 // The initial window span (in nanoseconds)
64 public static final long INITIAL_WINDOW_SPAN
= (1L * 100 * 1000 * 1000); // .1sec
67 * The view's unique ID.
69 public static final String ID
= "org.eclipse.linuxtools.lttng.ui.views.latency.LatencyView"; //$NON-NLS-1$
72 * A reference to the currently selected experiment.
74 protected TmfExperiment
<LttngEvent
> fExperiment
= null;
79 protected Composite fParent
;
84 protected GraphViewer fGraphViewer
;
89 protected HistogramViewer fHistogramViewer
;
92 * Action executed when the user wants to see the list of matching events.
94 protected Action fListMatchingEvents
;
97 * Action executed when the user wants to add matching events.
99 protected Action fAddMatchingEvents
;
102 * Action executed when the user wants to delete matching events.
104 protected Action fDeleteMatchingEvents
;
107 * Action executed when the user wants to increase the width of the histogram bars.
109 protected Action fIncreaseBarWidth
;
112 * Action executed when the user wants to decrease the width of the histogram bars.
114 protected Action fDecreaseBarWidth
;
117 * The current histogram window time range.
119 protected TmfTimeRange fTimeRange
= null;
122 * Controller of the latency model which is responsible to retrieve data from the trace
124 final private LatencyController fController
;
127 * Flag to notify that TimeSyncSignal was received and is being processed.
129 private boolean fSyncSignalReceived
= false;
131 // ------------------------------------------------------------------------
133 // ------------------------------------------------------------------------
138 public LatencyView() {
139 super(Messages
.LatencyView_ViewName
);
140 fController
= LatencyController
.getInstance();
143 // ------------------------------------------------------------------------
145 // ------------------------------------------------------------------------
148 * Create the UI controls of this view.
151 * The composite parent of this view.
154 public void createPartControl(Composite parent
) {
159 contributeToActionBars();
161 // Add a control listener to handle the view resize events (to redraw the canvas)
162 fParent
.addControlListener(new ControlListener() {
164 public void controlMoved(ControlEvent event
) {
165 fHistogramViewer
.clearBackground();
166 fGraphViewer
.clearBackground();
167 fController
.handleCompleted();
171 public void controlResized(ControlEvent event
) {
172 fHistogramViewer
.clearBackground();
173 fGraphViewer
.clearBackground();
174 fController
.handleCompleted();
178 // ///////////////////////////////////////////////////////////////////////////////////
179 // Layout for the whole view, other elements will be in a child composite of this one
181 // Composite layoutSelectionWindow
182 // Composite layoutTimesSpinner
183 // Composite layoutExperimentHistogram
184 // ///////////////////////////////////////////////////////////////////////////////////
185 Composite layoutFullView
= new Composite(fParent
, SWT
.FILL
);
186 FillLayout gridFullView
= new FillLayout();
187 gridFullView
.marginHeight
= 0;
188 gridFullView
.marginWidth
= 0;
189 layoutFullView
.setLayout(gridFullView
);
191 // Create the graph views
192 fGraphViewer
= new GraphViewer(layoutFullView
, SWT
.DOUBLE_BUFFERED
);
193 fGraphViewer
.setDrawLabelEachNTicks(2);
194 fGraphViewer
.setGraphTitle(Messages
.LatencyView_Graphs_Graph_Title
);
195 fGraphViewer
.setXAxisLabel(Messages
.LatencyView_Graphs_Graph_XAxisLabel
, 40);
196 fGraphViewer
.setYAxisLabel(Messages
.LatencyView_Graphs_Graph_YAxisLabel
);
198 fHistogramViewer
= new HistogramViewer(layoutFullView
, SWT
.DOUBLE_BUFFERED
);
199 fHistogramViewer
.setDrawLabelEachNTicks(2);
200 fHistogramViewer
.setGraphTitle(Messages
.LatencyView_Graphs_Histogram_Title
);
201 fHistogramViewer
.setXAxisLabel(Messages
.LatencyView_Graphs_Histogram_XAxisLabel
, 55);
202 fHistogramViewer
.setYAxisLabel(Messages
.LatencyView_Graphs_Histogram_YAxisLabel
);
204 fController
.registerModel(fGraphViewer
.getModel());
205 fController
.registerModel(fHistogramViewer
.getModel());
207 ((LatencyGraphModel
)fGraphViewer
.getModel()).addGraphModelListener(this);
209 @SuppressWarnings("unchecked")
210 TmfExperiment
<TmfEvent
> experiment
= (TmfExperiment
<TmfEvent
>) TmfExperiment
.getCurrentExperiment();
211 if (experiment
!= null) {
213 TmfTimeRange experimentTRange
= experiment
.getTimeRange();
215 if (experimentTRange
!= TmfTimeRange
.NULL_RANGE
) {
216 TmfExperimentSelectedSignal
<TmfEvent
> signal
= new TmfExperimentSelectedSignal
<TmfEvent
>(this, experiment
);
217 experimentSelected(signal
);
222 @SuppressWarnings("nls")
224 public String
toString() {
225 return "["+ Messages
.LatencyView_ViewName
+"]";
228 // ------------------------------------------------------------------------
230 // ------------------------------------------------------------------------
232 @SuppressWarnings("unchecked")
234 public void experimentSelected(TmfExperimentSelectedSignal
<TmfEvent
> signal
) {
236 fGraphViewer
.clear();
237 fHistogramViewer
.clear();
239 if (fParent
!= null) {
240 // Update the trace reference
241 fExperiment
= (TmfExperiment
<LttngEvent
>) signal
.getExperiment();
243 fTimeRange
= TmfTimeRange
.NULL_RANGE
;
244 TmfTimeRange experimentTRange
= fExperiment
.getTimeRange();
246 if (!experimentTRange
.equals(TmfTimeRange
.NULL_RANGE
)) {
247 fTimeRange
= new TmfTimeRange(experimentTRange
.getStartTime(),
248 new TmfTimestamp(experimentTRange
.getStartTime().getValue() + INITIAL_WINDOW_SPAN
, experimentTRange
.getStartTime().getScale(), experimentTRange
.getStartTime().getPrecision()));
249 fController
.refreshModels(fExperiment
, fTimeRange
);
254 public void experimentRangeUpdated(TmfExperimentRangeUpdatedSignal signal
) {
255 if (fTimeRange
== TmfTimeRange
.NULL_RANGE
&& signal
.getExperiment().equals(fExperiment
)) {
256 TmfTimeRange experimentTRange
= signal
.getRange();
258 if (experimentTRange
!= TmfTimeRange
.NULL_RANGE
) {
259 fTimeRange
= new TmfTimeRange(experimentTRange
.getStartTime(),
260 new TmfTimestamp(experimentTRange
.getStartTime().getValue() + INITIAL_WINDOW_SPAN
, experimentTRange
.getStartTime().getScale(), experimentTRange
.getStartTime().getPrecision()));
261 fController
.refreshModels(fExperiment
, fTimeRange
);
267 public void experimentDisposed(TmfExperimentDisposedSignal
<TmfEvent
> signal
) {
268 if (signal
.getExperiment() != fExperiment
) {
271 fTimeRange
= TmfTimeRange
.NULL_RANGE
;
277 * Called when the LatencyView is closed: disposes of the canvas and unregisters models from views.
280 public void dispose() {
281 fController
.dispose();
282 fController
.deregisterModel(fGraphViewer
.getModel());
283 fController
.deregisterModel(fHistogramViewer
.getModel());
284 ((LatencyGraphModel
)fGraphViewer
.getModel()).removeGraphModelListener(this);
286 fGraphViewer
.dispose();
287 fHistogramViewer
.dispose();
293 * Method called when synchronization is active and that the user select an event.
295 * The models will be updated with the new current selected time.
298 * Signal received from the framework. Contain the event.
301 public void currentTimeUpdated(TmfTimeSynchSignal signal
) {
302 if (signal
.getSource() != this) {
303 fSyncSignalReceived
= true;
304 fController
.setCurrentEventTime(signal
.getCurrentTime().getValue());
305 fSyncSignalReceived
= false;
310 * Method called when synchronization is active and that the user changed the current time range.
312 * The models will be updated with the new time range.
315 * Signal received from the framework. Contain the new time range.
318 public void synchToTimeRange(TmfRangeSynchSignal signal
) {
319 if (signal
.getSource() != this) {
320 // Erase the graph views
321 fGraphViewer
.clear();
322 fHistogramViewer
.clear();
324 ITmfTimestamp startTime
= signal
.getCurrentRange().getStartTime();
325 ITmfTimestamp endTime
= signal
.getCurrentRange().getEndTime();
326 fTimeRange
= new TmfTimeRange(startTime
, endTime
);
328 fController
.refreshModels(fExperiment
, fTimeRange
);
334 * @see org.eclipse.linuxtools.lttng.ui.views.latency.model.IGraphModelListener#graphModelUpdated()
337 public void graphModelUpdated() {
338 // Nothing to do - update of viewers will be done in the viewers
343 * @see org.eclipse.linuxtools.lttng.ui.views.latency.model.IGraphModelListener#currentEventUpdated(long)
346 public void currentEventUpdated(final long currentEventTime
) {
347 if (fExperiment
!= null &&
348 !fSyncSignalReceived
&& // Don't broadcast the current time that was received just before with a time sync signal
349 currentEventTime
!= Config
.INVALID_EVENT_TIME
) {
351 // Queue update in the event request queue
352 TmfTimeRange timeRange
= new TmfTimeRange(new TmfTimestamp(currentEventTime
, Config
.TIME_SCALE
), TmfTimestamp
.BIG_CRUNCH
);
353 TmfEventRequest
<LttngEvent
> request
= new TmfEventRequest
<LttngEvent
>(LttngEvent
.class, timeRange
, 0, 1, ExecutionType
.FOREGROUND
) {
355 public void handleCompleted() {
356 broadcast(new TmfTimeSynchSignal(this, new TmfTimestamp(currentEventTime
, Config
.TIME_SCALE
)));
359 fExperiment
.sendRequest(request
);
363 // ------------------------------------------------------------------------
365 // ------------------------------------------------------------------------
368 * Fills the local pull down menu.
372 private void fillLocalPullDown(IMenuManager manager
) {
373 manager
.add(new Separator());
374 manager
.add(fIncreaseBarWidth
);
375 manager
.add(fDecreaseBarWidth
);
376 manager
.add(new Separator());
377 manager
.add(fListMatchingEvents
);
378 manager
.add(fAddMatchingEvents
);
379 manager
.add(fDeleteMatchingEvents
);
380 manager
.add(new Separator());
384 * Fills the local toolbar.
386 * The toolbar manager
388 private void fillLocalToolBar(IToolBarManager manager
) {
389 manager
.add(new Separator());
390 manager
.add(fIncreaseBarWidth
);
391 manager
.add(fDecreaseBarWidth
);
392 manager
.add(new Separator());
393 manager
.add(fListMatchingEvents
);
394 manager
.add(fAddMatchingEvents
);
395 manager
.add(fDeleteMatchingEvents
);
396 manager
.add(new Separator());
400 * Creates the actions required by the dialog events.
402 private void makeActions() {
403 // Increase the histogram bar width
404 fIncreaseBarWidth
= new Action() {
407 fHistogramViewer
.increaseBarWidth();
408 fGraphViewer
.increaseBarWidth();
411 String tooltipText
= Messages
.LatencyView_Action_IncreaseBarWidth_Tooltip
;
412 fIncreaseBarWidth
.setText(tooltipText
);
413 fIncreaseBarWidth
.setToolTipText(tooltipText
);
414 fIncreaseBarWidth
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(Messages
.LatencyView_tmf_UI
, "icons/elcl16/increasebar_button.gif")); //$NON-NLS-1$
416 // Decrease the histogram bar width
417 fDecreaseBarWidth
= new Action() {
420 fHistogramViewer
.decreaseBarWidth();
421 fGraphViewer
.decreaseBarWidth();
424 tooltipText
= Messages
.LatencyView_Action_DecreaseBarWidth_Tooltip
;
425 fDecreaseBarWidth
.setText(tooltipText
);
426 fDecreaseBarWidth
.setToolTipText(tooltipText
);
427 fDecreaseBarWidth
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(Messages
.LatencyView_tmf_UI
, "icons/elcl16/decreasebar_button.gif")); //$NON-NLS-1$
429 // List matching events dialog
430 fListMatchingEvents
= new Action() {
433 ListDialog listDialog
= new ListDialog(fParent
.getShell(), Messages
.LatencyView_Dialogs_ListEvents_Title
, Messages
.LatencyView_Dialogs_ListEvents_Message
);
438 tooltipText
= Messages
.LatencyView_Action_ListEvents_Tooltip
;
439 fListMatchingEvents
.setText(tooltipText
);
440 fListMatchingEvents
.setToolTipText(tooltipText
);
441 fListMatchingEvents
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(Messages
.LatencyView_tmf_UI
, "icons/eview16/events_view.gif")); //$NON-NLS-1$
443 // Add matching events dialog
444 fAddMatchingEvents
= new Action() {
447 AddDialog addDialog
= new AddDialog(fParent
.getShell(), Messages
.LatencyView_Dialogs_AddEvents_Title
, Messages
.LatencyView_Dialogs_AddEvents_Message
);
452 tooltipText
= Messages
.LatencyView_Action_AddEvents_Tooltip
;
453 fAddMatchingEvents
.setText(tooltipText
);
454 fAddMatchingEvents
.setToolTipText(tooltipText
);
455 fAddMatchingEvents
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(Messages
.LatencyView_tmf_UI
, "icons/elcl16/add_button.gif")); //$NON-NLS-1$
457 // Remove matching events dialog
458 fDeleteMatchingEvents
= new Action() {
461 DeleteDialog deleteDialog
= new DeleteDialog(fParent
.getShell(), Messages
.LatencyView_Dialogs_DeleteEvents_Title
,
462 Messages
.LatencyView_Dialogs_DeleteEvents_Message
);
463 deleteDialog
.create();
467 tooltipText
= Messages
.LatencyView_Action_DeleteEvents_Tooltip
;
468 fDeleteMatchingEvents
.setText(tooltipText
);
469 fDeleteMatchingEvents
.setToolTipText(tooltipText
);
470 fDeleteMatchingEvents
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(Messages
.LatencyView_tmf_UI
, "icons/elcl16/delete_button.gif")); //$NON-NLS-1$
474 * Build the toolbar and menu by adding action buttons for dialogs.
476 private void contributeToActionBars() {
477 IActionBars bars
= getViewSite().getActionBars();
478 fillLocalPullDown(bars
.getMenuManager());
479 fillLocalToolBar(bars
.getToolBarManager());