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
.internal
.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
.internal
.lttng
.ui
.views
.latency
.dialogs
.AddDialog
;
22 import org
.eclipse
.linuxtools
.internal
.lttng
.ui
.views
.latency
.dialogs
.DeleteDialog
;
23 import org
.eclipse
.linuxtools
.internal
.lttng
.ui
.views
.latency
.dialogs
.ListDialog
;
24 import org
.eclipse
.linuxtools
.internal
.lttng
.ui
.views
.latency
.model
.Config
;
25 import org
.eclipse
.linuxtools
.internal
.lttng
.ui
.views
.latency
.model
.IGraphModelListener
;
26 import org
.eclipse
.linuxtools
.internal
.lttng
.ui
.views
.latency
.model
.LatencyController
;
27 import org
.eclipse
.linuxtools
.internal
.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
.equals(TmfTimeRange
.NULL_RANGE
)) {
216 TmfExperimentSelectedSignal
<TmfEvent
> signal
= new TmfExperimentSelectedSignal
<TmfEvent
>(this, experiment
);
217 experimentSelected(signal
);
223 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
226 public void setFocus() {
227 fGraphViewer
.setFocus();
230 @SuppressWarnings("nls")
232 public String
toString() {
233 return "["+ Messages
.LatencyView_ViewName
+"]";
236 // ------------------------------------------------------------------------
238 // ------------------------------------------------------------------------
240 @SuppressWarnings("unchecked")
242 public void experimentSelected(TmfExperimentSelectedSignal
<TmfEvent
> signal
) {
244 fGraphViewer
.clear();
245 fHistogramViewer
.clear();
247 if (fParent
!= null) {
248 // Update the trace reference
249 fExperiment
= (TmfExperiment
<LttngEvent
>) signal
.getExperiment();
251 fTimeRange
= TmfTimeRange
.NULL_RANGE
;
252 TmfTimeRange experimentTRange
= fExperiment
.getTimeRange();
254 if (!experimentTRange
.equals(TmfTimeRange
.NULL_RANGE
)) {
255 fTimeRange
= new TmfTimeRange(experimentTRange
.getStartTime(),
256 new TmfTimestamp(experimentTRange
.getStartTime().getValue() + INITIAL_WINDOW_SPAN
, experimentTRange
.getStartTime().getScale(), experimentTRange
.getStartTime().getPrecision()));
257 fController
.refreshModels(fExperiment
, fTimeRange
);
262 public void experimentRangeUpdated(TmfExperimentRangeUpdatedSignal signal
) {
263 if (fTimeRange
.equals(TmfTimeRange
.NULL_RANGE
) && signal
.getExperiment().equals(fExperiment
)) {
264 TmfTimeRange experimentTRange
= signal
.getRange();
266 if (!experimentTRange
.equals(TmfTimeRange
.NULL_RANGE
)) {
267 fTimeRange
= new TmfTimeRange(experimentTRange
.getStartTime(),
268 new TmfTimestamp(experimentTRange
.getStartTime().getValue() + INITIAL_WINDOW_SPAN
, experimentTRange
.getStartTime().getScale(), experimentTRange
.getStartTime().getPrecision()));
269 fController
.refreshModels(fExperiment
, fTimeRange
);
275 public void experimentDisposed(TmfExperimentDisposedSignal
<TmfEvent
> signal
) {
276 if (signal
.getExperiment() != fExperiment
) {
279 fTimeRange
= TmfTimeRange
.NULL_RANGE
;
285 * Called when the LatencyView is closed: disposes of the canvas and unregisters models from views.
288 public void dispose() {
289 fController
.dispose();
290 fController
.deregisterModel(fGraphViewer
.getModel());
291 fController
.deregisterModel(fHistogramViewer
.getModel());
292 ((LatencyGraphModel
)fGraphViewer
.getModel()).removeGraphModelListener(this);
294 fGraphViewer
.dispose();
295 fHistogramViewer
.dispose();
301 * Method called when synchronization is active and that the user select an event.
303 * The models will be updated with the new current selected time.
306 * Signal received from the framework. Contain the event.
309 public void currentTimeUpdated(TmfTimeSynchSignal signal
) {
310 if (signal
.getSource() != this) {
311 fSyncSignalReceived
= true;
312 fController
.setCurrentEventTime(signal
.getCurrentTime().getValue());
313 fSyncSignalReceived
= false;
318 * Method called when synchronization is active and that the user changed the current time range.
320 * The models will be updated with the new time range.
323 * Signal received from the framework. Contain the new time range.
326 public void synchToTimeRange(TmfRangeSynchSignal signal
) {
327 if (signal
.getSource() != this) {
328 // Erase the graph views
329 fGraphViewer
.clear();
330 fHistogramViewer
.clear();
332 ITmfTimestamp startTime
= signal
.getCurrentRange().getStartTime();
333 ITmfTimestamp endTime
= signal
.getCurrentRange().getEndTime();
334 fTimeRange
= new TmfTimeRange(startTime
, endTime
);
336 fController
.refreshModels(fExperiment
, fTimeRange
);
342 * @see org.eclipse.linuxtools.lttng.ui.views.latency.model.IGraphModelListener#graphModelUpdated()
345 public void graphModelUpdated() {
346 // Nothing to do - update of viewers will be done in the viewers
351 * @see org.eclipse.linuxtools.lttng.ui.views.latency.model.IGraphModelListener#currentEventUpdated(long)
354 public void currentEventUpdated(final long currentEventTime
) {
355 if (fExperiment
!= null &&
356 !fSyncSignalReceived
&& // Don't broadcast the current time that was received just before with a time sync signal
357 currentEventTime
!= Config
.INVALID_EVENT_TIME
) {
359 // Queue update in the event request queue
360 TmfTimeRange timeRange
= new TmfTimeRange(new TmfTimestamp(currentEventTime
, Config
.TIME_SCALE
), TmfTimestamp
.BIG_CRUNCH
);
361 TmfEventRequest
<LttngEvent
> request
= new TmfEventRequest
<LttngEvent
>(LttngEvent
.class, timeRange
, 0, 1, ExecutionType
.FOREGROUND
) {
363 public void handleCompleted() {
364 broadcast(new TmfTimeSynchSignal(this, new TmfTimestamp(currentEventTime
, Config
.TIME_SCALE
)));
367 fExperiment
.sendRequest(request
);
371 // ------------------------------------------------------------------------
373 // ------------------------------------------------------------------------
376 * Fills the local pull down menu.
380 private void fillLocalPullDown(IMenuManager manager
) {
381 manager
.add(new Separator());
382 manager
.add(fIncreaseBarWidth
);
383 manager
.add(fDecreaseBarWidth
);
384 manager
.add(new Separator());
385 manager
.add(fListMatchingEvents
);
386 manager
.add(fAddMatchingEvents
);
387 manager
.add(fDeleteMatchingEvents
);
388 manager
.add(new Separator());
392 * Fills the local toolbar.
394 * The toolbar manager
396 private void fillLocalToolBar(IToolBarManager manager
) {
397 manager
.add(new Separator());
398 manager
.add(fIncreaseBarWidth
);
399 manager
.add(fDecreaseBarWidth
);
400 manager
.add(new Separator());
401 manager
.add(fListMatchingEvents
);
402 manager
.add(fAddMatchingEvents
);
403 manager
.add(fDeleteMatchingEvents
);
404 manager
.add(new Separator());
408 * Creates the actions required by the dialog events.
410 private void makeActions() {
411 // Increase the histogram bar width
412 fIncreaseBarWidth
= new Action() {
415 fHistogramViewer
.increaseBarWidth();
416 fGraphViewer
.increaseBarWidth();
419 String tooltipText
= Messages
.LatencyView_Action_IncreaseBarWidth_Tooltip
;
420 fIncreaseBarWidth
.setText(tooltipText
);
421 fIncreaseBarWidth
.setToolTipText(tooltipText
);
422 fIncreaseBarWidth
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(Messages
.LatencyView_tmf_UI
, "icons/elcl16/increasebar_button.gif")); //$NON-NLS-1$
424 // Decrease the histogram bar width
425 fDecreaseBarWidth
= new Action() {
428 fHistogramViewer
.decreaseBarWidth();
429 fGraphViewer
.decreaseBarWidth();
432 tooltipText
= Messages
.LatencyView_Action_DecreaseBarWidth_Tooltip
;
433 fDecreaseBarWidth
.setText(tooltipText
);
434 fDecreaseBarWidth
.setToolTipText(tooltipText
);
435 fDecreaseBarWidth
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(Messages
.LatencyView_tmf_UI
, "icons/elcl16/decreasebar_button.gif")); //$NON-NLS-1$
437 // List matching events dialog
438 fListMatchingEvents
= new Action() {
441 ListDialog listDialog
= new ListDialog(fParent
.getShell(), Messages
.LatencyView_Dialogs_ListEvents_Title
, Messages
.LatencyView_Dialogs_ListEvents_Message
);
446 tooltipText
= Messages
.LatencyView_Action_ListEvents_Tooltip
;
447 fListMatchingEvents
.setText(tooltipText
);
448 fListMatchingEvents
.setToolTipText(tooltipText
);
449 fListMatchingEvents
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(Messages
.LatencyView_tmf_UI
, "icons/eview16/events_view.gif")); //$NON-NLS-1$
451 // Add matching events dialog
452 fAddMatchingEvents
= new Action() {
455 AddDialog addDialog
= new AddDialog(fParent
.getShell(), Messages
.LatencyView_Dialogs_AddEvents_Title
, Messages
.LatencyView_Dialogs_AddEvents_Message
);
460 tooltipText
= Messages
.LatencyView_Action_AddEvents_Tooltip
;
461 fAddMatchingEvents
.setText(tooltipText
);
462 fAddMatchingEvents
.setToolTipText(tooltipText
);
463 fAddMatchingEvents
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(Messages
.LatencyView_tmf_UI
, "icons/elcl16/add_button.gif")); //$NON-NLS-1$
465 // Remove matching events dialog
466 fDeleteMatchingEvents
= new Action() {
469 DeleteDialog deleteDialog
= new DeleteDialog(fParent
.getShell(), Messages
.LatencyView_Dialogs_DeleteEvents_Title
,
470 Messages
.LatencyView_Dialogs_DeleteEvents_Message
);
471 deleteDialog
.create();
475 tooltipText
= Messages
.LatencyView_Action_DeleteEvents_Tooltip
;
476 fDeleteMatchingEvents
.setText(tooltipText
);
477 fDeleteMatchingEvents
.setToolTipText(tooltipText
);
478 fDeleteMatchingEvents
.setImageDescriptor(AbstractUIPlugin
.imageDescriptorFromPlugin(Messages
.LatencyView_tmf_UI
, "icons/elcl16/delete_button.gif")); //$NON-NLS-1$
482 * Build the toolbar and menu by adding action buttons for dialogs.
484 private void contributeToActionBars() {
485 IActionBars bars
= getViewSite().getActionBars();
486 fillLocalPullDown(bars
.getMenuManager());
487 fillLocalToolBar(bars
.getToolBarManager());