X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=org.eclipse.linuxtools.tmf.ui%2Fsrc%2Forg%2Feclipse%2Flinuxtools%2Ftmf%2Fui%2Fwidgets%2Ftimegraph%2FTimeGraphCombo.java;h=2c695fc491370706b45da90e980b8a1ee4696c88;hb=4999a1961695db623f11e653207a24c639d67744;hp=023f47b3450c6bc282bfb0dcff4370f3d13ef058;hpb=36a65820e273f61aa4f5a1524f3ec37221a7409e;p=deliverable%2Ftracecompass.git 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..2c695fc491 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 Ericsson + * Copyright (c) 2012, 2013 Ericsson, others * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License v1.0 which @@ -8,6 +8,7 @@ * * Contributors: * Patrick Tasse - Initial API and implementation + * François Rajotte - Filter implementation *******************************************************************************/ package org.eclipse.linuxtools.tmf.ui.widgets.timegraph; @@ -15,7 +16,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 +31,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; @@ -70,24 +79,45 @@ public class TimeGraphCombo extends Composite { // Fields // ------------------------------------------------------------------------ - // The tree viewer + /** The tree viewer */ private TreeViewer fTreeViewer; - // The time viewer + /** The time viewer */ private TimeGraphViewer fTimeGraphViewer; - // The selection listener map - private final HashMap fSelectionListenerMap = new HashMap(); + /** The top-level input (children excluded) */ + private List fTopInput; - // Flag to block the tree selection changed listener when triggered by the time graph combo + /** The selection listener map */ + private final Map 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; - // Number of filler rows used by the tree content provider + /** Number of filler rows used by the tree content provider */ private int fNumFillerRows; - // Calculated item height for Linux workaround + /** 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; + + /** Default weight of each part of the sash */ + private static final int[] DEFAULT_WEIGHTS = { 1, 1 }; + // ------------------------------------------------------------------------ // Classes // ------------------------------------------------------------------------ @@ -117,7 +147,7 @@ public class TimeGraphCombo extends Composite { public Object[] getElements(Object inputElement) { Object[] elements = contentProvider.getElements(inputElement); // add filler elements to ensure alignment with time analysis viewer - Object[] oElements = Arrays.copyOf(elements, elements.length + fNumFillerRows, new Object[0].getClass()); + Object[] oElements = Arrays.copyOf(elements, elements.length + fNumFillerRows, Object[].class); for (int i = 0; i < fNumFillerRows; i++) { oElements[elements.length + i] = FILLER; } @@ -240,6 +270,56 @@ 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 { + + private 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 filtered out. + * All the other elements will be shown. + * By default and when the list is set to null, all elements are shown. + */ + private class RawViewerFilter extends ViewerFilter { + + private List fFiltered = null; + + public void setFiltered(List objects) { + fFiltered = objects; + } + + public List getFiltered() { + return fFiltered; + } + + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + if (fFiltered == null) { + return true; + } + return !fFiltered.contains(element); + } + } + // ------------------------------------------------------------------------ // Constructors // ------------------------------------------------------------------------ @@ -252,6 +332,23 @@ public class TimeGraphCombo extends Composite { * @param style the style of widget to construct */ public TimeGraphCombo(Composite parent, int style) { + this(parent, style, DEFAULT_WEIGHTS); + } + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of widget to construct + * @param weights + * The relative weights of each side of the sash form + * @since 2.1 + */ + public TimeGraphCombo(Composite parent, int style, int[] weights) { super(parent, style); setLayout(new FillLayout()); @@ -268,12 +365,17 @@ 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, // so we need to reset it later when the control is resized. tree.addControlListener(new ControlAdapter() { - int depth = 0; + private int depth = 0; @Override public void controlResized(ControlEvent e) { if (depth == 0) { @@ -292,7 +394,7 @@ public class TimeGraphCombo extends Composite { @Override public void treeCollapsed(TreeExpansionEvent event) { fTimeGraphViewer.setExpandedState((ITimeGraphEntry) event.getElement(), false); - ArrayList treeItems = getVisibleExpandedItems(tree); + List treeItems = getVisibleExpandedItems(tree); if (treeItems.size() == 0) { return; } @@ -302,8 +404,13 @@ public class TimeGraphCombo extends Composite { @Override public void treeExpanded(TreeExpansionEvent event) { - fTimeGraphViewer.setExpandedState((ITimeGraphEntry) event.getElement(), true); - ArrayList treeItems = getVisibleExpandedItems(tree); + ITimeGraphEntry entry = (ITimeGraphEntry) event.getElement(); + fTimeGraphViewer.setExpandedState(entry, true); + for (ITimeGraphEntry child : entry.getChildren()) { + boolean expanded = fTreeViewer.getExpandedState(child); + fTimeGraphViewer.setExpandedState(child, expanded); + } + List treeItems = getVisibleExpandedItems(tree); if (treeItems.size() == 0) { return; } @@ -327,7 +434,12 @@ public class TimeGraphCombo extends Composite { @Override public void treeExpanded(TimeGraphTreeExpansionEvent event) { - fTreeViewer.setExpandedState(event.getEntry(), true); + ITimeGraphEntry entry = event.getEntry(); + fTreeViewer.setExpandedState(entry, true); + for (ITimeGraphEntry child : entry.getChildren()) { + boolean expanded = fTreeViewer.getExpandedState(child); + fTimeGraphViewer.setExpandedState(child, expanded); + } } }); @@ -338,7 +450,7 @@ public class TimeGraphCombo extends Composite { TreeItem treeItem = tree.getItem(new Point(event.x, event.y)); if (treeItem == null || treeItem.getData() == FILLER) { event.doit = false; - ArrayList treeItems = getVisibleExpandedItems(tree); + List treeItems = getVisibleExpandedItems(tree); if (treeItems.size() == 0) { fTreeViewer.setSelection(new StructuredSelection()); fTimeGraphViewer.setSelection(null); @@ -360,7 +472,7 @@ public class TimeGraphCombo extends Composite { event.doit = false; Slider scrollBar = fTimeGraphViewer.getVerticalBar(); fTimeGraphViewer.setTopIndex(scrollBar.getSelection() - event.count); - ArrayList treeItems = getVisibleExpandedItems(tree); + List treeItems = getVisibleExpandedItems(tree); if (treeItems.size() == 0) { return; } @@ -373,7 +485,7 @@ public class TimeGraphCombo extends Composite { tree.addListener(SWT.KeyDown, new Listener() { @Override public void handleEvent(Event event) { - ArrayList treeItems = getVisibleExpandedItems(tree); + List treeItems = getVisibleExpandedItems(tree); if (treeItems.size() == 0) { fTreeViewer.setSelection(new StructuredSelection()); event.doit = false; @@ -407,7 +519,7 @@ public class TimeGraphCombo extends Composite { fTimeGraphViewer.getTimeGraphControl().addControlListener(new ControlAdapter() { @Override public void controlResized(ControlEvent e) { - ArrayList treeItems = getVisibleExpandedItems(tree); + List treeItems = getVisibleExpandedItems(tree); if (treeItems.size() == 0) { return; } @@ -428,7 +540,7 @@ public class TimeGraphCombo extends Composite { if (selection instanceof ITimeGraphEntry) { fTimeGraphViewer.setSelection((ITimeGraphEntry) selection); } - ArrayList treeItems = getVisibleExpandedItems(tree); + List treeItems = getVisibleExpandedItems(tree); if (treeItems.size() == 0) { return; } @@ -451,7 +563,7 @@ public class TimeGraphCombo extends Composite { fTreeViewer.setSelection(new StructuredSelection()); } fInhibitTreeSelection = false; - ArrayList treeItems = getVisibleExpandedItems(tree); + List treeItems = getVisibleExpandedItems(tree); if (treeItems.size() == 0) { return; } @@ -464,7 +576,7 @@ public class TimeGraphCombo extends Composite { fTimeGraphViewer.getVerticalBar().addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - ArrayList treeItems = getVisibleExpandedItems(tree); + List treeItems = getVisibleExpandedItems(tree); if (treeItems.size() == 0) { return; } @@ -477,7 +589,7 @@ public class TimeGraphCombo extends Composite { fTimeGraphViewer.getTimeGraphControl().addMouseWheelListener(new MouseWheelListener() { @Override public void mouseScrolled(MouseEvent e) { - ArrayList treeItems = getVisibleExpandedItems(tree); + List treeItems = getVisibleExpandedItems(tree); if (treeItems.size() == 0) { return; } @@ -519,7 +631,7 @@ public class TimeGraphCombo extends Composite { // to a value that would cause blank space to be drawn at the bottom of the tree. fNumFillerRows = Display.getDefault().getBounds().height / getItemHeight(tree); - sash.setWeights(new int[] { 1, 1 }); + sash.setWeights(weights); } // ------------------------------------------------------------------------ @@ -544,13 +656,77 @@ public class TimeGraphCombo extends Composite { return fTimeGraphViewer; } + /** + * Callback for the show filter action + * + * @since 2.0 + */ + public void showFilterDialog() { + if(fTopInput != null) { + List allElements = listAllInputs(fTopInput); + fFilterDialog.setInput(fTopInput.toArray(new ITimeGraphEntry[0])); + fFilterDialog.setTitle(Messages.TmfTimeFilterDialog_WINDOW_TITLE); + fFilterDialog.setMessage(Messages.TmfTimeFilterDialog_MESSAGE); + fFilterDialog.setExpandedElements(allElements.toArray()); + if (fFilter.getFiltered() != null) { + ArrayList nonFilteredElements = new ArrayList(allElements); + nonFilteredElements.removeAll(fFilter.getFiltered()); + fFilterDialog.setInitialElementSelections(nonFilteredElements); + } else { + fFilterDialog.setInitialElementSelections(allElements); + } + fFilterDialog.create(); + fFilterDialog.open(); + // Process selected elements + if (fFilterDialog.getResult() != null) { + fInhibitTreeSelection = true; + if (fFilterDialog.getResult().length != allElements.size()) { + ArrayList filteredElements = new ArrayList(allElements); + filteredElements.removeAll(Arrays.asList(fFilterDialog.getResult())); + fFilter.setFiltered(filteredElements); + } else { + fFilter.setFiltered(null); + } + 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 // ------------------------------------------------------------------------ - /* (non-Javadoc) - * @see org.eclipse.swt.widgets.Control#redraw() - */ @Override public void redraw() { fTimeGraphViewer.getControl().redraw(); @@ -579,6 +755,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 +789,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 +815,8 @@ 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)); + fFilter.setFiltered(null); fInhibitTreeSelection = true; fTreeViewer.setInput(input); for (SelectionListenerWrapper listenerWrapper : fSelectionListenerMap.values()) { @@ -622,6 +830,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. */ @@ -670,7 +900,7 @@ public class TimeGraphCombo extends Composite { fTreeViewer.setSelection(new StructuredSelection()); } fInhibitTreeSelection = false; - ArrayList treeItems = getVisibleExpandedItems(fTreeViewer.getTree()); + List treeItems = getVisibleExpandedItems(fTreeViewer.getTree()); if (treeItems.size() == 0) { return; } @@ -717,7 +947,7 @@ public class TimeGraphCombo extends Composite { // Internal // ------------------------------------------------------------------------ - private ArrayList getVisibleExpandedItems(Tree tree) { + private List getVisibleExpandedItems(Tree tree) { ArrayList items = new ArrayList(); for (TreeItem item : tree.getItems()) { if (item.getData() == FILLER) { @@ -731,7 +961,7 @@ public class TimeGraphCombo extends Composite { return items; } - private ArrayList getVisibleExpandedItems(TreeItem treeItem) { + private List getVisibleExpandedItems(TreeItem treeItem) { ArrayList items = new ArrayList(); for (TreeItem item : treeItem.getItems()) { items.add(item); @@ -742,6 +972,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. @@ -750,7 +997,7 @@ public class TimeGraphCombo extends Composite { if (fLinuxItemHeight != 0) { return fLinuxItemHeight; } - ArrayList treeItems = getVisibleExpandedItems(tree); + List treeItems = getVisibleExpandedItems(tree); if (treeItems.size() > 1) { final TreeItem treeItem0 = treeItems.get(0); final TreeItem treeItem1 = treeItems.get(1);