lami.ui: Replace LAMI charts with custom charts
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.lami.ui / src / org / eclipse / tracecompass / internal / provisional / analysis / lami / ui / viewers / LamiTableViewer.java
CommitLineData
4208b510
AM
1/*******************************************************************************
2 * Copyright (c) 2015, 2016 Ericsson, EfficiOS Inc. and others
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.viewers;
11
682c435f 12import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
4208b510
AM
13import static org.eclipse.tracecompass.common.core.NonNullUtils.nullToEmptyString;
14
15import java.util.HashSet;
16import java.util.List;
17import java.util.Set;
18
19import org.eclipse.jdt.annotation.Nullable;
20import org.eclipse.jface.viewers.ColumnLabelProvider;
21import org.eclipse.jface.viewers.IStructuredSelection;
22import org.eclipse.jface.viewers.StructuredSelection;
23import org.eclipse.jface.viewers.TableViewer;
24import org.eclipse.swt.SWT;
25import org.eclipse.swt.events.SelectionAdapter;
26import org.eclipse.swt.events.SelectionEvent;
27import org.eclipse.swt.widgets.Display;
28import org.eclipse.swt.widgets.TableColumn;
29import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.aspect.LamiTableEntryAspect;
4208b510
AM
30import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.module.LamiTableEntry;
31import org.eclipse.tracecompass.internal.provisional.analysis.lami.ui.signals.LamiSelectionUpdateSignal;
32import org.eclipse.tracecompass.internal.provisional.analysis.lami.ui.views.LamiReportView;
3f506e25 33import org.eclipse.tracecompass.internal.provisional.analysis.lami.ui.views.LamiReportViewTabPage;
682c435f 34import org.eclipse.tracecompass.internal.provisional.tmf.chart.core.signal.ChartSelectionUpdateSignal;
4208b510
AM
35import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
36import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
37import org.eclipse.tracecompass.tmf.ui.viewers.table.TmfSimpleTableViewer;
38
39/**
40 * Table viewer to use in {@link LamiReportView}s.
41 *
42 * @author Alexandre Montplaisir
682c435f 43 * @author Gabriel-Andrew Pollo-Guilbert
4208b510
AM
44 */
45public final class LamiTableViewer extends TmfSimpleTableViewer implements ILamiViewer {
46
47 // ------------------------------------------------------------------------
48 // Attributes
49 // ------------------------------------------------------------------------
50
3f506e25 51 private final LamiReportViewTabPage fPage;
4208b510 52 private Set<Integer> fSelections;
682c435f 53 private Set<Object> fSelection;
4208b510
AM
54
55 // ------------------------------------------------------------------------
56 // Inner class definitions
57 // ------------------------------------------------------------------------
58
59 /**
60 * Abstract class for the column label provider for the latency analysis
682c435f 61 * table viewer.
4208b510
AM
62 */
63 private static class LamiTableColumnLabelProvider extends ColumnLabelProvider {
4208b510
AM
64 private final LamiTableEntryAspect fColumnAspect;
65
66 public LamiTableColumnLabelProvider(LamiTableEntryAspect aspect) {
67 fColumnAspect = aspect;
68 }
69
70 @Override
71 public String getText(@Nullable Object input) {
682c435f 72 /* Doubles as a null check */
4208b510 73 if (!(input instanceof LamiTableEntry)) {
4208b510
AM
74 return ""; //$NON-NLS-1$
75 }
682c435f
GAPG
76
77 return nullToEmptyString(fColumnAspect.resolveString((LamiTableEntry) input));
4208b510
AM
78 }
79 }
80
81 /**
682c435f
GAPG
82 * Listener to update in other viewers when a cell of the latency table view
83 * is selected.
4208b510
AM
84 */
85 private class LamiTableSelectionListener extends SelectionAdapter {
86 @Override
682c435f 87 public void widgetSelected(@Nullable SelectionEvent event) {
4208b510
AM
88 IStructuredSelection selections = getTableViewer().getStructuredSelection();
89
682c435f 90 // Lami selections
4208b510
AM
91 Set<Integer> selectionIndexes = new HashSet<>();
92 for (Object selectedEntry : selections.toArray() ) {
3f506e25 93 selectionIndexes.add(fPage.getResultTable().getEntries().indexOf(selectedEntry));
4208b510
AM
94 }
95
96 fSelections = selectionIndexes;
97
98 /* Signal all Lami viewers & views of the selection */
3f506e25 99 LamiSelectionUpdateSignal signal = new LamiSelectionUpdateSignal(LamiTableViewer.this, selectionIndexes, fPage);
4208b510 100 TmfSignalManager.dispatchSignal(signal);
682c435f
GAPG
101
102 /* Find all selected entries */
103 Set<Object> selectionSet = new HashSet<>();
104 for (Object selectedEntry : selections.toArray()) {
105 selectionSet.add(checkNotNull(selectedEntry));
106 }
107 fSelection = selectionSet;
108
109
110 /* Signal all Lami viewers & views of the selection */
111 ChartSelectionUpdateSignal customSignal = new ChartSelectionUpdateSignal(LamiTableViewer.this, fPage.getResultTable(), selectionSet);
112 TmfSignalManager.dispatchSignal(customSignal);
4208b510
AM
113 }
114 }
115
116 // ------------------------------------------------------------------------
682c435f 117 // Constructors
4208b510
AM
118 // ------------------------------------------------------------------------
119
120 /**
121 * Constructor
122 *
123 * @param tableViewer
124 * Table viewer of the view
3f506e25
JR
125 * @param page
126 * The {@link LamiReportViewTabPage} parent page
4208b510 127 */
3f506e25 128 public LamiTableViewer(TableViewer tableViewer, LamiReportViewTabPage page) {
4208b510 129 super(tableViewer);
682c435f
GAPG
130
131 /* The viewer should always be the first element in the control. */
4208b510
AM
132 tableViewer.getTable().moveAbove(null);
133
3f506e25 134 fPage = page;
4208b510 135 fSelections = new HashSet<>();
682c435f 136 fSelection = new HashSet<>();
4208b510
AM
137
138 /* Default sort order of the content provider is by its first column */
139 getTableViewer().setContentProvider(new LamiTableContentProvider());
140 getTableViewer().getTable().addSelectionListener(new LamiTableSelectionListener());
141
142 createColumns();
143 fillData();
144 }
145
146 // ------------------------------------------------------------------------
147 // Operations
148 // ------------------------------------------------------------------------
149
150 private void createColumns() {
3f506e25 151 final List<LamiTableEntryAspect> aspects = fPage.getResultTable().getTableClass().getAspects();
4208b510
AM
152
153 Display.getDefault().asyncExec(new Runnable() {
154 @Override
155 public void run() {
156 for (LamiTableEntryAspect aspect : aspects) {
157 createColumn(aspect.getLabel(), new LamiTableColumnLabelProvider(aspect), aspect.getComparator());
158 }
159 }
160 });
161 }
162
163 /**
164 * Update the data in the table viewer
165 *
166 * @param dataInput
167 * New data input
168 */
169 private void fillData() {
170 final TableViewer tableViewer = getTableViewer();
171 Display.getDefault().asyncExec(() -> {
172 if (tableViewer.getTable().isDisposed()) {
173 return;
174 }
175 // Go to the top of the table
176 tableViewer.getTable().setTopIndex(0);
177 // Reset selected row
178 tableViewer.setSelection(StructuredSelection.EMPTY);
179
180 /* Fill the table data */
3f506e25 181 tableViewer.setInput(fPage.getResultTable().getEntries());
4208b510
AM
182 LamiTableContentProvider latencyContentProvider = (LamiTableContentProvider) getTableViewer().getContentProvider();
183 tableViewer.setItemCount(latencyContentProvider.getNbEntries());
184
185 /* Set the column's alignment and pack them */
186 TableColumn[] cols = tableViewer.getTable().getColumns();
187 for (int i = 0; i < cols.length; i++) {
3f506e25 188 LamiTableEntryAspect colAspect = fPage.getResultTable().getTableClass().getAspects().get(i);
4208b510
AM
189 int alignment = (colAspect.isContinuous() ? SWT.RIGHT : SWT.LEFT);
190 cols[i].setAlignment(alignment);
191
192 }
193
194 /*
195 * On creation check if there is selections if so update the table
196 * selections here. Selections needs the ContentProvider for valid
197 * index lookup and since the content provider is set in an
198 * asynchronous task we cannot use the normal signal handler since
199 * we have no guarantee of time of execution of the fill data.
200 */
201 if (!fSelections.isEmpty()) {
3f506e25
JR
202 int[] selectionsIndexes = fSelections.stream()
203 .map(index -> fPage.getResultTable().getEntries().get(index))
204 .mapToInt(entry -> ((LamiTableContentProvider) getTableViewer().getContentProvider()).getIndexOf(entry))
205 .toArray();
206
4208b510
AM
207 Display.getDefault().asyncExec(() -> {
208 getTableViewer().getTable().setSelection(selectionsIndexes);
209 getTableViewer().getTable().redraw();
210 });
211 }
682c435f
GAPG
212 if (!fSelection.isEmpty()) {
213 LamiTableContentProvider provider = (LamiTableContentProvider) getTableViewer().getContentProvider();
214
215 /* Find the indexes in the UI table of the selected objects */
216 int[] selectionsIndexes = fSelection.stream()
217 .map(obj -> (LamiTableEntry) obj)
218 .mapToInt(entry -> provider.getIndexOf(checkNotNull(entry)))
219 .toArray();
220
221 /* Update the selection in the UI table */
222 Display.getDefault().asyncExec(() -> {
223 getTableViewer().getTable().setSelection(selectionsIndexes);
224 getTableViewer().getTable().redraw();
225 });
226 }
4208b510
AM
227 });
228 Display.getDefault().asyncExec(() -> {
f95c9345
AM
229 if (tableViewer.getTable().isDisposed()) {
230 return;
231 }
232
4208b510
AM
233 TableColumn[] cols = tableViewer.getTable().getColumns();
234 for (int i = 0; i < cols.length; i++) {
235 cols[i].pack();
236 }
237 });
238 }
239
682c435f
GAPG
240 // ------------------------------------------------------------------------
241 // Signals
242 // ------------------------------------------------------------------------
243
4208b510
AM
244 /**
245 * The signal handler for selection update.
246 *
247 * @param signal
248 * The selection update signal
249 */
250 @TmfSignalHandler
251 public void updateSelection(LamiSelectionUpdateSignal signal) {
252
3f506e25 253 if (fPage != signal.getSignalKey() || equals(signal.getSource())) {
4208b510
AM
254 /* The signal is not for us */
255 return;
256 }
257 /* Fetch the position of the selected entry in the actual table since it could be sorted by another column */
258 LamiTableContentProvider latencyContentProvider = (LamiTableContentProvider) getTableViewer().getContentProvider();
259
260 Set<Integer> selections = signal.getEntryIndex();
261
262 int[] selectionsIndexes = selections.stream()
3f506e25 263 .map(index -> fPage.getResultTable().getEntries().get(index))
4208b510
AM
264 .mapToInt(entry -> latencyContentProvider.getIndexOf(entry))
265 .toArray();
266
267 fSelections = new HashSet<>(selections);
268
269 Display.getDefault().asyncExec(() -> {
270 getTableViewer().getTable().setSelection(selectionsIndexes);
271 getTableViewer().getTable().redraw();
272 });
273 }
682c435f
GAPG
274
275 /**
276 * The signal handler for selection update.
277 *
278 * @param signal
279 * The selection update signal
280 */
281 @TmfSignalHandler
282 public void updateCustomSelection(ChartSelectionUpdateSignal signal) {
283 /* Make sure we are not sending a signal to ourself */
284 if (signal.getSource() == this) {
285 return;
286 }
287
288 /* Make sure the signal comes from the data provider's scope */
289 if (fPage.getResultTable().hashCode() != signal.getDataProvider().hashCode()) {
290 return;
291 }
292
293 /* Get the set of selected objects */
294 fSelection = signal.getSelectedObject();
295
296 /* Get the selected index in the UI table */
297 LamiTableContentProvider tableContentProvider = (LamiTableContentProvider) getTableViewer().getContentProvider();
298 int[] tableSelection = fSelection.stream()
299 .map(obj -> (LamiTableEntry) obj)
300 .mapToInt(entry -> tableContentProvider.getIndexOf(checkNotNull(entry)))
301 .toArray();
302
303 /* Update the selection in the UI table */
304 Display.getDefault().asyncExec(() -> {
305 getTableViewer().getTable().setSelection(tableSelection);
306 getTableViewer().getTable().redraw();
307 });
308 }
309
4208b510 310}
This page took 0.049085 seconds and 5 git commands to generate.