/*******************************************************************************
- * 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 java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.resource.FontDescriptor;
+import org.eclipse.jface.resource.FontRegistry;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
+import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.OpenStrategy;
+import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.custom.StyleRange;
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.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
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.signal.TmfEventSearchAppliedSignal;
import org.eclipse.tracecompass.tmf.core.signal.TmfEventSelectedSignal;
import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
-import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal;
+import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceUpdatedSignal;
import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
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;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.ide.IGotoMarker;
import org.eclipse.ui.themes.ColorUtil;
+import org.eclipse.ui.themes.IThemeManager;
import com.google.common.base.Joiner;
import com.google.common.collect.HashMultimap;
*
* @author Francois Chouinard
* @author Patrick Tasse
- * @since 2.0
*/
-public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorSettingsListener, ISelectionProvider {
+public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorSettingsListener, ISelectionProvider, IPropertyChangeListener {
/**
* 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 boolean IS_LINUX = System.getProperty("os.name").contains("Linux") ? true : false; //$NON-NLS-1$ //$NON-NLS-2$
+ private static final String FONT_DEFINITION_ID = "org.eclipse.tracecompass.tmf.ui.font.eventtable"; //$NON-NLS-1$
+
private static final Image BOOKMARK_IMAGE = Activator.getDefault().getImageFromPath(
"icons/elcl16/bookmark_obj.gif"); //$NON-NLS-1$
private static final Image SEARCH_IMAGE = Activator.getDefault().getImageFromPath("icons/elcl16/search.gif"); //$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$
+
+ /** Table item list of style ranges
+ * @since 1.0*/
+ String STYLE_RANGES = "$style_ranges"; //$NON-NLS-1$
}
/**
private LocalResourceManager fResourceManager = new LocalResourceManager(JFaceResources.getResources());
private Color fGrayColor;
private Color fGreenColor;
+ private Font fFont;
private Font fBoldFont;
private final List<TmfEventTableColumn> fColumns = new LinkedList<>();
private boolean fCacheUpdateCompleted = false;
private final Object fCacheUpdateSyncObj = new Object();
+ // Keep track of column order, it is needed after table is disposed
+ private int[] fColumnOrder;
+
private boolean fDisposeOnClose;
// ------------------------------------------------------------------------
* 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);
+ } else {
+ column.setMoveable(true);
}
+ column.addControlListener(new ControlAdapter() {
+ /*
+ * Make sure that the margin column is always first
+ * and keep the column order variable up to date.
+ */
+ @Override
+ public void controlMoved(ControlEvent e) {
+ int[] order = fTable.getColumnOrder();
+ if (order[0] == MARGIN_COLUMN_INDEX) {
+ fColumnOrder = order;
+ 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);
+ fColumnOrder = fTable.getColumnOrder();
+ }
+ });
}
+ fColumnOrder = fTable.getColumnOrder();
// Set the frozen row for header row
fTable.setFrozenRowCount(1);
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 TmfSelectionRangeUpdatedSignal(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 TmfSelectionRangeUpdatedSignal(TmfEventsTable.this, checkNotNull(ts), checkNotNull(fSelectedBeginTimestamp)));
updateStatusLine(fSelectedBeginTimestamp.getDelta(ts));
}
}
fTable.addListener(SWT.MouseDown, tooltipListener);
fTable.addListener(SWT.MouseWheel, tooltipListener);
+ fTable.addListener(SWT.EraseItem, new Listener() {
+ @Override
+ public void handleEvent(Event event) {
+ TableItem item = (TableItem) event.item;
+ List<?> styleRanges = (List<?>) item.getData(Key.STYLE_RANGES);
+
+ GC gc = event.gc;
+ Color background = item.getBackground(event.index);
+ /*
+ * Paint the background if it is not the default system color.
+ * In Windows, if you let the widget draw the background, it
+ * will not show the item's background color if the item is
+ * selected or hot. If there are no style ranges and the item
+ * background is the default system color, we do not want to
+ * paint it or otherwise we would override the platform theme
+ * (e.g. alternating colors).
+ */
+ if (styleRanges != null || !background.equals(item.getParent().getBackground())) {
+ // we will paint the table item's background
+ event.detail &= ~SWT.BACKGROUND;
+
+ // paint the item's default background
+ gc.setBackground(background);
+ gc.fillRectangle(event.x, event.y, event.width, event.height);
+ }
+
+ /*
+ * We will paint the table item's foreground. In Windows, if you paint
+ * the background but let the widget draw the foreground, it will
+ * override your background, unless the item is selected or hot.
+ */
+ event.detail &= ~SWT.FOREGROUND;
+
+ // paint the highlighted background for all style ranges
+ if (styleRanges != null) {
+ Rectangle textBounds = item.getTextBounds(event.index);
+ String text = item.getText(event.index);
+ for (Object o : styleRanges) {
+ if (o instanceof StyleRange) {
+ StyleRange styleRange = (StyleRange) o;
+ if (styleRange.data.equals(event.index)) {
+ int startIndex = styleRange.start;
+ int endIndex = startIndex + styleRange.length;
+ int startX = gc.stringExtent(text.substring(0, startIndex)).x;
+ int endX = gc.stringExtent(text.substring(0, endIndex)).x;
+ gc.setBackground(styleRange.background);
+ gc.fillRectangle(textBounds.x + startX, textBounds.y, (endX - startX), textBounds.height);
+ }
+ }
+ }
+ }
+ }
+ });
+
+ fTable.addListener(SWT.PaintItem, new Listener() {
+ @Override
+ public void handleEvent(Event event) {
+ TableItem item = (TableItem) event.item;
+
+ // we promised to paint the table item's foreground
+ GC gc = event.gc;
+ Image image = item.getImage(event.index);
+ if (image != null) {
+ Rectangle imageBounds = item.getImageBounds(event.index);
+ /*
+ * The image bounds don't match the default image position.
+ */
+ if (IS_LINUX) {
+ gc.drawImage(image, imageBounds.x + 1, imageBounds.y + 3);
+ } else {
+ gc.drawImage(image, imageBounds.x, imageBounds.y + 1);
+ }
+ }
+ gc.setForeground(item.getForeground(event.index));
+ gc.setFont(item.getFont(event.index));
+ String text = item.getText(event.index);
+ Rectangle textBounds = item.getTextBounds(event.index);
+ /*
+ * The text bounds don't match the default text position.
+ */
+ if (IS_LINUX) {
+ gc.drawText(text, textBounds.x + 1, textBounds.y + 3, true);
+ } else {
+ gc.drawText(text, textBounds.x - 1, textBounds.y + 2, true);
+ }
+ }
+ });
+
// Create resources
createResources();
+ initializeFonts();
+ PlatformUI.getWorkbench().getThemeManager().addPropertyChangeListener(this);
+
ColorSettingsManager.addColorSettingsListener(this);
fTable.setItemCount(1); // +1 for header row
}
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));
+ broadcast(new TmfSelectionRangeUpdatedSignal(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);
}
}
public void run() {
fHeaderState = HeaderState.SEARCH;
fTable.refresh();
+ fTable.redraw();
}
};
public void run() {
fHeaderState = HeaderState.FILTER;
fTable.refresh();
+ fTable.redraw();
}
};
// 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) {
public void dispose() {
stopSearchThread();
stopFilterThread();
+ PlatformUI.getWorkbench().getThemeManager().removePropertyChangeListener(this);
ColorSettingsManager.removeColorSettingsListener(this);
fComposite.dispose();
if ((fTrace != null) && fDisposeOnClose) {
*/
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());
item.setForeground(colorSetting.getForegroundColor());
item.setBackground(colorSetting.getBackgroundColor());
}
+ item.setFont(fFont);
if (searchMatch) {
if (!markerIds.isEmpty()) {
item.setImage((Image) null);
}
+ List<StyleRange> styleRanges = new ArrayList<>();
+ for (int index = 0; index < fTable.getColumns().length; index++) {
+ TableColumn column = fTable.getColumns()[index];
+ String regex = null;
+ if (fHeaderState == HeaderState.FILTER) {
+ regex = (String) column.getData(Key.FILTER_TXT);
+ } else if (searchMatch) {
+ regex = (String) column.getData(Key.SEARCH_TXT);
+ }
+ if (regex != null) {
+ String text = item.getText(index);
+ try {
+ Pattern pattern = Pattern.compile(regex);
+ Matcher matcher = pattern.matcher(text);
+ while (matcher.find()) {
+ int start = matcher.start();
+ int length = matcher.end() - start;
+ Color foreground = colorSetting.getForegroundColor();
+ Color background = item.getDisplay().getSystemColor(SWT.COLOR_YELLOW);
+ StyleRange styleRange = new StyleRange(start, length, foreground, background);
+ styleRange.data = index;
+ styleRanges.add(styleRange);
+ }
+ } catch (PatternSyntaxException e) {
+ /* ignored */
+ }
+ }
+ }
+ if (styleRanges.isEmpty()) {
+ item.setData(Key.STYLE_RANGES, null);
+ } else {
+ item.setData(Key.STYLE_RANGES, styleRanges);
+ }
+ item.getParent().redraw();
+
if ((itemStrings[MARGIN_COLUMN_INDEX] != null) && !itemStrings[MARGIN_COLUMN_INDEX].isEmpty()) {
packMarginColumn();
}
item.setText(i, FILTER_HINT);
}
item.setForeground(i, fGrayColor);
- item.setFont(i, fTable.getFont());
+ item.setFont(i, fFont);
} else {
item.setText(i, filter);
item.setForeground(i, fGreenColor);
item.setData(null);
item.setData(Key.TIMESTAMP, null);
item.setData(Key.RANK, null);
+ item.setData(Key.STYLE_RANGES, null);
item.setForeground(null);
item.setBackground(null);
+ item.setFont(fFont);
}
/**
}
fTable.setSelection(0);
fTable.refresh();
+ fTable.redraw();
return;
}
/*
* returns true is value was changed
*/
- private boolean updateHeader(final String text) {
+ private boolean updateHeader(final String regex) {
String objKey = null;
String txtKey = null;
if (fHeaderState == HeaderState.SEARCH) {
objKey = Key.FILTER_OBJ;
txtKey = Key.FILTER_TXT;
}
- if (text.trim().length() > 0) {
+ if (regex.length() > 0) {
try {
- final String regex = TmfFilterMatchesNode.regexFix(text);
Pattern.compile(regex);
if (regex.equals(column.getData(txtKey))) {
tableEditor.getEditor().dispose();
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();
fSelectedRank = foundRank;
fRawViewer.selectAndReveal(fSelectedRank);
if (foundTimestamp != null) {
- broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, foundTimestamp));
+ broadcast(new TmfSelectionRangeUpdatedSignal(TmfEventsTable.this, foundTimestamp));
}
fireSelectionChanged(new SelectionChangedEvent(TmfEventsTable.this, getSelection()));
synchronized (fSearchSyncObj) {
fGrayColor = fResourceManager.createColor(ColorUtil.blend(fTable.getBackground().getRGB(), fTable
.getForeground().getRGB()));
fGreenColor = fTable.getDisplay().getSystemColor(SWT.COLOR_DARK_GREEN);
- fBoldFont = fResourceManager.createFont(FontDescriptor.createFrom(fTable.getFont()).setStyle(SWT.BOLD));
+ }
+
+ /**
+ * Initialize the fonts.
+ * @since 1.0
+ */
+ protected void initializeFonts() {
+ FontRegistry fontRegistry = PlatformUI.getWorkbench().getThemeManager().getCurrentTheme().getFontRegistry();
+ fFont = fontRegistry.get(FONT_DEFINITION_ID);
+ fBoldFont = fontRegistry.getBold(FONT_DEFINITION_ID);
+ fTable.setFont(fFont);
+ /* Column header font cannot be set. See Bug 63038 */
+ }
+
+ /**
+ * @since 1.0
+ */
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+ if ((IThemeManager.CHANGE_CURRENT_THEME.equals(event.getProperty())) ||
+ (FONT_DEFINITION_ID.equals(event.getProperty()))) {
+ initializeFonts();
+ fTable.refresh();
+ }
}
/**
* @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);
+ }
+
+ /**
+ * Returns an array of zero-relative integers that map
+ * the creation order of the receiver's columns to the
+ * order in which they are currently being displayed.
+ * <p>
+ * Specifically, the indices of the returned array represent
+ * the current visual order of the columns, and the contents
+ * of the array represent the creation order of the columns.
+ *
+ * @return the current visual order of the receiver's columns
+ * @since 1.0
+ */
+ public int[] getColumnOrder() {
+ return fColumnOrder;
+ }
+
+ /**
+ * Sets the order that the columns in the receiver should
+ * be displayed in to the given argument which is described
+ * in terms of the zero-relative ordering of when the columns
+ * were added.
+ * <p>
+ * Specifically, the contents of the array represent the
+ * original position of each column at the time its creation.
+ *
+ * @param order the new order to display the columns
+ * @since 1.0
+ */
+ public void setColumnOrder(int[] order) {
+ if (order == null || order.length != fTable.getColumns().length) {
+ return;
+ }
+ fTable.setColumnOrder(order);
+ fColumnOrder = fTable.getColumnOrder();
}
/**
*
* @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();
}
/**
- * Handler for the time synch signal.
+ * Handler for the selection range signal.
*
* @param signal
* The incoming signal
+ * @since 1.0
*/
@TmfSignalHandler
- public void currentTimeUpdated(final TmfTimeSynchSignal signal) {
+ public void selectionRangeUpdated(final TmfSelectionRangeUpdatedSignal signal) {
if ((signal.getSource() != this) && (fTrace != null) && (!fTable.isDisposed())) {
// Create a request for one event that will be queued after other ongoing requests. When this request is completed
}
@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);
+ }
+ }
}