/*******************************************************************************
- * Copyright (c) 2010, 2011, 2012 Ericsson
+ * Copyright (c) 2010, 2014 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Francois Chouinard - Initial API and implementation
- * Patrick Tasse - Factored out from events view
- * Francois Chouinard - Replaced Table by TmfVirtualTable
- * Patrick Tasse - Filter implementation (inspired by www.eclipse.org/mat)
+ * Francois Chouinard - Initial API and implementation, replaced Table by TmfVirtualTable
+ * Patrick Tasse - Factored out from events view,
+ * Filter implementation (inspired by www.eclipse.org/mat)
+ * Ansgar Radermacher - Support navigation to model URIs (Bug 396956)
+ * Bernd Hufmann - Updated call site and model URI implementation
+ * Alexandre Montplaisir - Update to new column API
*******************************************************************************/
package org.eclipse.linuxtools.tmf.ui.viewers.events;
+import java.io.FileNotFoundException;
import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collection;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.NotEnabledException;
+import org.eclipse.core.commands.NotHandledException;
+import org.eclipse.core.commands.ParameterizedCommand;
+import org.eclipse.core.commands.common.NotDefinedException;
+import org.eclipse.core.expressions.IEvaluationContext;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EValidator;
+import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.resource.FontDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
+import org.eclipse.jface.util.OpenStrategy;
import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.window.Window;
+import org.eclipse.linuxtools.internal.tmf.core.filter.TmfCollapseFilter;
import org.eclipse.linuxtools.internal.tmf.ui.Activator;
import org.eclipse.linuxtools.internal.tmf.ui.Messages;
+import org.eclipse.linuxtools.internal.tmf.ui.commands.ExportToTextCommandHandler;
import org.eclipse.linuxtools.internal.tmf.ui.dialogs.MultiLineInputDialog;
-import org.eclipse.linuxtools.tmf.core.component.ITmfDataProvider;
+import org.eclipse.linuxtools.tmf.core.component.ITmfEventProvider;
import org.eclipse.linuxtools.tmf.core.component.TmfComponent;
import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
-import org.eclipse.linuxtools.tmf.core.event.ITmfEventField;
-import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
-import org.eclipse.linuxtools.tmf.core.event.TmfEventField;
-import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
+import org.eclipse.linuxtools.tmf.core.event.collapse.ITmfCollapsibleEvent;
+import org.eclipse.linuxtools.tmf.core.event.lookup.ITmfCallsite;
+import org.eclipse.linuxtools.tmf.core.event.lookup.ITmfModelLookup;
+import org.eclipse.linuxtools.tmf.core.event.lookup.ITmfSourceLookup;
import org.eclipse.linuxtools.tmf.core.filter.ITmfFilter;
import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode;
import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterAndNode;
import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterMatchesNode;
import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterNode;
-import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest.ExecutionType;
-import org.eclipse.linuxtools.tmf.core.request.TmfDataRequest;
+import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest.ExecutionType;
+import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest;
import org.eclipse.linuxtools.tmf.core.signal.TmfEventFilterAppliedSignal;
import org.eclipse.linuxtools.tmf.core.signal.TmfEventSearchAppliedSignal;
+import org.eclipse.linuxtools.tmf.core.signal.TmfEventSelectedSignal;
import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;
import org.eclipse.linuxtools.tmf.core.signal.TmfTraceUpdatedSignal;
+import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
+import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
+import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
-import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation;
import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager;
+import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation;
import org.eclipse.linuxtools.tmf.ui.viewers.events.TmfEventsCache.CachedEvent;
+import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableColumn;
+import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableFieldColumn;
import org.eclipse.linuxtools.tmf.ui.views.colors.ColorSetting;
import org.eclipse.linuxtools.tmf.ui.views.colors.ColorSettingsManager;
import org.eclipse.linuxtools.tmf.ui.views.colors.IColorSettingsListener;
import org.eclipse.linuxtools.tmf.ui.views.filter.FilterManager;
import org.eclipse.linuxtools.tmf.ui.widgets.rawviewer.TmfRawEventViewer;
-import org.eclipse.linuxtools.tmf.ui.widgets.virtualtable.ColumnData;
import org.eclipse.linuxtools.tmf.ui.widgets.virtualtable.TmfVirtualTable;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.dialogs.ListDialog;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.ide.IGotoMarker;
import org.eclipse.ui.themes.ColorUtil;
+import com.google.common.base.Joiner;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Multimap;
+
/**
* The generic TMF Events table
*
* This is a view that will list events that are read from a trace.
*
- * @version 1.0
* @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 boolean IS_LINUX = System.getProperty("os.name").contains("Linux") ? true : false; //$NON-NLS-1$ //$NON-NLS-2$
+
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 String FILTER_HINT = Messages.TmfEventsTable_FilterHint;
private static final int MAX_CACHE_SIZE = 1000;
+ private static final int MARGIN_COLUMN_INDEX = 0;
+ 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
*
/** Filter object */
String FILTER_OBJ = "$fltr_obj"; //$NON-NLS-1$
- /** Timestamp*/
+ /** Timestamp */
String TIMESTAMP = "$time"; //$NON-NLS-1$
/** Rank */
private SashForm fSashForm;
private TmfRawEventViewer fRawViewer;
private ITmfTrace fTrace;
- private boolean fPackDone = false;
+ volatile private boolean fPackDone = false;
private HeaderState fHeaderState = HeaderState.SEARCH;
private long fSelectedRank = 0;
+ private ITmfTimestamp fSelectedBeginTimestamp = null;
+ private IStatusLineManager fStatusLineManager = null;
// Filter data
private long fFilterMatchCount;
private ListenerList selectionChangedListeners = new ListenerList();
// Bookmark map <Rank, MarkerId>
- private Map<Long, Long> fBookmarksMap = new HashMap<Long, Long>();
+ private Multimap<Long, Long> fBookmarksMap = HashMultimap.create();
private IFile fBookmarksFile;
private long fPendingGotoRank = -1;
private Color fGreenColor;
private Font fBoldFont;
- // Table column names
- private static final String[] COLUMN_NAMES = new String[] { Messages.TmfEventsTable_TimestampColumnHeader,
- Messages.TmfEventsTable_SourceColumnHeader, Messages.TmfEventsTable_TypeColumnHeader,
- Messages.TmfEventsTable_ReferenceColumnHeader, Messages.TmfEventsTable_ContentColumnHeader };
-
- private static final ColumnData[] COLUMN_DATA = new ColumnData[] { new ColumnData(COLUMN_NAMES[0], 100, SWT.LEFT),
- new ColumnData(COLUMN_NAMES[1], 100, SWT.LEFT), new ColumnData(COLUMN_NAMES[2], 100, SWT.LEFT),
- new ColumnData(COLUMN_NAMES[3], 100, SWT.LEFT), new ColumnData(COLUMN_NAMES[4], 100, SWT.LEFT) };
+ private final List<TmfEventTableColumn> fColumns = new LinkedList<>();
// Event cache
private final TmfEventsCache fCache;
// ------------------------------------------------------------------------
/**
- * Basic constructor, will use default column data.
+ * Basic constructor, using the default set of columns
*
* @param parent
* The parent composite UI object
* The size of the event table cache
*/
public TmfEventsTable(final Composite parent, final int cacheSize) {
- this(parent, cacheSize, COLUMN_DATA);
+ this(parent, cacheSize, DEFAULT_COLUMNS);
}
/**
- * Advanced constructor, where we also define which column data to use.
+ * Legacy constructor, using ColumnData to define columns
*
* @param parent
* The parent composite UI object
* @param cacheSize
* The size of the event table cache
* @param columnData
- * The column data to use for this table
+ * Unused
+ * @deprecated Deprecated constructor, use
+ * {@link #TmfEventsTable(Composite, int, Collection)}
+ */
+ @Deprecated
+ public TmfEventsTable(final Composite parent, int cacheSize,
+ final org.eclipse.linuxtools.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
+ * ColumnData they passed.
+ */
+ this(parent, cacheSize, convertFromColumnData(columnData));
+ }
+
+ @Deprecated
+ private static Collection<TmfEventTableColumn> convertFromColumnData(
+ org.eclipse.linuxtools.tmf.ui.widgets.virtualtable.ColumnData[] columnData) {
+
+ ImmutableList.Builder<TmfEventTableColumn> builder = new ImmutableList.Builder<>();
+ for (org.eclipse.linuxtools.tmf.ui.widgets.virtualtable.ColumnData col : columnData) {
+ String header = col.header;
+ if (header != null) {
+ builder.add(new TmfEventTableFieldColumn(header));
+ }
+ }
+ return builder.build();
+ }
+
+ /**
+ * Standard constructor, where we define which columns to use.
+ *
+ * @param parent
+ * The parent composite UI object
+ * @param cacheSize
+ * The size of the event table cache
+ * @param columns
+ * The columns to use in this table.
+ * <p>
+ * The iteration order of this collection will correspond to the
+ * initial ordering of this series of columns in the table.
+ * </p>
+ * @since 3.1
*/
- public TmfEventsTable(final Composite parent, int cacheSize, final ColumnData[] columnData) {
+ public TmfEventsTable(final Composite parent, int cacheSize,
+ Collection<? extends TmfEventTableColumn> columns) {
super("TmfEventsTable"); //$NON-NLS-1$
fComposite = new Composite(parent, SWT.NONE);
fSashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
// Create a virtual table
- final int style = SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION;
+ final int style = SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION;
fTable = new TmfVirtualTable(fSashForm, style);
// Set the table layout
fTable.setHeaderVisible(true);
fTable.setLinesVisible(true);
- // Set the columns
- setColumnHeaders(columnData);
+ // Setup the columns
+ if (columns != null) {
+ fColumns.addAll(columns);
+ }
+
+ TmfMarginColumn collapseCol = new TmfMarginColumn();
+ fColumns.add(MARGIN_COLUMN_INDEX, collapseCol);
- // Set the default column field ids if this is not a subclass
- if (Arrays.equals(columnData, COLUMN_DATA)) {
- fTable.getColumns()[0].setData(Key.FIELD_ID, ITmfEvent.EVENT_FIELD_TIMESTAMP);
- fTable.getColumns()[1].setData(Key.FIELD_ID, ITmfEvent.EVENT_FIELD_SOURCE);
- fTable.getColumns()[2].setData(Key.FIELD_ID, ITmfEvent.EVENT_FIELD_TYPE);
- fTable.getColumns()[3].setData(Key.FIELD_ID, ITmfEvent.EVENT_FIELD_REFERENCE);
- fTable.getColumns()[4].setData(Key.FIELD_ID, ITmfEvent.EVENT_FIELD_CONTENT);
+ // Create the UI columns in the table
+ for (TmfEventTableColumn col : fColumns) {
+ TableColumn column = fTable.newTableColumn(SWT.LEFT);
+ column.setText(col.getHeaderName());
+ column.setToolTipText(col.getHeaderTooltip());
+ column.setData(Key.FIELD_ID, col.getFilterFieldId());
+ column.pack();
+ if (col instanceof TmfMarginColumn) {
+ column.setResizable(false);
+ }
}
// Set the frozen row for header row
fTable.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(final SelectionEvent e) {
- final TableItem[] selection = fTable.getSelection();
- if (selection.length > 0) {
- final TableItem selectedTableItem = selection[0];
- if (selectedTableItem != null) {
- if (selectedTableItem.getData(Key.RANK) instanceof Long) {
- fSelectedRank = (Long) selectedTableItem.getData(Key.RANK);
- fRawViewer.selectAndReveal((Long) selectedTableItem.getData(Key.RANK));
+ if (e.item == null) {
+ return;
+ }
+ updateStatusLine(null);
+ if (fTable.getSelectionIndices().length > 0) {
+ if (e.item.getData(Key.RANK) instanceof Long) {
+ fSelectedRank = (Long) e.item.getData(Key.RANK);
+ 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);
+ if (fTable.getSelectionIndices().length == 1) {
+ fSelectedBeginTimestamp = ts;
+ }
+ if (fSelectedBeginTimestamp != null) {
+ if (fSelectedBeginTimestamp.compareTo(ts) <= 0) {
+ broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, fSelectedBeginTimestamp, ts));
+ if (fTable.getSelectionIndices().length == 2) {
+ updateStatusLine(ts.getDelta(fSelectedBeginTimestamp));
+ }
+ } else {
+ broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, ts, fSelectedBeginTimestamp));
+ updateStatusLine(fSelectedBeginTimestamp.getDelta(ts));
+ }
}
- if (selectedTableItem.getData(Key.TIMESTAMP) instanceof TmfTimestamp) {
- final TmfTimestamp ts = (TmfTimestamp) selectedTableItem.getData(Key.TIMESTAMP);
- broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, ts));
+ } else {
+ if (fTable.getSelectionIndices().length == 1) {
+ fSelectedBeginTimestamp = null;
}
}
}
- fireSelectionChanged(new SelectionChangedEvent(TmfEventsTable.this, getSelection()));
+ if (e.item.getData() instanceof ITmfEvent) {
+ broadcast(new TmfEventSelectedSignal(TmfEventsTable.this, (ITmfEvent) e.item.getData()));
+ fireSelectionChanged(new SelectionChangedEvent(TmfEventsTable.this, new StructuredSelection(e.item.getData())));
+ } else {
+ fireSelectionChanged(new SelectionChangedEvent(TmfEventsTable.this, StructuredSelection.EMPTY));
+ }
}
});
final CachedEvent cachedEvent = fCache.getEvent(index);
if (cachedEvent != null) {
- setItemData(item, cachedEvent.event, cachedEvent.rank);
+ setItemData(item, cachedEvent, cachedEvent.rank);
return;
}
layout.marginWidth = 2;
tooltipShell.setLayout(layout);
final Label label = new Label(tooltipShell, SWT.WRAP);
- String text = rank.toString() + (tooltipText != null ? ": " + tooltipText : ""); //$NON-NLS-1$ //$NON-NLS-2$
+ String text = rank.toString() + (tooltipText != null ? ": " + tooltipText : EMPTY_STRING); //$NON-NLS-1$
label.setForeground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
label.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
label.setText(text);
* the method toDisplay() expects coordinates relative to an origin that includes the table header.
*/
int y = event.y;
- if (System.getProperty("os.name").contains("Linux")) { //$NON-NLS-1$ //$NON-NLS-2$
+ if (IS_LINUX) {
y += fTable.getHeaderHeight();
}
Point pt = fTable.toDisplay(event.x, y);
}
fTable.setSelection(index + 1); // +1 for header row
fSelectedRank = rank;
+ updateStatusLine(null);
} else if (e.data instanceof ITmfLocation) {
// DOES NOT WORK: rank undefined in context from seekLocation()
// ITmfLocation<?> location = (ITmfLocation<?>) e.data;
createPopupMenu();
}
+ // ------------------------------------------------------------------------
+ // Operations
+ // ------------------------------------------------------------------------
+
/**
* Create a pop-up menu.
*/
fRawViewer.setVisible(true);
fSashForm.layout();
final int index = fTable.getSelectionIndex();
- if (index >= +1) {
+ if (index >= 1) {
fRawViewer.selectAndReveal(index - 1);
}
}
}
};
+ final IAction openCallsiteAction = new Action(Messages.TmfEventsTable_OpenSourceCodeActionText) {
+ @Override
+ public void run() {
+ final TableItem items[] = fTable.getSelection();
+ if (items.length != 1) {
+ return;
+ }
+ final TableItem item = items[0];
+
+ final Object data = item.getData();
+ if (data instanceof ITmfSourceLookup) {
+ ITmfSourceLookup event = (ITmfSourceLookup) data;
+ ITmfCallsite cs = event.getCallsite();
+ if (cs == null || cs.getFileName() == null) {
+ return;
+ }
+ IMarker marker = null;
+ try {
+ String fileName = cs.getFileName();
+ final String trimmedPath = fileName.replaceAll("\\.\\./", EMPTY_STRING); //$NON-NLS-1$
+ final ArrayList<IFile> files = new ArrayList<>();
+ ResourcesPlugin.getWorkspace().getRoot().accept(new IResourceVisitor() {
+ @Override
+ public boolean visit(IResource resource) throws CoreException {
+ if (resource instanceof IFile && resource.getFullPath().toString().endsWith(trimmedPath)) {
+ files.add((IFile) resource);
+ }
+ return true;
+ }
+ });
+ IFile file = null;
+ if (files.size() > 1) {
+ ListDialog dialog = new ListDialog(getTable().getShell());
+ dialog.setContentProvider(ArrayContentProvider.getInstance());
+ dialog.setLabelProvider(new LabelProvider() {
+ @Override
+ public String getText(Object element) {
+ return ((IFile) element).getFullPath().toString();
+ }
+ });
+ dialog.setInput(files);
+ dialog.setTitle(Messages.TmfEventsTable_OpenSourceCodeSelectFileDialogTitle);
+ dialog.setMessage(Messages.TmfEventsTable_OpenSourceCodeSelectFileDialogTitle + '\n' + cs.toString());
+ dialog.open();
+ Object[] result = dialog.getResult();
+ if (result != null && result.length > 0) {
+ file = (IFile) result[0];
+ }
+ } else if (files.size() == 1) {
+ file = files.get(0);
+ }
+ if (file != null) {
+ marker = file.createMarker(IMarker.MARKER);
+ marker.setAttribute(IMarker.LINE_NUMBER, Long.valueOf(cs.getLineNumber()).intValue());
+ IDE.openEditor(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(), marker);
+ marker.delete();
+ } else if (files.size() == 0){
+ displayException(new FileNotFoundException('\'' + cs.toString() + '\'' + '\n' + Messages.TmfEventsTable_OpenSourceCodeNotFound));
+ }
+ } catch (CoreException e) {
+ displayException(e);
+ }
+ }
+ }
+ };
+
+ final IAction openModelAction = new Action(Messages.TmfEventsTable_OpenModelActionText) {
+ @Override
+ public void run() {
+
+ final TableItem items[] = fTable.getSelection();
+ if (items.length != 1) {
+ return;
+ }
+ final TableItem item = items[0];
+
+ final Object eventData = item.getData();
+ if (eventData instanceof ITmfModelLookup) {
+ String modelURI = ((ITmfModelLookup) eventData).getModelUri();
+
+ if (modelURI != null) {
+ IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+
+ IFile file = null;
+ final URI uri = URI.createURI(modelURI);
+ if (uri.isPlatformResource()) {
+ IPath path = new Path(uri.toPlatformString(true));
+ file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
+ } else if (uri.isFile() && !uri.isRelative()) {
+ file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(
+ new Path(uri.toFileString()));
+ }
+
+ if (file != null) {
+ try {
+ /*
+ * create a temporary validation marker on the
+ * model file, remove it afterwards thus,
+ * navigation works with all model editors
+ * supporting the navigation to a marker
+ */
+ IMarker marker = file.createMarker(EValidator.MARKER);
+ marker.setAttribute(EValidator.URI_ATTRIBUTE, modelURI);
+ marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO);
+
+ IDE.openEditor(activePage, marker, OpenStrategy.activateOnOpen());
+ marker.delete();
+ }
+ catch (CoreException e) {
+ displayException(e);
+ }
+ } else {
+ displayException(new FileNotFoundException('\'' + modelURI + '\'' + '\n' + Messages.TmfEventsTable_OpenModelUnsupportedURI));
+ }
+ }
+ }
+ }
+ };
+
+ final IAction exportToTextAction = new Action(Messages.TmfEventsTable_Export_to_text) {
+ @Override
+ public void run() {
+ IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ IHandlerService handlerService = (IHandlerService) activePage.getActiveEditor().getSite().getService(IHandlerService.class);
+ ICommandService cmdService = (ICommandService) activePage.getActiveEditor().getSite().getService(ICommandService.class);
+ try {
+ HashMap<String, Object> parameters = new HashMap<>();
+ Command command = cmdService.getCommand(ExportToTextCommandHandler.COMMAND_ID);
+ 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());
+ 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) {
+ displayException(e);
+ }
+ }
+ };
+
final IAction showSearchBarAction = new Action(Messages.TmfEventsTable_ShowSearchBarActionText) {
@Override
public void run() {
}
};
+ final IAction collapseAction = new Action(Messages.TmfEventsTable_CollapseFilterMenuName) {
+ @Override
+ public void run() {
+ applyFilter(new TmfCollapseFilter());
+ }
+ };
+
class ToggleBookmarkAction extends Action {
- long fRank;
+ Long fRank;
- public ToggleBookmarkAction(final String text, final long rank) {
+ public ToggleBookmarkAction(final String text, final Long rank) {
super(text);
fRank = rank;
}
return;
}
}
+
// Right-click on table
if (fTable.isVisible() && fRawViewer.isVisible()) {
tablePopupMenu.add(hideTableAction);
} else if (!fRawViewer.isVisible()) {
tablePopupMenu.add(showRawAction);
}
+ tablePopupMenu.add(exportToTextAction);
tablePopupMenu.add(new Separator());
+
+ if (item != null) {
+ final Object data = item.getData();
+ Separator separator = null;
+ if (data instanceof ITmfSourceLookup) {
+ ITmfSourceLookup event = (ITmfSourceLookup) data;
+ if (event.getCallsite() != null) {
+ tablePopupMenu.add(openCallsiteAction);
+ separator = new Separator();
+ }
+ }
+
+ if (data instanceof ITmfModelLookup) {
+ ITmfModelLookup event = (ITmfModelLookup) data;
+ if (event.getModelUri() != null) {
+ tablePopupMenu.add(openModelAction);
+ separator = new Separator();
+ }
+
+ if (separator != null) {
+ tablePopupMenu.add(separator);
+ }
+ }
+ }
+
+ // 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) {
+ Class <? extends ITmfEvent> eventClass = trace.getEventType();
+ isCollapsible = ITmfCollapsibleEvent.class.isAssignableFrom(eventClass);
+ if (isCollapsible) {
+ break;
+ }
+ }
+ }
+
+ if (isCollapsible && !(fTable.getData(Key.FILTER_OBJ) instanceof TmfCollapseFilter)) {
+ tablePopupMenu.add(collapseAction);
+ tablePopupMenu.add(new Separator());
+ }
+
tablePopupMenu.add(clearFiltersAction);
final ITmfFilterTreeNode[] savedFilters = FilterManager.getSavedFilters();
if (savedFilters.length > 0) {
fTrace.dispose();
}
fResourceManager.dispose();
+ fRawViewer.dispose();
super.dispose();
}
/**
* @param columnData
- *
- * FIXME: Add support for column selection
+ * columnData
+ * @deprecated The column headers are now set at the constructor, this
+ * shouldn't be called anymore.
*/
- protected void setColumnHeaders(final ColumnData[] columnData) {
- fTable.setColumnHeaders(columnData);
+ @Deprecated
+ protected void setColumnHeaders(final org.eclipse.linuxtools.tmf.ui.widgets.virtualtable.ColumnData [] columnData) {
+ /* No-op */
}
/**
* Which rank this event has in the trace/experiment
*/
protected void setItemData(final TableItem item, final ITmfEvent event, final long rank) {
- final ITmfEventField[] fields = extractItemFields(event);
- final String[] content = new String[fields.length];
- for (int i = 0; i < fields.length; i++) {
- content[i] = fields[i].getValue() != null ? fields[i].getValue().toString() : ""; //$NON-NLS-1$
- }
- item.setText(content);
+ String[] itemStrings = getItemStrings(fColumns, event);
+ item.setText(itemStrings);
item.setData(event);
item.setData(Key.TIMESTAMP, new TmfTimestamp(event.getTimestamp()));
item.setData(Key.RANK, rank);
- boolean bookmark = false;
- final Long markerId = fBookmarksMap.get(rank);
- if (markerId != null) {
- bookmark = true;
+ final Collection<Long> markerIds = fBookmarksMap.get(rank);
+ if (!markerIds.isEmpty()) {
+ Joiner joiner = Joiner.on("\n -").skipNulls(); //$NON-NLS-1$
+ List<Object> parts = new ArrayList<>();
+ if (markerIds.size() > 1) {
+ parts.add(Messages.TmfEventsTable_MultipleBookmarksToolTip);
+ }
try {
- final IMarker marker = fBookmarksFile.findMarker(markerId);
- item.setData(Key.BOOKMARK, marker.getAttribute(IMarker.MESSAGE));
- } catch (final CoreException e) {
+ for (long markerId : markerIds) {
+ final IMarker marker = fBookmarksFile.findMarker(markerId);
+ parts.add(marker.getAttribute(IMarker.MESSAGE));
+ }
+ } catch (CoreException e) {
displayException(e);
}
+ item.setData(Key.BOOKMARK, joiner.join(parts));
} else {
item.setData(Key.BOOKMARK, null);
}
}
if (searchMatch) {
- if (bookmark) {
+ if (!markerIds.isEmpty()) {
item.setImage(SEARCH_MATCH_BOOKMARK_IMAGE);
} else {
item.setImage(SEARCH_MATCH_IMAGE);
}
- } else if (bookmark) {
+ } else if (!markerIds.isEmpty()) {
item.setImage(BOOKMARK_IMAGE);
} else {
item.setImage((Image) null);
}
+
+ if ((itemStrings[MARGIN_COLUMN_INDEX] != null) && !itemStrings[MARGIN_COLUMN_INDEX].isEmpty()) {
+ packMarginColumn();
+ }
}
/**
txtKey = Key.FILTER_TXT;
}
item.setForeground(fGrayColor);
- for (int i = 0; i < fTable.getColumns().length; i++) {
+ // Ignore collapse and image column
+ for (int i = EVENT_COLUMNS_START_INDEX; i < fTable.getColumns().length; i++) {
final TableColumn column = fTable.getColumns()[i];
final String filter = (String) column.getData(txtKey);
if (filter == null) {
*/
protected void setFilterStatusRowItemData(final TableItem item) {
for (int i = 0; i < fTable.getColumns().length; i++) {
- if (i == 0) {
+ if (i == MARGIN_COLUMN_INDEX) {
if ((fTrace == null) || (fFilterCheckCount == fTrace.getNbEvents())) {
item.setImage(FILTER_IMAGE);
} else {
item.setImage(STOP_IMAGE);
}
- item.setText(0, fFilterMatchCount + "/" + fFilterCheckCount); //$NON-NLS-1$
+ }
+
+ if (i == FILTER_SUMMARY_INDEX) {
+ item.setText(FILTER_SUMMARY_INDEX, fFilterMatchCount + "/" + fFilterCheckCount); //$NON-NLS-1$
} else {
- item.setText(i, ""); //$NON-NLS-1$
+ item.setText(i, EMPTY_STRING);
}
}
item.setData(null);
} else if (fHeaderState == HeaderState.FILTER) {
fHeaderState = HeaderState.SEARCH;
}
+ fTable.setSelection(0);
fTable.refresh();
return;
}
if (e.character == SWT.CR) {
updateHeader(newEditor.getText());
applyHeader();
+
+ // Set focus on the table so that the next carriage return goes to the next result
+ TmfEventsTable.this.getTable().setFocus();
} else if (e.character == SWT.ESC) {
tableEditor.getEditor().dispose();
}
fTable.setSelection(0);
}
fireFilterApplied(null);
+ updateStatusLine(null);
+
+ // Set original width
+ fTable.getColumns()[MARGIN_COLUMN_INDEX].setWidth(0);
+ packMarginColumn();
}
/**
*/
protected class FilterThread extends Thread {
private final ITmfFilterTreeNode filter;
- private TmfDataRequest request;
+ private TmfEventRequest request;
private boolean refreshBusy = false;
private boolean refreshPending = false;
private final Object syncObj = new Object();
if (nbRequested <= 0) {
return;
}
- request = new TmfDataRequest(ITmfEvent.class, (int) fFilterCheckCount,
- nbRequested, fTrace.getCacheSize(), ExecutionType.BACKGROUND) {
+ request = new TmfEventRequest(ITmfEvent.class, TmfTimeRange.ETERNITY,
+ (int) fFilterCheckCount, nbRequested, ExecutionType.BACKGROUND) {
@Override
public void handleData(final ITmfEvent event) {
super.handleData(event);
if (request.isCancelled()) {
return;
}
+ boolean refresh = false;
if (filter.matches(event)) {
final long rank = fFilterCheckCount;
final int index = (int) fFilterMatchCount;
fFilterMatchCount++;
- fCache.storeEvent(event.clone(), rank, index);
- refreshTable();
- } else if ((fFilterCheckCount % 100) == 0) {
+ fCache.storeEvent(event, rank, index);
+ refresh = true;
+ } else {
+ if (filter instanceof TmfCollapseFilter) {
+ fCache.updateCollapsedEvent((int) fFilterMatchCount - 1);
+ }
+ }
+
+ if (refresh || (fFilterCheckCount % 100) == 0) {
refreshTable();
}
fFilterCheckCount++;
}
};
- ((ITmfDataProvider) fTrace).sendRequest(request);
+ ((ITmfEventProvider) fTrace).sendRequest(request);
try {
request.waitForCompletion();
} catch (final InterruptedException e) {
startIndex = Math.max(0, fTable.getTopIndex() - 1); // -1 for header row
}
final ITmfFilterTreeNode eventFilter = (ITmfFilterTreeNode) fTable.getData(Key.FILTER_OBJ);
- if (eventFilter != null)
- {
+ if (eventFilter != null) {
startIndex = Math.max(0, startIndex - 1); // -1 for top filter status row
}
fSearchThread = new SearchThread(searchFilter, eventFilter, startIndex, fSelectedRank, Direction.FORWARD);
startIndex = fTable.getTopIndex() - 2; // -1 for header row, -1 for previous event
}
final ITmfFilterTreeNode eventFilter = (ITmfFilterTreeNode) fTable.getData(Key.FILTER_OBJ);
- if (eventFilter != null)
- {
+ if (eventFilter != null) {
startIndex = startIndex - 1; // -1 for top filter status row
}
fSearchThread = new SearchThread(searchFilter, eventFilter, startIndex, fSelectedRank, Direction.BACKWARD);
private int direction;
private long rank;
private long foundRank = -1;
- private TmfDataRequest request;
+ private TmfEventRequest request;
private ITmfTimestamp foundTimestamp = null;
/**
if (direction == Direction.BACKWARD) {
rank = Math.max(0, rank - fTrace.getCacheSize() + 1);
}
- request = new TmfDataRequest(ITmfEvent.class, (int) rank, nbRequested, fTrace.getCacheSize(), ExecutionType.BACKGROUND) {
+ request = new TmfEventRequest(ITmfEvent.class, TmfTimeRange.ETERNITY,
+ (int) rank, nbRequested, ExecutionType.BACKGROUND) {
long currentRank = rank;
@Override
currentRank++;
}
};
- ((ITmfDataProvider) fTrace).sendRequest(request);
+ ((ITmfEventProvider) fTrace).sendRequest(request);
try {
request.waitForCompletion();
if (request.isCancelled()) {
if (foundTimestamp != null) {
broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, foundTimestamp));
}
+ fireSelectionChanged(new SelectionChangedEvent(TmfEventsTable.this, getSelection()));
synchronized (fSearchSyncObj) {
fSearchThread = null;
}
+ updateStatusLine(null);
}
});
return Status.OK_STATUS;
if (fPackDone) {
return;
}
- boolean isLinux = System.getProperty("os.name").contains("Linux") ? true : false; //$NON-NLS-1$ //$NON-NLS-2$
-
- TableColumn tableColumns[] = fTable.getColumns();
- for (int i = 0; i < tableColumns.length; i++) {
- final TableColumn column = tableColumns[i];
- final int headerWidth = column.getWidth();
- column.pack();
- // Workaround for Linux which doesn't consider the image width of
- // search/filter row in TableColumn.pack() after having executed
- // TableItem.setImage((Image)null) for other rows than search/filter row.
- if (isLinux && (i == 0)) {
- column.setWidth(column.getWidth() + SEARCH_IMAGE.getBounds().width);
+ fTable.setRedraw(false);
+ try {
+ TableColumn tableColumns[] = fTable.getColumns();
+ for (int i = 0; i < tableColumns.length; i++) {
+ final TableColumn column = tableColumns[i];
+ packSingleColumn(i, column);
}
+ } finally {
+ // Make sure that redraw is always enabled.
+ fTable.setRedraw(true);
+ }
+ fPackDone = true;
+ }
+
+
+ private void packMarginColumn() {
+ TableColumn[] columns = fTable.getColumns();
+ if (columns.length > 0) {
+ packSingleColumn(0, columns[0]);
+ }
+ }
+
+ private void packSingleColumn(int i, final TableColumn column) {
+ final int headerWidth = column.getWidth();
+ column.pack();
+ // Workaround for Linux which doesn't consider the image width of
+ // search/filter row in TableColumn.pack() after having executed
+ // TableItem.setImage((Image)null) for other rows than search/filter row.
+ boolean isCollapseFilter = fTable.getData(Key.FILTER_OBJ) instanceof TmfCollapseFilter;
+ if (IS_LINUX && (i == 0) && isCollapseFilter) {
+ column.setWidth(column.getWidth() + SEARCH_IMAGE.getBounds().width);
+ }
+
+ if (column.getWidth() < headerWidth) {
+ column.setWidth(headerWidth);
+ }
+ }
+
+ /**
+ * Get the array of item strings (e.g., what to display in each cell of the
+ * table row) corresponding to the columns and trace event passed in
+ * parameter. The order of the Strings in the returned array will correspond
+ * to the iteration order of 'columns'.
+ *
+ * <p>
+ * To ensure consistent results, make sure only call this within a scope
+ * synchronized on 'columns'! If the order of 'columns' changes right after
+ * this method is called, the returned value won't be ordered correctly
+ * anymore.
+ */
+ private static String[] getItemStrings(List<TmfEventTableColumn> columns, ITmfEvent event) {
+ if (event == null) {
+ return EMPTY_STRING_ARRAY;
+ }
+ synchronized (columns) {
+ List<String> itemStrings = new ArrayList<>(columns.size());
+ for (TmfEventTableColumn column : columns) {
+ ITmfEvent passedEvent = event;
+ if (!(column instanceof TmfMarginColumn) && (event instanceof CachedEvent)) {
+ // Make sure that the event object from the trace is passed
+ // to all columns but the TmfMarginColumn
+ passedEvent = ((CachedEvent) event).event;
+ }
+ if (passedEvent == null) {
+ itemStrings.add(EMPTY_STRING);
+ } else {
+ itemStrings.add(column.getItemString(passedEvent));
+ }
- if (column.getWidth() < headerWidth) {
- column.setWidth(headerWidth);
}
+ return itemStrings.toArray(new String[0]);
}
- fPackDone = true;
}
/**
- * Extract the fields of an event (item in the table).
+ * Get the contents of the row in the events table corresponding to an
+ * event. The order of the elements corresponds to the current order of the
+ * columns.
*
* @param event
- * The event to extract from
- * @return The array of fields
- *
- * FIXME: Add support for column selection
+ * The event printed in this row
+ * @return The event row entries
+ * @since 3.0
*/
- protected ITmfEventField[] extractItemFields(final ITmfEvent event) {
- ITmfEventField[] fields = new TmfEventField[0];
- if (event != null) {
- final String timestamp = event.getTimestamp().toString();
- final String source = event.getSource();
- final String type = event.getType().getName();
- final String reference = event.getReference();
- final String content = event.getContent().toString();
- fields = new TmfEventField[] {
- new TmfEventField(ITmfEvent.EVENT_FIELD_TIMESTAMP, timestamp),
- new TmfEventField(ITmfEvent.EVENT_FIELD_SOURCE, source),
- new TmfEventField(ITmfEvent.EVENT_FIELD_TYPE, type),
- new TmfEventField(ITmfEvent.EVENT_FIELD_REFERENCE, reference),
- new TmfEventField(ITmfEvent.EVENT_FIELD_CONTENT, content)
- };
- }
- return fields;
+ public String[] getItemStrings(ITmfEvent event) {
+ return getItemStrings(fColumns, event);
}
/**
});
}
+ /**
+ * Assign the status line manager
+ *
+ * @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) {
+ fStatusLineManager.setMessage(EMPTY_STRING);
+ }
+ fStatusLineManager = statusLineManager;
+ }
+
+ private void updateStatusLine(ITmfTimestamp delta) {
+ if (fStatusLineManager != null) {
+ if (delta != null) {
+ fStatusLineManager.setMessage("\u0394: " + delta); //$NON-NLS-1$
+ } else {
+ fStatusLineManager.setMessage(null);
+ }
+ }
+ }
+
// ------------------------------------------------------------------------
// Event cache
// ------------------------------------------------------------------------
// ISelectionProvider
// ------------------------------------------------------------------------
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
- */
/**
* @since 2.0
*/
selectionChangedListeners.add(listener);
}
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection()
- */
/**
* @since 2.0
*/
if (fTable == null || fTable.isDisposed()) {
return StructuredSelection.EMPTY;
}
- List<Object> list = new ArrayList<Object>(fTable.getSelection().length);
+ List<Object> list = new ArrayList<>(fTable.getSelection().length);
for (TableItem item : fTable.getSelection()) {
if (item.getData() != null) {
list.add(item.getData());
return new StructuredSelection(list);
}
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
- */
/**
* @since 2.0
*/
selectionChangedListeners.remove(listener);
}
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection)
- */
/**
* @since 2.0
*/
if (tableItem.getData(Key.RANK) != null) {
final StringBuffer defaultMessage = new StringBuffer();
for (int i = 0; i < fTable.getColumns().length; i++) {
- if (i > 0)
- {
+ if (i > 0) {
defaultMessage.append(", "); //$NON-NLS-1$
}
defaultMessage.append(tableItem.getText(i));
final IMarker bookmark = bookmarksFile.createMarker(IMarker.BOOKMARK);
if (bookmark.exists()) {
bookmark.setAttribute(IMarker.MESSAGE, message.toString());
- final long rank = (Long) tableItem.getData(Key.RANK);
- final int location = (int) rank;
- bookmark.setAttribute(IMarker.LOCATION, (Integer) location);
+ final Long rank = (Long) tableItem.getData(Key.RANK);
+ final int location = rank.intValue();
+ bookmark.setAttribute(IMarker.LOCATION, Integer.valueOf(location));
fBookmarksMap.put(rank, bookmark.getId());
fTable.refresh();
}
* The bookmark to remove
*/
public void removeBookmark(final IMarker bookmark) {
- for (final Entry<Long, Long> entry : fBookmarksMap.entrySet()) {
+ for (final Entry<Long, Long> entry : fBookmarksMap.entries()) {
if (entry.getValue().equals(bookmark.getId())) {
- fBookmarksMap.remove(entry.getKey());
+ fBookmarksMap.remove(entry.getKey(), entry.getValue());
fTable.refresh();
return;
}
}
}
- private void toggleBookmark(final long rank) {
+ private void toggleBookmark(final Long rank) {
if (fBookmarksFile == null) {
return;
}
if (fBookmarksMap.containsKey(rank)) {
- final Long markerId = fBookmarksMap.remove(rank);
+ final Collection<Long> markerIds = fBookmarksMap.removeAll(rank);
fTable.refresh();
try {
- final IMarker bookmark = fBookmarksFile.findMarker(markerId);
- if (bookmark != null) {
- bookmark.delete();
+ for (long markerId : markerIds) {
+ final IMarker bookmark = fBookmarksFile.findMarker(markerId);
+ if (bookmark != null) {
+ bookmark.delete();
+ }
}
} catch (final CoreException e) {
displayException(e);
} else if (rank >= fTable.getItemCount()) {
fPendingGotoRank = rank;
}
+ fSelectedRank = rank;
fTable.setSelection(index + 1); // +1 for header row
+ updateStatusLine(null);
}
}
// Listeners
// ------------------------------------------------------------------------
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.linuxtools.tmf.ui.views.colors.IColorSettingsListener#colorSettingsChanged(org.eclipse.linuxtools.tmf.ui.views.colors.ColorSetting[])
- */
@Override
public void colorSettingsChanged(final ColorSetting[] colorSettings) {
fTable.refresh();
if ((fPendingGotoRank != -1) && ((fPendingGotoRank + 1) < fTable.getItemCount())) { // +1 for header row
fTable.setSelection((int) fPendingGotoRank + 1); // +1 for header row
fPendingGotoRank = -1;
+ updateStatusLine(null);
}
} else {
startFilterThread();
// Create a request for one event that will be queued after other ongoing requests. When this request is completed
// do the work to select the actual event with the timestamp specified in the signal. This procedure prevents
// the method fTrace.getRank() from interfering and delaying ongoing requests.
- final TmfDataRequest subRequest = new TmfDataRequest(ITmfEvent.class, 0, 1, ExecutionType.FOREGROUND) {
+ final TmfEventRequest subRequest = new TmfEventRequest(ITmfEvent.class,
+ TmfTimeRange.ETERNITY, 0, 1, ExecutionType.FOREGROUND) {
- TmfTimestamp ts = new TmfTimestamp(signal.getCurrentTime());
+ TmfTimestamp ts = new TmfTimestamp(signal.getBeginTime());
@Override
public void handleData(final ITmfEvent event) {
if (fTable.isDisposed()) {
return;
}
- if (fTable.getData(Key.FILTER_OBJ) != null)
- {
+ if (fTable.getData(Key.FILTER_OBJ) != null) {
index = fCache.getFilteredEventIndex(rank) + 1; // +1 for top filter status row
}
fTable.setSelection(index + 1); // +1 for header row
fRawViewer.selectAndReveal(rank);
+ updateStatusLine(null);
}
});
}
};
- ((ITmfDataProvider) fTrace).sendRequest(subRequest);
+ ((ITmfEventProvider) fTrace).sendRequest(subRequest);
}
}
*/
private static void displayException(final Exception e) {
final MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
- mb.setText(e.getClass().getName());
+ mb.setText(e.getClass().getSimpleName());
mb.setMessage(e.getMessage());
mb.open();
}
fTable.refresh();
fTable.redraw();
}
+
+ /**
+ * 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;
+ }
+ }
+
}