lami: Update plugin version
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.lami.ui / src / org / eclipse / tracecompass / internal / provisional / analysis / lami / ui / views / LamiReportViewTabPage.java
CommitLineData
f95c9345
AM
1/*******************************************************************************
2 * Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir
3 *
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
8 *******************************************************************************/
9
10package org.eclipse.tracecompass.internal.provisional.analysis.lami.ui.views;
11
f95c9345
AM
12import java.util.HashSet;
13import java.util.LinkedHashSet;
f95c9345 14import java.util.Set;
a805f10b 15
f95c9345
AM
16import org.eclipse.jface.window.Window;
17import org.eclipse.swt.widgets.Composite;
682c435f 18import org.eclipse.swt.widgets.Shell;
f95c9345
AM
19import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.module.LamiResultTable;
20import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.module.LamiTableEntry;
f95c9345 21import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.types.LamiTimeRange;
682c435f
GAPG
22import org.eclipse.tracecompass.internal.provisional.tmf.chart.core.chart.ChartData;
23import org.eclipse.tracecompass.internal.provisional.tmf.chart.core.chart.ChartModel;
24import org.eclipse.tracecompass.internal.provisional.tmf.chart.core.signal.ChartSelectionUpdateSignal;
682c435f 25import org.eclipse.tracecompass.internal.provisional.tmf.chart.ui.dialog.ChartMakerDialog;
f95c9345
AM
26import org.eclipse.tracecompass.tmf.core.component.TmfComponent;
27import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
28import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
29import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
30import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
31import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
32import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
33import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
34
35import com.google.common.collect.Iterables;
36
37/**
38 * Sub-view of a {@link LamiReportView} that shows the contents of one table of
39 * the analysis report. While it is not a View object directly, its
40 * responsibilities are the same.
41 *
42 * @author Alexandre Montplaisir
43 * @author Jonathan Rajotte-Julien
682c435f 44 * @author Gabriel-Andrew Pollo-Guilbert
ea82729d 45 * @since 1.1
f95c9345
AM
46 */
47public final class LamiReportViewTabPage extends TmfComponent {
48
49 // ------------------------------------------------------------------------
50 // Attributes
51 // ------------------------------------------------------------------------
52
53 private final LamiResultTable fResultTable;
f95c9345
AM
54 private final LamiViewerControl fTableViewerControl;
55 private final Set<LamiViewerControl> fCustomGraphViewerControls = new LinkedHashSet<>();
56 private final Composite fControl;
57
682c435f
GAPG
58 private Set<Object> fSelection;
59
f95c9345
AM
60 // ------------------------------------------------------------------------
61 // Constructor
62 // ------------------------------------------------------------------------
63
64 /**
65 * Constructor
66 *
67 * @param parent
68 * Parent composite
69 * @param table
70 * The result table to display in this tab
71 */
72 public LamiReportViewTabPage(Composite parent, LamiResultTable table) {
73 super(table.getTableClass().getTableTitle());
682c435f 74
f95c9345 75 fResultTable = table;
f95c9345
AM
76
77 fControl = parent;
78
682c435f
GAPG
79 /* Map the current trace selection to our lami entry */
80 fSelection = getEntriesIntersectingTimerange(fResultTable, TmfTraceManager.getInstance().getCurrentTraceContext().getSelectionRange());
81
f95c9345 82 /* Prepare the table viewer, which is always present */
3f506e25 83 LamiViewerControl tableViewerControl = new LamiViewerControl(fControl, this);
f95c9345
AM
84 fTableViewerControl = tableViewerControl;
85
86 /* Automatically open the table viewer initially */
682c435f 87 fTableViewerControl.getToggleAction().run();
f95c9345
AM
88
89 /* Simulate a new external signal to the default viewer */
682c435f
GAPG
90 ChartSelectionUpdateSignal chartSignal = new ChartSelectionUpdateSignal(this, fResultTable, fSelection);
91 TmfSignalManager.dispatchSignal(chartSignal);
f95c9345 92
682c435f 93 /* Dispose this class's resource */
f95c9345 94 fControl.addDisposeListener(e -> {
f95c9345
AM
95 fTableViewerControl.dispose();
96 clearAllCustomViewers();
97 super.dispose();
98 });
99 }
100
101 // ------------------------------------------------------------------------
682c435f 102 // Overriden methods
f95c9345
AM
103 // ------------------------------------------------------------------------
104
105 @Override
106 public void dispose() {
682c435f 107 /* fControl's listner will dispose other resources */
f95c9345 108 fControl.dispose();
f95c9345
AM
109 }
110
682c435f
GAPG
111 // ------------------------------------------------------------------------
112 // Operations
113 // ------------------------------------------------------------------------
f95c9345
AM
114
115 /**
682c435f
GAPG
116 * This method is used for creating a chart from the result table of the
117 * analyse. It uses the custom charts plugin to configure and create the
118 * chart.
f95c9345 119 */
682c435f
GAPG
120 public void createNewCustomChart() {
121 Shell shell = this.getControl().getShell();
122 if (shell == null) {
123 return;
124 }
125
126 /* Open the chart maker dialog */
127 ChartMakerDialog dialog = new ChartMakerDialog(shell, fResultTable);
128 if (dialog.open() != Window.OK) {
129 return;
130 }
131
132 /* Make sure the data for making a chart was generated */
133 ChartData data = dialog.getDataSeries();
134 ChartModel model = dialog.getChartModel();
135 if (data == null || model == null) {
136 return;
137 }
138
139 /* Make a chart with the factory constructor */
a805f10b
GB
140 LamiViewerControl viewerControl = new LamiViewerControl(fControl, data, model);
141 fCustomGraphViewerControls.add(viewerControl);
142 viewerControl.getToggleAction().run();
682c435f
GAPG
143 /* Signal the current selection to the newly created graph */
144 ChartSelectionUpdateSignal signal = new ChartSelectionUpdateSignal(LamiReportViewTabPage.this,
145 fResultTable, fSelection);
146 TmfSignalManager.dispatchSignal(signal);
a805f10b
GB
147
148
f95c9345
AM
149 }
150
151 /**
152 * Clear all the custom graph viewers in this tab.
153 */
154 public void clearAllCustomViewers() {
155 fCustomGraphViewerControls.forEach(LamiViewerControl::dispose);
156 fCustomGraphViewerControls.clear();
157 }
158
159 /**
160 * Toggle the display of the table viewer in this tab. This shows it if it
161 * is currently hidden, and vice versa.
162 */
163 public void toggleTableViewer() {
164 fTableViewerControl.getToggleAction().run();
165 }
166
682c435f
GAPG
167 // ------------------------------------------------------------------------
168 // Accessors
169 // ------------------------------------------------------------------------
170
171 /**
172 * Get the SWT control associated with this tab page.
173 *
174 * @return The SWT control
175 */
176 public Composite getControl() {
177 return fControl;
178 }
179
180 /**
181 * Get the result table shown in this tab.
182 *
183 * @return The report result table
184 */
185 public LamiResultTable getResultTable() {
186 return fResultTable;
187 }
188
f95c9345
AM
189 // ------------------------------------------------------------------------
190 // Signals
191 // ------------------------------------------------------------------------
192
682c435f
GAPG
193 // Custom chart signals
194 /**
195 * Signal handler for a chart selection update. It will try to propagate a
196 * {@link TmfSelectionRangeUpdatedSignal} if possible.
197 *
198 * @param signal
199 * The selection update signal
200 */
201 @TmfSignalHandler
202 public void updateSelection(ChartSelectionUpdateSignal signal) {
682c435f
GAPG
203
204 /* Make sure we are not sending a signal to ourself */
205 if (signal.getSource() == this) {
206 return;
207 }
208
209 /* Make sure the signal comes from the data provider's scope */
210 if (fResultTable.hashCode() != signal.getDataProvider().hashCode()) {
211 return;
212 }
213
214 /* Find which index row has been selected */
215 Set<Object> entries = signal.getSelectedObject();
216
682c435f
GAPG
217 /* Update the selection */
218 fSelection = entries;
219
682c435f
GAPG
220 /* Only propagate to all TraceCompass if there is a single selection */
221 if (entries.size() == 1) {
222 LamiTableEntry entry = (LamiTableEntry) Iterables.getOnlyElement(entries);
223
224 /* Make sure the selection represent a time range */
225 LamiTimeRange timeRange = entry.getCorrespondingTimeRange();
226 if (timeRange == null) {
227 return;
228 }
229
230 /* Get the timestamps from the time range */
231 /**
232 * TODO: Consider low and high limits of timestamps here.
233 */
234 Number tsBeginValueNumber = timeRange.getBegin().getValue();
235 Number tsEndValueNumber = timeRange.getEnd().getValue();
236 if(tsBeginValueNumber == null || tsEndValueNumber == null) {
237 return;
238 }
239
240 /* Send Range update to other views */
241 ITmfTimestamp start = TmfTimestamp.fromNanos(tsBeginValueNumber.longValue());
242 ITmfTimestamp end = TmfTimestamp.fromNanos(tsEndValueNumber.longValue());
243 TmfSignalManager.dispatchSignal(new TmfSelectionRangeUpdatedSignal(this, start, end));
244 }
245
246 }
247
248 /**
249 * Signal handler for a trace selection range update signal. It will try to
250 * map the external selection to our lami table entry.
251 *
252 * @param signal
253 * The received signal
254 */
255 @TmfSignalHandler
256 public void externalUpdateSelectionCustomCharts(TmfSelectionRangeUpdatedSignal signal) {
257 /* Make sure we are not sending a signal to ourself */
258 if (signal.getSource() == this) {
259 return;
260 }
261
262 TmfTimeRange range = new TmfTimeRange(signal.getBeginTime(), signal.getEndTime());
263
682c435f
GAPG
264 // Custom chart signal
265 /* Find which lami table entry intersects the signal */
266 Set<Object> selection = getEntriesIntersectingTimerange(fResultTable, range);
267
268 /* Update all LamiViewer */
269 ChartSelectionUpdateSignal updateSignal = new ChartSelectionUpdateSignal(this, fResultTable, selection);
270 TmfSignalManager.dispatchSignal(updateSignal);
271 }
272
273 // ------------------------------------------------------------------------
274 // Util methods
275 // ------------------------------------------------------------------------
276
277 /**
278 * Util method that returns {@link LamiTableEntry} that intersects a
279 * {@link TmfTimeRange}.
280 *
281 * @param table
282 * The result table to search for entries
283 * @param range
284 * The time range itself
285 * @return The set of entries that intersect with the time range
286 */
287 private static Set<Object> getEntriesIntersectingTimerange(LamiResultTable table, TmfTimeRange range) {
288 Set<Object> entries = new HashSet<>();
289 for (LamiTableEntry entry : table.getEntries()) {
290 LamiTimeRange lamiTimeRange = entry.getCorrespondingTimeRange();
291
292 /* Make sure the table has time ranges */
293 if (lamiTimeRange == null) {
294 return entries;
295 }
296
297 /* Get the timestamps from the time range */
298 /**
299 * TODO: Consider low and high limits of timestamps here.
300 */
301 Number tsBeginValueNumber = lamiTimeRange.getBegin().getValue();
302 Number tsEndValueNumber = lamiTimeRange.getEnd().getValue();
303 if(tsBeginValueNumber == null || tsEndValueNumber == null) {
304 return entries;
305 }
306
307 /* Convert the timestamps into TMF timestamps */
308 ITmfTimestamp start = TmfTimestamp.fromNanos(tsBeginValueNumber.longValue());
309 ITmfTimestamp end = TmfTimestamp.fromNanos(tsEndValueNumber.longValue());
310
311 /* Add iff the time range intersects the the signal */
312 TmfTimeRange tempTimeRange = new TmfTimeRange(start, end);
313 if (tempTimeRange.getIntersection(range) != null) {
314 entries.add(entry);
315 }
316 }
317
318 return entries;
319 }
f95c9345 320}
This page took 0.052509 seconds and 5 git commands to generate.