/*******************************************************************************
- * Copyright (c) 2010, 2014 Ericsson
+ * Copyright (c) 2010, 2015 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
package org.eclipse.tracecompass.tmf.ui.viewers.events;
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.TableEditor;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
+import org.eclipse.tracecompass.common.core.NonNullUtils;
import org.eclipse.tracecompass.internal.tmf.core.filter.TmfCollapseFilter;
import org.eclipse.tracecompass.internal.tmf.ui.Activator;
import org.eclipse.tracecompass.internal.tmf.ui.Messages;
import org.eclipse.tracecompass.tmf.core.component.ITmfEventProvider;
import org.eclipse.tracecompass.tmf.core.component.TmfComponent;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
+import org.eclipse.tracecompass.tmf.core.event.aspect.TmfContentFieldAspect;
import org.eclipse.tracecompass.tmf.core.event.collapse.ITmfCollapsibleEvent;
import org.eclipse.tracecompass.tmf.core.event.lookup.ITmfCallsite;
import org.eclipse.tracecompass.tmf.core.event.lookup.ITmfModelLookup;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation;
import org.eclipse.tracecompass.tmf.ui.viewers.events.TmfEventsCache.CachedEvent;
import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn;
-import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableFieldColumn;
import org.eclipse.tracecompass.tmf.ui.views.colors.ColorSetting;
import org.eclipse.tracecompass.tmf.ui.views.colors.ColorSettingsManager;
import org.eclipse.tracecompass.tmf.ui.views.colors.IColorSettingsListener;
*
* @author Francois Chouinard
* @author Patrick Tasse
- * @since 2.0
*/
public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorSettingsListener, ISelectionProvider {
/**
* Empty string array, used by {@link #getItemStrings}.
- * @since 3.0
*/
protected static final @NonNull String[] EMPTY_STRING_ARRAY = new String[0];
/**
* Empty string
- * @since 3.1
*/
protected static final @NonNull String EMPTY_STRING = ""; //$NON-NLS-1$
private static final int FILTER_SUMMARY_INDEX = 1;
private static final int EVENT_COLUMNS_START_INDEX = MARGIN_COLUMN_INDEX + 1;
- /**
- * Default set of columns to use for trace types that do not specify
- * anything
- * @since 3.2
- */
- public static final Collection<TmfEventTableColumn> DEFAULT_COLUMNS = ImmutableList.of(
- TmfEventTableColumn.BaseColumns.TIMESTAMP,
- TmfEventTableColumn.BaseColumns.SOURCE,
- TmfEventTableColumn.BaseColumns.EVENT_TYPE,
- TmfEventTableColumn.BaseColumns.REFERENCE,
- TmfEventTableColumn.BaseColumns.CONTENTS
- );
-
/**
* The events table search/filter keys
*
/** Rank */
String RANK = "$rank"; //$NON-NLS-1$
- /** Field ID */
- String FIELD_ID = "$field_id"; //$NON-NLS-1$
-
/** Bookmark indicator */
String BOOKMARK = "$bookmark"; //$NON-NLS-1$
+
+ /** Event aspect represented by this column */
+ String ASPECT = "$aspect"; //$NON-NLS-1$
}
/**
* The size of the event table cache
*/
public TmfEventsTable(final Composite parent, final int cacheSize) {
- this(parent, cacheSize, DEFAULT_COLUMNS);
+ this(parent, cacheSize, TmfTrace.BASE_ASPECTS);
}
/**
* @param cacheSize
* The size of the event table cache
* @param columnData
- * Unused
+ * The column data array
* @deprecated Deprecated constructor, use
* {@link #TmfEventsTable(Composite, int, Collection)}
*/
final org.eclipse.tracecompass.tmf.ui.widgets.virtualtable.ColumnData[] columnData) {
/*
* We'll do a "best-effort" to keep trace types still using this API to
- * keep working, by defining a TmfEventTableFieldColumn for each
+ * keep working, by defining a TmfEventTableColumn for each
* ColumnData they passed.
*/
this(parent, cacheSize, convertFromColumnData(columnData));
}
@Deprecated
- private static Collection<TmfEventTableColumn> convertFromColumnData(
+ private static @NonNull Iterable<ITmfEventAspect> convertFromColumnData(
org.eclipse.tracecompass.tmf.ui.widgets.virtualtable.ColumnData[] columnData) {
- ImmutableList.Builder<TmfEventTableColumn> builder = new ImmutableList.Builder<>();
+ ImmutableList.Builder<ITmfEventAspect> builder = new ImmutableList.Builder<>();
for (org.eclipse.tracecompass.tmf.ui.widgets.virtualtable.ColumnData col : columnData) {
- String header = col.header;
- if (header != null) {
- builder.add(new TmfEventTableFieldColumn(header));
+ String fieldName = col.header;
+ if (fieldName != null) {
+ builder.add(new TmfContentFieldAspect(fieldName, fieldName));
}
}
- return builder.build();
+ return checkNotNull(builder.build());
}
/**
* The parent composite UI object
* @param cacheSize
* The size of the event table cache
- * @param columns
- * The columns to use in this table.
+ * @param aspects
+ * The event aspects to display in this table. One column per
+ * aspect will be created.
* <p>
* The iteration order of this collection will correspond to the
- * initial ordering of this series of columns in the table.
+ * initial ordering of the columns in the table.
* </p>
- * @since 3.1
*/
public TmfEventsTable(final Composite parent, int cacheSize,
- Collection<? extends TmfEventTableColumn> columns) {
+ @NonNull Iterable<ITmfEventAspect> aspects) {
super("TmfEventsTable"); //$NON-NLS-1$
fComposite = new Composite(parent, SWT.NONE);
fTable.setLinesVisible(true);
// Setup the columns
- if (columns != null) {
- fColumns.addAll(columns);
+ for (ITmfEventAspect aspect : aspects) {
+ if (aspect != null) {
+ fColumns.add(new TmfEventTableColumn(aspect));
+ }
}
TmfMarginColumn collapseCol = new TmfMarginColumn();
TableColumn column = fTable.newTableColumn(SWT.LEFT);
column.setText(col.getHeaderName());
column.setToolTipText(col.getHeaderTooltip());
- column.setData(Key.FIELD_ID, col.getFilterFieldId());
+ column.setData(Key.ASPECT, col.getEventAspect());
column.pack();
if (col instanceof TmfMarginColumn) {
column.setResizable(false);
+ column.addControlListener(new ControlAdapter() {
+ /*
+ * Make sure that the margin column is always first
+ */
+ @Override
+ public void controlMoved(ControlEvent e) {
+ int[] order = fTable.getColumnOrder();
+ if (order[0] == MARGIN_COLUMN_INDEX) {
+ return;
+ }
+ for (int i = order.length - 1; i > 0; i--) {
+ if (order[i] == MARGIN_COLUMN_INDEX) {
+ order[i] = order[i - 1];
+ order[i - 1] = MARGIN_COLUMN_INDEX;
+ }
+ }
+ fTable.setColumnOrder(order);
+ }
+ });
+ } else {
+ column.setMoveable(true);
}
}
fRawViewer.selectAndReveal((Long) e.item.getData(Key.RANK));
}
if (e.item.getData(Key.TIMESTAMP) instanceof ITmfTimestamp) {
- final ITmfTimestamp ts = (ITmfTimestamp) e.item.getData(Key.TIMESTAMP);
+ final ITmfTimestamp ts = NonNullUtils.checkNotNull((ITmfTimestamp) e.item.getData(Key.TIMESTAMP));
if (fTable.getSelectionIndices().length == 1) {
fSelectedBeginTimestamp = ts;
}
- if (fSelectedBeginTimestamp != null) {
- if (fSelectedBeginTimestamp.compareTo(ts) <= 0) {
- broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, fSelectedBeginTimestamp, ts));
+ ITmfTimestamp selectedBeginTimestamp = fSelectedBeginTimestamp;
+ if (selectedBeginTimestamp != null) {
+ if (selectedBeginTimestamp.compareTo(ts) <= 0) {
+ broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, selectedBeginTimestamp, ts));
if (fTable.getSelectionIndices().length == 2) {
- updateStatusLine(ts.getDelta(fSelectedBeginTimestamp));
+ updateStatusLine(ts.getDelta(selectedBeginTimestamp));
}
} else {
- broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, ts, fSelectedBeginTimestamp));
+ broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, checkNotNull(ts), checkNotNull(fSelectedBeginTimestamp)));
updateStatusLine(fSelectedBeginTimestamp.getDelta(ts));
}
}
}
final TableItem[] selection = fTable.getSelection();
if ((selection != null) && (selection.length > 0)) {
- final TmfTimestamp ts = (TmfTimestamp) fTable.getSelection()[0].getData(Key.TIMESTAMP);
+ TableItem item = fTable.getSelection()[0];
+ final TmfTimestamp ts = (TmfTimestamp) item.getData(Key.TIMESTAMP);
if (ts != null) {
broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, ts));
}
+ if (item.getData() instanceof ITmfEvent) {
+ broadcast(new TmfEventSelectedSignal(TmfEventsTable.this, (ITmfEvent) item.getData()));
+ fireSelectionChanged(new SelectionChangedEvent(TmfEventsTable.this, new StructuredSelection(item.getData())));
+ } else {
+ fireSelectionChanged(new SelectionChangedEvent(TmfEventsTable.this, StructuredSelection.EMPTY));
+ }
}
}
});
ParameterizedCommand cmd = ParameterizedCommand.generateCommand(command, parameters);
IEvaluationContext context = handlerService.getCurrentState();
- // Omit the margin column
- List<TmfEventTableColumn> exportColumns = fColumns.subList(EVENT_COLUMNS_START_INDEX, fColumns.size());
+ List<TmfEventTableColumn> exportColumns = new ArrayList<>();
+ for (int i : fTable.getColumnOrder()) {
+ // Omit the margin column
+ if (i >= EVENT_COLUMNS_START_INDEX) {
+ exportColumns.add(fColumns.get(i));
+ }
+ }
context.addVariable(ExportToTextCommandHandler.TMF_EVENT_TABLE_COLUMNS_ID, exportColumns);
handlerService.executeCommandInContext(cmd, null, context);
- } catch (ExecutionException e) {
- displayException(e);
- } catch (NotDefinedException e) {
- displayException(e);
- } catch (NotEnabledException e) {
- displayException(e);
- } catch (NotHandledException e) {
+ } catch (ExecutionException | NotDefinedException | NotEnabledException | NotHandledException e) {
displayException(e);
}
}
// only show collapse filter if at least one trace can be collapsed
boolean isCollapsible = false;
if (fTrace != null) {
- ITmfTrace traces[] = TmfTraceManager.getTraceSet(fTrace);
- for (ITmfTrace trace : traces) {
+ for (ITmfTrace trace : TmfTraceManager.getTraceSet(fTrace)) {
Class <? extends ITmfEvent> eventClass = trace.getEventType();
isCollapsible = ITmfCollapsibleEvent.class.isAssignableFrom(eventClass);
if (isCollapsible) {
*/
protected void setItemData(final TableItem item, final ITmfEvent event, final long rank) {
String[] itemStrings = getItemStrings(fColumns, event);
+
+ // Get the actual ITmfEvent from the CachedEvent
+ ITmfEvent tmfEvent = event;
+ if (event instanceof CachedEvent) {
+ tmfEvent = ((CachedEvent) event).event;
+ }
item.setText(itemStrings);
- item.setData(event);
- item.setData(Key.TIMESTAMP, new TmfTimestamp(event.getTimestamp()));
+ item.setData(tmfEvent);
+ item.setData(Key.TIMESTAMP, new TmfTimestamp(tmfEvent.getTimestamp()));
item.setData(Key.RANK, rank);
final Collection<Long> markerIds = fBookmarksMap.get(rank);
boolean searchNoMatch = false;
final ITmfFilter searchFilter = (ITmfFilter) fTable.getData(Key.SEARCH_OBJ);
if (searchFilter != null) {
- if (searchFilter.matches(event)) {
+ if (searchFilter.matches(tmfEvent)) {
searchMatch = true;
} else {
searchNoMatch = true;
}
}
- final ColorSetting colorSetting = ColorSettingsManager.getColorSetting(event);
+ final ColorSetting colorSetting = ColorSettingsManager.getColorSetting(tmfEvent);
if (searchNoMatch) {
item.setForeground(colorSetting.getDimmedForegroundColor());
item.setBackground(colorSetting.getDimmedBackgroundColor());
return false;
}
final TmfFilterMatchesNode filter = new TmfFilterMatchesNode(null);
- String fieldId = (String) column.getData(Key.FIELD_ID);
- if (fieldId == null) {
- fieldId = column.getText();
- }
- filter.setField(fieldId);
+ ITmfEventAspect aspect = (ITmfEventAspect) column.getData(Key.ASPECT);
+ filter.setEventAspect(aspect);
filter.setRegex(regex);
column.setData(objKey, filter);
column.setData(txtKey, regex);
*
* @param filter
* The filter to apply
- * @since 1.1
*/
protected void applyFilter(ITmfFilter filter) {
stopFilterThread();
* @param event
* The event printed in this row
* @return The event row entries
- * @since 3.0
*/
public String[] getItemStrings(ITmfEvent event) {
- return getItemStrings(fColumns, event);
+ List<TmfEventTableColumn> columns = new ArrayList<>();
+ for (int i : fTable.getColumnOrder()) {
+ columns.add(fColumns.get(i));
+ }
+ return getItemStrings(columns, event);
}
/**
*
* @param statusLineManager
* The status line manager, or null to disable status line messages
- * @since 2.1
*/
public void setStatusLineManager(IStatusLineManager statusLineManager) {
if (fStatusLineManager != null && statusLineManager == null) {
// ISelectionProvider
// ------------------------------------------------------------------------
- /**
- * @since 2.0
- */
@Override
public void addSelectionChangedListener(ISelectionChangedListener listener) {
selectionChangedListeners.add(listener);
}
- /**
- * @since 2.0
- */
@Override
public ISelection getSelection() {
if (fTable == null || fTable.isDisposed()) {
return new StructuredSelection(list);
}
- /**
- * @since 2.0
- */
@Override
public void removeSelectionChangedListener(ISelectionChangedListener listener) {
selectionChangedListeners.remove(listener);
}
- /**
- * @since 2.0
- */
@Override
public void setSelection(ISelection selection) {
// not implemented
* @param event a selection changed event
*
* @see ISelectionChangedListener#selectionChanged
- * @since 2.0
*/
protected void fireSelectionChanged(final SelectionChangedEvent event) {
Object[] listeners = selectionChangedListeners.getListeners();
}
@Override
- public void handleCompleted() {
- super.handleCompleted();
+ public void handleSuccess() {
+ super.handleSuccess();
if (fTrace == null) {
return;
}
}
/**
- * @since 2.0
+ * Refresh the table
*/
public void refresh() {
fCache.clear();
}
/**
- * Margin column for images and special text (e.g. collapse count)
- */
- private static final class TmfMarginColumn extends TmfEventTableColumn {
-
- private static final @NonNull String HEADER = EMPTY_STRING;
-
- /**
- * Constructor
- */
- public TmfMarginColumn() {
- super(HEADER);
- }
-
- @Override
- public String getItemString(ITmfEvent event) {
- if (!(event instanceof CachedEvent) || ((CachedEvent) event).repeatCount == 0) {
- return EMPTY_STRING;
- }
- return "+" + ((CachedEvent) event).repeatCount; //$NON-NLS-1$
- }
-
- @Override
- public String getFilterFieldId() {
- return null;
- }
- }
+ * Margin column for images and special text (e.g. collapse count)
+ */
+ private static final class TmfMarginColumn extends TmfEventTableColumn {
+
+ private static final @NonNull ITmfEventAspect MARGIN_ASPECT = new ITmfEventAspect() {
+
+ @Override
+ public String getName() {
+ return EMPTY_STRING;
+ }
+
+ @Override
+ public String resolve(ITmfEvent event) {
+ if (!(event instanceof CachedEvent) || ((CachedEvent) event).repeatCount == 0) {
+ return EMPTY_STRING;
+ }
+ return "+" + ((CachedEvent) event).repeatCount; //$NON-NLS-1$
+ }
+
+ @Override
+ public String getHelpText() {
+ return EMPTY_STRING;
+ }
+ };
+
+ /**
+ * Constructor
+ */
+ public TmfMarginColumn() {
+ super(MARGIN_ASPECT);
+ }
+ }
}