1 /*******************************************************************************
2 * Copyright (c) 2015, 2016 Ericsson, EfficiOS Inc. and others
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 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.internal
.provisional
.analysis
.lami
.ui
.viewers
;
13 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
14 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.nullToEmptyString
;
16 import java
.util
.HashSet
;
17 import java
.util
.List
;
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
;
40 * Table viewer to use in {@link LamiReportView}s.
42 * @author Alexandre Montplaisir
44 public final class LamiTableViewer
extends TmfSimpleTableViewer
implements ILamiViewer
{
46 // ------------------------------------------------------------------------
48 // ------------------------------------------------------------------------
50 private final LamiResultTable fResultTable
;
51 private Set
<Integer
> fSelections
;
53 // ------------------------------------------------------------------------
54 // Inner class definitions
55 // ------------------------------------------------------------------------
58 * Abstract class for the column label provider for the latency analysis
61 private static class LamiTableColumnLabelProvider
extends ColumnLabelProvider
{
63 private final LamiTableEntryAspect fColumnAspect
;
65 public LamiTableColumnLabelProvider(LamiTableEntryAspect aspect
) {
66 fColumnAspect
= aspect
;
70 public String
getText(@Nullable Object input
) {
71 if (!(input
instanceof LamiTableEntry
)) {
72 /* Doubles as a null check */
73 return ""; //$NON-NLS-1$
75 LamiTableEntry entry
= (LamiTableEntry
) input
;
76 return nullToEmptyString(fColumnAspect
.resolveString(entry
));
81 * Listener to update in other viewers when a cell of the latency
82 * table view is selected
84 private class LamiTableSelectionListener
extends SelectionAdapter
{
86 public void widgetSelected(@Nullable SelectionEvent e
) {
88 IStructuredSelection selections
= getTableViewer().getStructuredSelection();
90 Set
<Integer
> selectionIndexes
= new HashSet
<>();
91 for (Object selectedEntry
: selections
.toArray() ) {
92 selectionIndexes
.add(fResultTable
.getEntries().indexOf(selectedEntry
));
95 fSelections
= selectionIndexes
;
97 /* Signal all Lami viewers & views of the selection */
98 LamiSelectionUpdateSignal signal
= new LamiSelectionUpdateSignal(LamiTableViewer
.this, selectionIndexes
, checkNotNull(fResultTable
).hashCode());
99 TmfSignalManager
.dispatchSignal(signal
);
103 // ------------------------------------------------------------------------
105 // ------------------------------------------------------------------------
111 * Table viewer of the view
113 * Data table populating this viewer
115 public LamiTableViewer(TableViewer tableViewer
, LamiResultTable resultTable
) {
118 * The table viewer should always be the first element in the control.
120 tableViewer
.getTable().moveAbove(null);
122 fResultTable
= resultTable
;
123 fSelections
= new HashSet
<>();
125 /* Default sort order of the content provider is by its first column */
126 getTableViewer().setContentProvider(new LamiTableContentProvider());
127 getTableViewer().getTable().addSelectionListener(new LamiTableSelectionListener());
133 // ------------------------------------------------------------------------
135 // ------------------------------------------------------------------------
137 private void createColumns() {
138 final List
<LamiTableEntryAspect
> aspects
= fResultTable
.getTableClass().getAspects();
140 Display
.getDefault().asyncExec(new Runnable() {
143 for (LamiTableEntryAspect aspect
: aspects
) {
144 createColumn(aspect
.getLabel(), new LamiTableColumnLabelProvider(aspect
), aspect
.getComparator());
151 * Update the data in the table viewer
156 private void fillData() {
157 final TableViewer tableViewer
= getTableViewer();
158 Display
.getDefault().asyncExec(() -> {
159 if (tableViewer
.getTable().isDisposed()) {
162 // Go to the top of the table
163 tableViewer
.getTable().setTopIndex(0);
164 // Reset selected row
165 tableViewer
.setSelection(StructuredSelection
.EMPTY
);
167 /* Fill the table data */
168 tableViewer
.setInput(fResultTable
.getEntries());
169 LamiTableContentProvider latencyContentProvider
= (LamiTableContentProvider
) getTableViewer().getContentProvider();
170 tableViewer
.setItemCount(latencyContentProvider
.getNbEntries());
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
);
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.
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();
196 Display
.getDefault().asyncExec(() -> {
197 if (tableViewer
.getTable().isDisposed()) {
201 TableColumn
[] cols
= tableViewer
.getTable().getColumns();
202 for (int i
= 0; i
< cols
.length
; i
++) {
209 * The signal handler for selection update.
212 * The selection update signal
215 public void updateSelection(LamiSelectionUpdateSignal signal
) {
217 if (fResultTable
.hashCode() != signal
.getSignalHash() || equals(signal
.getSource())) {
218 /* The signal is not for us */
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();
224 Set
<Integer
> selections
= signal
.getEntryIndex();
226 int[] selectionsIndexes
= selections
.stream()
227 .map(index
-> fResultTable
.getEntries().get(index
))
228 .mapToInt(entry
-> latencyContentProvider
.getIndexOf(entry
))
231 fSelections
= new HashSet
<>(selections
);
233 Display
.getDefault().asyncExec(() -> {
234 getTableViewer().getTable().setSelection(selectionsIndexes
);
235 getTableViewer().getTable().redraw();