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.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.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.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.TmfTimestamp;
import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
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;
*/
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.1
+ * @since 3.2
*/
public static final Collection<TmfEventTableColumn> DEFAULT_COLUMNS = ImmutableList.of(
TmfEventTableColumn.BaseColumns.TIMESTAMP,
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;
fColumns.addAll(columns);
}
+ TmfMarginColumn collapseCol = new TmfMarginColumn();
+ fColumns.add(MARGIN_COLUMN_INDEX, collapseCol);
+
// Create the UI columns in the table
for (TmfEventTableColumn col : fColumns) {
TableColumn column = fTable.newTableColumn(SWT.LEFT);
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
}
}
}
- if (e.item.getData() != null) {
+ 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);
IMarker marker = null;
try {
String fileName = cs.getFileName();
- final String trimmedPath = fileName.replaceAll("\\.\\./", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ final String trimmedPath = fileName.replaceAll("\\.\\./", EMPTY_STRING); //$NON-NLS-1$
final ArrayList<IFile> files = new ArrayList<>();
ResourcesPlugin.getWorkspace().getRoot().accept(new IResourceVisitor() {
@Override
ICommandService cmdService = (ICommandService) activePage.getActiveEditor().getSite().getService(ICommandService.class);
try {
HashMap<String, Object> parameters = new HashMap<>();
- StringBuilder header = new StringBuilder();
- boolean needTab = false;
- for (TableColumn tc: fTable.getColumns()) {
- if (needTab) {
- header.append('\t');
- }
- header.append(tc.getText());
- needTab = true;
- }
Command command = cmdService.getCommand(ExportToTextCommandHandler.COMMAND_ID);
- ParameterizedCommand cmd = ParameterizedCommand.generateCommand(command,parameters);
+ ParameterizedCommand cmd = ParameterizedCommand.generateCommand(command, parameters);
+
IEvaluationContext context = handlerService.getCurrentState();
- context.addVariable(ExportToTextCommandHandler.TMF_EVENT_TABLE_HEADER_ID, header.toString());
- context.addVariable(ExportToTextCommandHandler.TMF_EVENT_TABLE_PARAMETER_ID, TmfEventsTable.this);
+ // 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);
}
};
+ final IAction collapseAction = new Action(Messages.TmfEventsTable_CollapseFilterMenuName) {
+ @Override
+ public void run() {
+ applyFilter(new TmfCollapseFilter());
+ }
+ };
+
class ToggleBookmarkAction extends Action {
Long fRank;
}
}
+ // 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) {
* Which rank this event has in the trace/experiment
*/
protected void setItemData(final TableItem item, final ITmfEvent event, final long rank) {
- item.setText(getItemStrings(fColumns, event));
+ String[] itemStrings = getItemStrings(fColumns, event);
+ item.setText(itemStrings);
item.setData(event);
item.setData(Key.TIMESTAMP, new TmfTimestamp(event.getTimestamp()));
item.setData(Key.RANK, rank);
} 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);
}
fireFilterApplied(null);
updateStatusLine(null);
+
+ // Set original width
+ fTable.getColumns()[MARGIN_COLUMN_INDEX].setWidth(0);
+ packMarginColumn();
}
/**
if (request.isCancelled()) {
return;
}
+ boolean refresh = false;
if (filter.matches(event)) {
final long rank = fFilterCheckCount;
final int index = (int) fFilterMatchCount;
fFilterMatchCount++;
fCache.storeEvent(event, rank, index);
- refreshTable();
- } else if ((fFilterCheckCount % 100) == 0) {
+ refresh = true;
+ } else {
+ if (filter instanceof TmfCollapseFilter) {
+ fCache.updateCollapsedEvent((int) fFilterMatchCount - 1);
+ }
+ }
+
+ if (refresh || (fFilterCheckCount % 100) == 0) {
refreshTable();
}
fFilterCheckCount++;
return;
}
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;
+ }
- 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);
- }
+ private void packMarginColumn() {
+ TableColumn[] columns = fTable.getColumns();
+ if (columns.length > 0) {
+ packSingleColumn(0, columns[0]);
+ }
+ }
- if (column.getWidth() < headerWidth) {
- column.setWidth(headerWidth);
- }
+ 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);
}
- fTable.setRedraw(true);
- fPackDone = true;
+ if (column.getWidth() < headerWidth) {
+ column.setWidth(headerWidth);
+ }
}
/**
synchronized (columns) {
List<String> itemStrings = new ArrayList<>(columns.size());
for (TmfEventTableColumn column : columns) {
- itemStrings.add(column.getItemString(event));
+ 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));
+ }
+
}
return itemStrings.toArray(new String[0]);
}
*/
public void setStatusLineManager(IStatusLineManager statusLineManager) {
if (fStatusLineManager != null && statusLineManager == null) {
- fStatusLineManager.setMessage(""); //$NON-NLS-1$
+ fStatusLineManager.setMessage(EMPTY_STRING);
}
fStatusLineManager = statusLineManager;
}
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;
+ }
+ }
+
}