Add entry filter support for TimegraphCombo via dialog
authorAlexandre Montplaisir <alexmonthy@voxpopuli.im>
Thu, 24 Jan 2013 22:09:07 +0000 (17:09 -0500)
committerAlexandre Montplaisir <alexmonthy@voxpopuli.im>
Fri, 25 Jan 2013 22:11:21 +0000 (17:11 -0500)
Change-Id: I56d714f5a7bcb1b849fda463821dccb525478745
Signed-off-by: François Rajotte <francois.rajotte@polymtl.ca>
Signed-off-by: Alexandre Montplaisir <alexmonthy@voxpopuli.im>
Reviewed-on: https://git.eclipse.org/r/6874
Tested-by: Hudson CI
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphCombo.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphViewer.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java

index d5a4ab9a4f369e817d7b2048cf9f71ae74965d6c..f9678a44947bb4834cd39c606c19b014c98a9c20 100644 (file)
@@ -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());
index 023f47b3450c6bc282bfb0dcff4370f3d13ef058..39b81dc891c45567b49e29924739451771c7d835 100644 (file)
@@ -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<? extends ITimeGraphEntry> fTopInput;
+
+    // All the inputs (children included)
+    private List<? extends ITimeGraphEntry> fAllInput;
+
     // The selection listener map
     private final HashMap<ITimeGraphSelectionListener, SelectionListenerWrapper> fSelectionListenerMap = new HashMap<ITimeGraphSelectionListener, SelectionListenerWrapper>();
 
+    // The map of viewer filters
+    private final Map<ViewerFilter, ViewerFilter> fViewerFilterMap = new HashMap<ViewerFilter, ViewerFilter>();
+
     // 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<Object> fNonFiltered = new ArrayList<Object>();
+
+        public void setNonFiltered(List<Object> objects) {
+            fNonFiltered = objects;
+        }
+
+        public List<Object> 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<Object>(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 <code>null</code> if none
      */
     public void setInput(ITimeGraphEntry[] input) {
+        fTopInput = new ArrayList<ITimeGraphEntry>(Arrays.asList(input));
+        fAllInput = listAllInputs(fTopInput);
+        fFilter.setNonFiltered(new ArrayList<Object>(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<? extends ITimeGraphEntry> listAllInputs(List<? extends ITimeGraphEntry> inputs) {
+        ArrayList<ITimeGraphEntry> items = new ArrayList<ITimeGraphEntry>();
+        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.
index 99ede5f8e50d74aad1c2dd89a82b19595d6ab8f9..2cac2943d324d2f292e0937dc6caa51bc51344ec 100644 (file)
@@ -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();
+    }
 
 }
index 0c4985492f301833b87f51300877ef111346920b..a9e8483729b753fabbbc98e84150215687d88986 100644 (file)
@@ -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<MenuDetectListener> _timeEventMenuListeners = new ArrayList<MenuDetectListener>();
     private final Cursor _dragCursor3;
     private final Cursor _WaitCursor;
+    private final List<ViewerFilter> _filters = new ArrayList<ViewerFilter>();
 
     // 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<Item> 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);
+                    }
                 }
             }
         }
This page took 0.030837 seconds and 5 git commands to generate.