analysis.lami: Show one view per report
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.lami.ui / src / org / eclipse / tracecompass / internal / provisional / analysis / lami / ui / viewers / LamiTableViewer.java
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
10 package org.eclipse.tracecompass.internal.provisional.analysis.lami.ui.viewers;
11
12
13 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
14 import static org.eclipse.tracecompass.common.core.NonNullUtils.nullToEmptyString;
15
16 import java.util.HashSet;
17 import java.util.List;
18 import java.util.Set;
19
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.eclipse.jface.viewers.ColumnLabelProvider;
22 import org.eclipse.jface.viewers.IStructuredSelection;
23 import org.eclipse.jface.viewers.StructuredSelection;
24 import org.eclipse.jface.viewers.TableViewer;
25 import org.eclipse.swt.SWT;
26 import org.eclipse.swt.events.SelectionAdapter;
27 import org.eclipse.swt.events.SelectionEvent;
28 import org.eclipse.swt.widgets.Display;
29 import org.eclipse.swt.widgets.TableColumn;
30 import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.aspect.LamiTableEntryAspect;
31 import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.module.LamiResultTable;
32 import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.module.LamiTableEntry;
33 import org.eclipse.tracecompass.internal.provisional.analysis.lami.ui.signals.LamiSelectionUpdateSignal;
34 import org.eclipse.tracecompass.internal.provisional.analysis.lami.ui.views.LamiReportView;
35 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
36 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
37 import org.eclipse.tracecompass.tmf.ui.viewers.table.TmfSimpleTableViewer;
38
39 /**
40 * Table viewer to use in {@link LamiReportView}s.
41 *
42 * @author Alexandre Montplaisir
43 */
44 public final class LamiTableViewer extends TmfSimpleTableViewer implements ILamiViewer {
45
46 // ------------------------------------------------------------------------
47 // Attributes
48 // ------------------------------------------------------------------------
49
50 private final LamiResultTable fResultTable;
51 private Set<Integer> fSelections;
52
53 // ------------------------------------------------------------------------
54 // Inner class definitions
55 // ------------------------------------------------------------------------
56
57 /**
58 * Abstract class for the column label provider for the latency analysis
59 * table viewer
60 */
61 private static class LamiTableColumnLabelProvider extends ColumnLabelProvider {
62
63 private final LamiTableEntryAspect fColumnAspect;
64
65 public LamiTableColumnLabelProvider(LamiTableEntryAspect aspect) {
66 fColumnAspect = aspect;
67 }
68
69 @Override
70 public String getText(@Nullable Object input) {
71 if (!(input instanceof LamiTableEntry)) {
72 /* Doubles as a null check */
73 return ""; //$NON-NLS-1$
74 }
75 LamiTableEntry entry = (LamiTableEntry) input;
76 return nullToEmptyString(fColumnAspect.resolveString(entry));
77 }
78 }
79
80 /**
81 * Listener to update in other viewers when a cell of the latency
82 * table view is selected
83 */
84 private class LamiTableSelectionListener extends SelectionAdapter {
85 @Override
86 public void widgetSelected(@Nullable SelectionEvent e) {
87
88 IStructuredSelection selections = getTableViewer().getStructuredSelection();
89
90 Set<Integer> selectionIndexes = new HashSet<>();
91 for (Object selectedEntry : selections.toArray() ) {
92 selectionIndexes.add(fResultTable.getEntries().indexOf(selectedEntry));
93 }
94
95 fSelections = selectionIndexes;
96
97 /* Signal all Lami viewers & views of the selection */
98 LamiSelectionUpdateSignal signal = new LamiSelectionUpdateSignal(LamiTableViewer.this, selectionIndexes, checkNotNull(fResultTable).hashCode());
99 TmfSignalManager.dispatchSignal(signal);
100 }
101 }
102
103 // ------------------------------------------------------------------------
104 // Constructor
105 // ------------------------------------------------------------------------
106
107 /**
108 * Constructor
109 *
110 * @param tableViewer
111 * Table viewer of the view
112 * @param resultTable
113 * Data table populating this viewer
114 */
115 public LamiTableViewer(TableViewer tableViewer, LamiResultTable resultTable) {
116 super(tableViewer);
117 /*
118 * The table viewer should always be the first element in the control.
119 */
120 tableViewer.getTable().moveAbove(null);
121
122 fResultTable = resultTable;
123 fSelections = new HashSet<>();
124
125 /* Default sort order of the content provider is by its first column */
126 getTableViewer().setContentProvider(new LamiTableContentProvider());
127 getTableViewer().getTable().addSelectionListener(new LamiTableSelectionListener());
128
129 createColumns();
130 fillData();
131 }
132
133 // ------------------------------------------------------------------------
134 // Operations
135 // ------------------------------------------------------------------------
136
137 private void createColumns() {
138 final List<LamiTableEntryAspect> aspects = fResultTable.getTableClass().getAspects();
139
140 Display.getDefault().asyncExec(new Runnable() {
141 @Override
142 public void run() {
143 for (LamiTableEntryAspect aspect : aspects) {
144 createColumn(aspect.getLabel(), new LamiTableColumnLabelProvider(aspect), aspect.getComparator());
145 }
146 }
147 });
148 }
149
150 /**
151 * Update the data in the table viewer
152 *
153 * @param dataInput
154 * New data input
155 */
156 private void fillData() {
157 final TableViewer tableViewer = getTableViewer();
158 Display.getDefault().asyncExec(() -> {
159 if (tableViewer.getTable().isDisposed()) {
160 return;
161 }
162 // Go to the top of the table
163 tableViewer.getTable().setTopIndex(0);
164 // Reset selected row
165 tableViewer.setSelection(StructuredSelection.EMPTY);
166
167 /* Fill the table data */
168 tableViewer.setInput(fResultTable.getEntries());
169 LamiTableContentProvider latencyContentProvider = (LamiTableContentProvider) getTableViewer().getContentProvider();
170 tableViewer.setItemCount(latencyContentProvider.getNbEntries());
171
172 /* Set the column's alignment and pack them */
173 TableColumn[] cols = tableViewer.getTable().getColumns();
174 for (int i = 0; i < cols.length; i++) {
175 LamiTableEntryAspect colAspect = fResultTable.getTableClass().getAspects().get(i);
176 int alignment = (colAspect.isContinuous() ? SWT.RIGHT : SWT.LEFT);
177 cols[i].setAlignment(alignment);
178
179 }
180
181 /*
182 * On creation check if there is selections if so update the table
183 * selections here. Selections needs the ContentProvider for valid
184 * index lookup and since the content provider is set in an
185 * asynchronous task we cannot use the normal signal handler since
186 * we have no guarantee of time of execution of the fill data.
187 */
188 if (!fSelections.isEmpty()) {
189 int[] selectionsIndexes = fSelections.stream().map(index -> fResultTable.getEntries().get(index)).mapToInt(entry -> ((LamiTableContentProvider) getTableViewer().getContentProvider()).getIndexOf(entry)).toArray();
190 Display.getDefault().asyncExec(() -> {
191 getTableViewer().getTable().setSelection(selectionsIndexes);
192 getTableViewer().getTable().redraw();
193 });
194 }
195 });
196 Display.getDefault().asyncExec(() -> {
197 if (tableViewer.getTable().isDisposed()) {
198 return;
199 }
200
201 TableColumn[] cols = tableViewer.getTable().getColumns();
202 for (int i = 0; i < cols.length; i++) {
203 cols[i].pack();
204 }
205 });
206 }
207
208 /**
209 * The signal handler for selection update.
210 *
211 * @param signal
212 * The selection update signal
213 */
214 @TmfSignalHandler
215 public void updateSelection(LamiSelectionUpdateSignal signal) {
216
217 if (fResultTable.hashCode() != signal.getSignalHash() || equals(signal.getSource())) {
218 /* The signal is not for us */
219 return;
220 }
221 /* Fetch the position of the selected entry in the actual table since it could be sorted by another column */
222 LamiTableContentProvider latencyContentProvider = (LamiTableContentProvider) getTableViewer().getContentProvider();
223
224 Set<Integer> selections = signal.getEntryIndex();
225
226 int[] selectionsIndexes = selections.stream()
227 .map(index -> fResultTable.getEntries().get(index))
228 .mapToInt(entry -> latencyContentProvider.getIndexOf(entry))
229 .toArray();
230
231 fSelections = new HashSet<>(selections);
232
233 Display.getDefault().asyncExec(() -> {
234 getTableViewer().getTable().setSelection(selectionsIndexes);
235 getTableViewer().getTable().redraw();
236 });
237 }
238 }
This page took 0.040064 seconds and 5 git commands to generate.