From 6ac5a950a13f5e6906e267b38a382f207937b08c Mon Sep 17 00:00:00 2001 From: Alexandre Montplaisir Date: Thu, 24 Jan 2013 17:09:07 -0500 Subject: [PATCH 1/1] Add entry filter support for TimegraphCombo via dialog MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change-Id: I56d714f5a7bcb1b849fda463821dccb525478745 Signed-off-by: François Rajotte Signed-off-by: Alexandre Montplaisir Reviewed-on: https://git.eclipse.org/r/6874 Tested-by: Hudson CI Reviewed-by: Matthew Khouzam Tested-by: Matthew Khouzam --- .../ui/views/controlflow/ControlFlowView.java | 12 ++ .../ui/widgets/timegraph/TimeGraphCombo.java | 203 ++++++++++++++++++ .../ui/widgets/timegraph/TimeGraphViewer.java | 18 +- .../timegraph/widgets/TimeGraphControl.java | 38 +++- 4 files changed, 266 insertions(+), 5 deletions(-) diff --git a/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java b/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java index d5a4ab9a4f..f9678a4494 100644 --- a/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java +++ b/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java @@ -100,6 +100,11 @@ public class ControlFlowView extends TmfView { TRACE_COLUMN }; + private final String[] FILTER_COLUMN_NAMES = new String[] { + PROCESS_COLUMN, + TID_COLUMN + }; + /** * Redraw state enum */ @@ -368,6 +373,12 @@ public class ControlFlowView extends TmfView { fTimeGraphCombo.setTreeColumns(COLUMN_NAMES); + fTimeGraphCombo.setFilterContentProvider(new TreeContentProvider()); + + fTimeGraphCombo.setFilterLabelProvider(new TreeLabelProvider()); + + fTimeGraphCombo.setFilterColumns(FILTER_COLUMN_NAMES); + fTimeGraphCombo.getTimeGraphViewer().addRangeListener(new ITimeGraphRangeListener() { @Override public void timeRangeUpdated(TimeGraphRangeUpdateEvent event) { @@ -874,6 +885,7 @@ public class ControlFlowView extends TmfView { } private void fillLocalToolBar(IToolBarManager manager) { + manager.add(fTimeGraphCombo.getShowFilterAction()); manager.add(fTimeGraphCombo.getTimeGraphViewer().getShowLegendAction()); manager.add(new Separator()); manager.add(fTimeGraphCombo.getTimeGraphViewer().getResetScaleAction()); diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphCombo.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphCombo.java index 023f47b345..39b81dc891 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphCombo.java +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphCombo.java @@ -15,7 +15,10 @@ package org.eclipse.linuxtools.tmf.ui.widgets.timegraph; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.eclipse.jface.action.Action; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; @@ -27,6 +30,11 @@ import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeExpansionEvent; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.linuxtools.internal.tmf.ui.Activator; +import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; +import org.eclipse.linuxtools.internal.tmf.ui.Messages; +import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.dialogs.TimeGraphFilterDialog; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; @@ -76,9 +84,18 @@ public class TimeGraphCombo extends Composite { // The time viewer private TimeGraphViewer fTimeGraphViewer; + // The top-level input (children excluded) + private List fTopInput; + + // All the inputs (children included) + private List fAllInput; + // The selection listener map private final HashMap fSelectionListenerMap = new HashMap(); + // The map of viewer filters + private final Map fViewerFilterMap = new HashMap(); + // Flag to block the tree selection changed listener when triggered by the time graph combo private boolean fInhibitTreeSelection = false; @@ -88,6 +105,15 @@ public class TimeGraphCombo extends Composite { // Calculated item height for Linux workaround private int fLinuxItemHeight = 0; + // The button that opens the filter dialog + private Action showFilterAction; + + // The filter dialog + private TimeGraphFilterDialog fFilterDialog; + + // The filter generated from the filter dialog + private RawViewerFilter fFilter; + // ------------------------------------------------------------------------ // Classes // ------------------------------------------------------------------------ @@ -240,6 +266,52 @@ public class TimeGraphCombo extends Composite { } } + /** + * The ViewerFilterWrapper is used to intercept the filler items from + * the time graph combo's real ViewerFilters. These filler items should + * always be visible. + */ + private class ViewerFilterWrapper extends ViewerFilter { + + ViewerFilter fWrappedFilter; + + ViewerFilterWrapper(ViewerFilter filter) { + super(); + this.fWrappedFilter = filter; + } + + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + if (element instanceof ITimeGraphEntry) { + return fWrappedFilter.select(viewer, parentElement, element); + } + return true; + } + + } + + /** + * This filter simply keeps a list of elements that should be shown + * All the other elements will be filtered + */ + private class RawViewerFilter extends ViewerFilter { + + private List fNonFiltered = new ArrayList(); + + public void setNonFiltered(List objects) { + fNonFiltered = objects; + } + + public List getNonFiltered() { + return fNonFiltered; + } + + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + return fNonFiltered.contains(element); + } + } + // ------------------------------------------------------------------------ // Constructors // ------------------------------------------------------------------------ @@ -268,6 +340,11 @@ public class TimeGraphCombo extends Composite { fTimeGraphViewer.setBorderWidth(tree.getBorderWidth()); fTimeGraphViewer.setNameWidthPref(0); + fFilter = new RawViewerFilter(); + addFilter(fFilter); + + fFilterDialog = new TimeGraphFilterDialog(getShell()); + // Feature in Windows. The tree vertical bar reappears when // the control is resized so we need to hide it again. // Bug in Linux. The tree header height is 0 in constructor, @@ -544,6 +621,60 @@ public class TimeGraphCombo extends Composite { return fTimeGraphViewer; } + /** + * Callback for the show filter action + * + * @since 2.0 + */ + public void showFilterDialog() { + if(fTopInput != null) { + fFilterDialog.setInput(fTopInput.toArray(new ITimeGraphEntry[0])); + fFilterDialog.setTitle(Messages.TmfTimeFilterDialog_WINDOW_TITLE); + fFilterDialog.setMessage(Messages.TmfTimeFilterDialog_MESSAGE); + fFilterDialog.setInitialElementSelections(fFilter.getNonFiltered()); + fFilterDialog.setExpandedElements(fAllInput.toArray()); + fFilterDialog.create(); + fFilterDialog.open(); + // Process selected elements + if (fFilterDialog.getResult() != null) { + fInhibitTreeSelection = true; + fFilter.setNonFiltered(new ArrayList(Arrays.asList(fFilterDialog.getResult()))); + fTreeViewer.refresh(); + fTreeViewer.expandAll(); + fTimeGraphViewer.refresh(); + fInhibitTreeSelection = false; + // Reset selection to first entry + if (fFilterDialog.getResult().length > 0) { + setSelection((ITimeGraphEntry) fFilterDialog.getResult()[0]); + } + } + } + } + + /** + * Get the show filter action. + * + * @return The Action object + * @since 2.0 + */ + public Action getShowFilterAction() { + if (showFilterAction == null) { + // showFilter + showFilterAction = new Action() { + @Override + public void run() { + showFilterDialog(); + } + }; + showFilterAction.setText(Messages.TmfTimeGraphCombo_FilterActionNameText); + showFilterAction.setToolTipText(Messages.TmfTimeGraphCombo_FilterActionToolTipText); + // TODO find a nice, distinctive icon + showFilterAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FILTERS)); + } + + return showFilterAction; + } + // ------------------------------------------------------------------------ // Control // ------------------------------------------------------------------------ @@ -579,6 +710,26 @@ public class TimeGraphCombo extends Composite { fTreeViewer.setLabelProvider(new TreeLabelProviderWrapper(labelProvider)); } + /** + * Sets the tree content provider used by the filter dialog + * + * @param contentProvider the tree content provider + * @since 2.0 + */ + public void setFilterContentProvider(ITreeContentProvider contentProvider) { + fFilterDialog.setContentProvider(contentProvider); + } + + /** + * Sets the tree label provider used by the filter dialog + * + * @param labelProvider the tree label provider + * @since 2.0 + */ + public void setFilterLabelProvider(ITableLabelProvider labelProvider) { + fFilterDialog.setLabelProvider(labelProvider); + } + /** * Sets the tree columns for this time graph combo. * @@ -593,6 +744,16 @@ public class TimeGraphCombo extends Composite { } } + /** + * Sets the tree columns for this time graph combo's filter dialog. + * + * @param columnNames the tree column names + * @since 2.0 + */ + public void setFilterColumns(String[] columnNames) { + fFilterDialog.setColumnNames(columnNames); + } + /** * Sets the time graph provider used by this time graph combo. * @@ -609,6 +770,9 @@ public class TimeGraphCombo extends Composite { * @param input the input of this time graph combo, or null if none */ public void setInput(ITimeGraphEntry[] input) { + fTopInput = new ArrayList(Arrays.asList(input)); + fAllInput = listAllInputs(fTopInput); + fFilter.setNonFiltered(new ArrayList(fAllInput)); fInhibitTreeSelection = true; fTreeViewer.setInput(input); for (SelectionListenerWrapper listenerWrapper : fSelectionListenerMap.values()) { @@ -622,6 +786,28 @@ public class TimeGraphCombo extends Composite { fTimeGraphViewer.setInput(input); } + /** + * @param filter The filter object to be attached to the view + * @since 2.0 + */ + public void addFilter(ViewerFilter filter) { + ViewerFilter wrapper = new ViewerFilterWrapper(filter); + fTreeViewer.addFilter(wrapper); + fTimeGraphViewer.addFilter(wrapper); + fViewerFilterMap.put(filter, wrapper); + } + + /** + * @param filter The filter object to be removed from the view + * @since 2.0 + */ + public void removeFilter(ViewerFilter filter) { + ViewerFilter wrapper = fViewerFilterMap.get(filter); + fTreeViewer.removeFilter(wrapper); + fTimeGraphViewer.removeFilter(wrapper); + fViewerFilterMap.remove(filter); + } + /** * Refreshes this time graph completely with information freshly obtained from its model. */ @@ -742,6 +928,23 @@ public class TimeGraphCombo extends Composite { return items; } + /** + * Explores the list of top-level inputs and returns all the inputs + * + * @param inputs The top-level inputs + * @return All the inputs + */ + private List listAllInputs(List inputs) { + ArrayList items = new ArrayList(); + for (ITimeGraphEntry entry : inputs) { + items.add(entry); + if (entry.hasChildren()) { + items.addAll(listAllInputs(entry.getChildren())); + } + } + return items; + } + private int getItemHeight(final Tree tree) { /* * Bug in Linux. The method getItemHeight doesn't always return the correct value. diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphViewer.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphViewer.java index 99ede5f8e5..2cac2943d3 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphViewer.java +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphViewer.java @@ -1,4 +1,3 @@ - /***************************************************************************** * Copyright (c) 2007, 2008 Intel Corporation, 2009, 2010, 2011, 2012 Ericsson. * All rights reserved. This program and the accompanying materials @@ -21,6 +20,7 @@ import java.util.ArrayList; import org.eclipse.jface.action.Action; import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.linuxtools.internal.tmf.ui.Activator; import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; import org.eclipse.linuxtools.internal.tmf.ui.Messages; @@ -1446,6 +1446,22 @@ public class TimeGraphViewer implements ITimeDataProvider, SelectionListener { _stateCtrl.removeTimeEventMenuListener(listener); } + /** + * @param filter The filter object to be attached to the view + * @since 2.0 + */ + public void addFilter(ViewerFilter filter) { + _stateCtrl.addFilter(filter); + refresh(); + } + /** + * @param filter The filter object to be attached to the view + * @since 2.0 + */ + public void removeFilter(ViewerFilter filter) { + _stateCtrl.removeFilter(filter); + refresh(); + } } diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java index 0c4985492f..a9e8483729 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java @@ -25,6 +25,7 @@ import org.eclipse.jface.resource.LocalResourceManager; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphTreeListener; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.StateItem; @@ -114,6 +115,7 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe private final List _timeEventMenuListeners = new ArrayList(); private final Cursor _dragCursor3; private final Cursor _WaitCursor; + private final List _filters = new ArrayList(); // Vertical formatting formatting for the state control view private final boolean _visibleVerticalScroll = true; @@ -1979,6 +1981,24 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe } + /** + * @param filter The filter object to be attached to the view + * @since 2.0 + */ + public void addFilter(ViewerFilter filter) { + if (!_filters.contains(filter)) { + _filters.add(filter); + } + } + + /** + * @param filter The filter object to be attached to the view + * @since 2.0 + */ + public void removeFilter(ViewerFilter filter) { + _filters.remove(filter); + } + private class ItemData { public Item[] _expandedItems = new Item[0]; public Item[] _items = new Item[0]; @@ -2058,10 +2078,20 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe } private void refreshExpanded(List expandedItemList, Item item) { - expandedItemList.add(item); - if (item._hasChildren && item._expanded) { - for (Item child : item.children) { - refreshExpanded(expandedItemList, child); + // Check for filters + boolean display = true; + for (ViewerFilter filter : _filters) { + if (!filter.select(null, item._trace.getParent(), item._trace)) { + display = false; + break; + } + } + if (display) { + expandedItemList.add(item); + if (item._hasChildren && item._expanded) { + for (Item child : item.children) { + refreshExpanded(expandedItemList, child); + } } } } -- 2.34.1