TMF: added support for process filter in the TimeGraphFilterDialog.
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / widgets / timegraph / dialogs / TimeGraphFilterDialog.java
index c8d50e205c30e53b9bcd2515c0469bf9589a8e6d..76465cd0710690bcbcebb3c2353b8878100ee3bb 100644 (file)
@@ -13,6 +13,8 @@
  *          CheckedTreeSelectionDialog#createSelectionButtons(Composite) fails to
  *          align the selection buttons to the right
  *      François Rajotte - Support for multiple columns + selection control
+ *      Patrick Tasse - Fix Sonar warnings
+ *      Generoso Pagano - Add tree filter
  *******************************************************************************/
 
 package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.dialogs;
@@ -29,6 +31,7 @@ import org.eclipse.jface.viewers.CheckboxTreeViewer;
 import org.eclipse.jface.viewers.IBaseLabelProvider;
 import org.eclipse.jface.viewers.ICheckStateListener;
 import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreeSelection;
 import org.eclipse.jface.viewers.ViewerComparator;
 import org.eclipse.jface.viewers.ViewerFilter;
 import org.eclipse.linuxtools.internal.tmf.ui.Messages;
@@ -37,7 +40,6 @@ import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.BusyIndicator;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
@@ -48,22 +50,29 @@ import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Tree;
 import org.eclipse.swt.widgets.TreeColumn;
 import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.dialogs.ContainerCheckedTreeViewer;
 import org.eclipse.ui.dialogs.ISelectionStatusValidator;
+import org.eclipse.ui.dialogs.PatternFilter;
 import org.eclipse.ui.dialogs.SelectionStatusDialog;
 
 /**
- * Filter dialog for the time graphs
- * This class is derived from the CheckedTreeSelectionDialog
- * It was necessary to develop this similar dialog to allow multiple columns
+ * Filter dialog for the time graphs This class is derived from the
+ * CheckedTreeSelectionDialog It was necessary to develop this similar dialog to
+ * allow multiple columns
  *
  * @version 1.0
  * @since 2.0
  * @author François Rajotte
  */
 public class TimeGraphFilterDialog extends SelectionStatusDialog {
+    private static final int BUTTON_CHECK_SELECTED_ID = IDialogConstants.CLIENT_ID;
+    private static final int BUTTON_UNCHECK_SELECTED_ID = IDialogConstants.CLIENT_ID + 1;
+    private static final int BUTTON_CHECK_SUBTREE_ID = IDialogConstants.CLIENT_ID + 2;
+    private static final int BUTTON_UNCHECK_SUBTREE_ID = IDialogConstants.CLIENT_ID + 3;
 
-    private CheckboxTreeViewer fViewer;
+    private static final int DEFAULT_WIDTH = 60;
+    private static final int DEFAULT_HEIGHT = 18;
+
+    private FilteredCheckboxTree fTree;
 
     private IBaseLabelProvider fLabelProvider;
 
@@ -86,11 +95,9 @@ public class TimeGraphFilterDialog extends SelectionStatusDialog {
 
     private boolean fIsEmpty;
 
-    private int fWidth = 60;
-
-    private int fHeight = 18;
+    private int fWidth = DEFAULT_WIDTH;
 
-    private boolean fContainerMode;
+    private int fHeight = DEFAULT_HEIGHT;
 
     private Object[] fExpandedElements;
 
@@ -102,24 +109,12 @@ public class TimeGraphFilterDialog extends SelectionStatusDialog {
      */
     public TimeGraphFilterDialog(Shell parent) {
         super(parent);
-        setResult(new ArrayList<Object>(0));
+        setResult(new ArrayList<>(0));
         setStatusLineAboveButtons(true);
         setHelpAvailable(false);
-        fContainerMode = false;
         fExpandedElements = null;
     }
 
-    /**
-     * If set, the checked /gray state of containers (inner nodes) is derived
-     * from the checked state of its leaf nodes.
-     *
-     * @param containerMode
-     *            The containerMode to set
-     */
-    public void setContainerMode(boolean containerMode) {
-        fContainerMode = containerMode;
-    }
-
     /**
      * Sets the initial selection. Convenience method.
      *
@@ -158,7 +153,7 @@ public class TimeGraphFilterDialog extends SelectionStatusDialog {
      */
     public void addFilter(ViewerFilter filter) {
         if (fFilters == null) {
-            fFilters = new ArrayList<ViewerFilter>(4);
+            fFilters = new ArrayList<>();
         }
         fFilters.add(filter);
     }
@@ -191,7 +186,11 @@ public class TimeGraphFilterDialog extends SelectionStatusDialog {
      *            The elements that will be expanded.
      */
     public void setExpandedElements(Object[] elements) {
-        fExpandedElements = elements;
+        if (elements != null) {
+            fExpandedElements = Arrays.copyOf(elements, elements.length);
+        } else {
+            fExpandedElements = null;
+        }
     }
 
     /**
@@ -208,24 +207,31 @@ public class TimeGraphFilterDialog extends SelectionStatusDialog {
     }
 
     /**
-     * @param contentProvider The content provider for the table
+     * @param contentProvider
+     *            The content provider for the table
      */
     public void setContentProvider(ITreeContentProvider contentProvider) {
         fContentProvider = contentProvider;
     }
 
     /**
-     * @param labelProvider The label provider for the table
+     * @param labelProvider
+     *            The label provider for the table
      */
     public void setLabelProvider(IBaseLabelProvider labelProvider) {
         fLabelProvider = labelProvider;
     }
 
     /**
-     * @param columnNames An array of column names to display
+     * @param columnNames
+     *            An array of column names to display
      */
     public void setColumnNames(String[] columnNames) {
-        fColumnNames = columnNames;
+        if (columnNames != null) {
+            fColumnNames = Arrays.copyOf(columnNames, columnNames.length);
+        } else {
+            fColumnNames = null;
+        }
     }
 
     /**
@@ -235,7 +241,7 @@ public class TimeGraphFilterDialog extends SelectionStatusDialog {
     protected void updateOKStatus() {
         if (!fIsEmpty) {
             if (fValidator != null) {
-                fCurrStatus = fValidator.validate(fViewer.getCheckedElements());
+                fCurrStatus = fValidator.validate(fTree.getCheckedElements());
                 updateStatus(fCurrStatus);
             } else if (!fCurrStatus.isOK()) {
                 fCurrStatus = new Status(IStatus.OK, PlatformUI.PLUGIN_ID,
@@ -256,10 +262,6 @@ public class TimeGraphFilterDialog extends SelectionStatusDialog {
         return getReturnCode();
     }
 
-    private void access$superCreate() {
-        super.create();
-    }
-
     @Override
     protected void cancelPressed() {
         setResult(null);
@@ -268,7 +270,7 @@ public class TimeGraphFilterDialog extends SelectionStatusDialog {
 
     @Override
     protected void computeResult() {
-        setResult(Arrays.asList(fViewer.getCheckedElements()));
+        setResult(Arrays.asList(fTree.getCheckedElements()));
     }
 
     @Override
@@ -276,11 +278,11 @@ public class TimeGraphFilterDialog extends SelectionStatusDialog {
         BusyIndicator.showWhile(null, new Runnable() {
             @Override
             public void run() {
-                access$superCreate();
-                fViewer.setCheckedElements(getInitialElementSelections()
+                TimeGraphFilterDialog.super.create();
+                fTree.setCheckedElements(getInitialElementSelections()
                         .toArray());
                 if (fExpandedElements != null) {
-                    fViewer.setExpandedElements(fExpandedElements);
+                    fTree.getViewer().setExpandedElements(fExpandedElements);
                 }
                 updateOKStatus();
             }
@@ -315,13 +317,11 @@ public class TimeGraphFilterDialog extends SelectionStatusDialog {
      * @return the tree viewer
      */
     protected CheckboxTreeViewer createTreeViewer(Composite parent) {
-        if (fContainerMode) {
-            fViewer = new ContainerCheckedTreeViewer(parent, SWT.BORDER);
-        } else {
-            fViewer = new CheckboxTreeViewer(parent, SWT.BORDER);
-        }
+        PatternFilter filter = new TreePatternFilter();
+        filter.setIncludeLeadingWildcard(true);
+        fTree = new FilteredCheckboxTree(parent, SWT.BORDER | SWT.MULTI, filter, true);
 
-        Tree tree = fViewer.getTree();
+        Tree tree = fTree.getViewer().getTree();
         tree.setHeaderVisible(true);
         for (String columnName : fColumnNames) {
             TreeColumn column = new TreeColumn(tree, SWT.LEFT);
@@ -329,28 +329,22 @@ public class TimeGraphFilterDialog extends SelectionStatusDialog {
             column.pack();
         }
 
-        fViewer.setContentProvider(fContentProvider);
-        fViewer.setLabelProvider(fLabelProvider);
-        fViewer.addCheckStateListener(new CheckStateListener());
-        fViewer.addCheckStateListener(new ICheckStateListener() {
-            @Override
-            public void checkStateChanged(CheckStateChangedEvent event) {
-                updateOKStatus();
-            }
-        });
-        fViewer.setComparator(fComparator);
+        fTree.getViewer().setContentProvider(fContentProvider);
+        fTree.getViewer().setLabelProvider(fLabelProvider);
+        fTree.addCheckStateListener(new CheckStateListener());
+        fTree.getViewer().setComparator(fComparator);
         if (fFilters != null) {
             for (int i = 0; i != fFilters.size(); i++) {
-                fViewer.addFilter(fFilters.get(i));
+                fTree.getViewer().addFilter(fFilters.get(i));
             }
         }
-        fViewer.setInput(fInput);
+        fTree.getViewer().setInput(fInput);
 
-        //pack the columns again for a nice view...
+        // pack the columns again for a nice view...
         for (TreeColumn column : tree.getColumns()) {
             column.pack();
         }
-        return fViewer;
+        return (CheckboxTreeViewer) fTree.getViewer();
     }
 
     /**
@@ -359,7 +353,7 @@ public class TimeGraphFilterDialog extends SelectionStatusDialog {
      * @return the tree viewer
      */
     protected CheckboxTreeViewer getTreeViewer() {
-        return fViewer;
+        return (CheckboxTreeViewer) fTree.getViewer();
     }
 
     /**
@@ -372,7 +366,6 @@ public class TimeGraphFilterDialog extends SelectionStatusDialog {
     protected Composite createSelectionButtons(Composite composite) {
         Composite buttonComposite = new Composite(composite, SWT.RIGHT);
         GridLayout layout = new GridLayout();
-        layout.numColumns = 0;
         layout.marginWidth = 0;
         layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
         buttonComposite.setLayout(layout);
@@ -381,46 +374,166 @@ public class TimeGraphFilterDialog extends SelectionStatusDialog {
                 | GridData.GRAB_HORIZONTAL);
         data.grabExcessHorizontalSpace = true;
         buttonComposite.setLayoutData(data);
-        Button selectButton = createButton(buttonComposite,
-                IDialogConstants.SELECT_ALL_ID, Messages.TmfTimeFilterDialog_SELECT_ALL,
+
+        /* Create the buttons in the good order to place them as we want */
+        Button checkSelectedButton = createButton(buttonComposite,
+                BUTTON_CHECK_SELECTED_ID, Messages.TmfTimeFilterDialog_CHECK_SELECTED,
+                false);
+        Button checkSubtreeButton = createButton(buttonComposite,
+                BUTTON_CHECK_SUBTREE_ID, Messages.TmfTimeFilterDialog_CHECK_SUBTREE,
                 false);
-        SelectionListener listener = new SelectionAdapter() {
+        Button checkAllButton = createButton(buttonComposite,
+                IDialogConstants.SELECT_ALL_ID, Messages.TmfTimeFilterDialog_CHECK_ALL,
+                false);
+
+        Button uncheckSelectedButton = createButton(buttonComposite,
+                BUTTON_UNCHECK_SELECTED_ID, Messages.TmfTimeFilterDialog_UNCHECK_SELECTED,
+                false);
+        Button uncheckSubtreeButton = createButton(buttonComposite,
+                BUTTON_UNCHECK_SUBTREE_ID, Messages.TmfTimeFilterDialog_UNCHECK_SUBTREE,
+                false);
+        Button uncheckAllButton = createButton(buttonComposite,
+                IDialogConstants.DESELECT_ALL_ID, Messages.TmfTimeFilterDialog_UNCHECK_ALL,
+                false);
+
+        /*
+         * Apply the layout again after creating the buttons to override
+         * createButton messing with the columns
+         */
+        layout.numColumns = 3;
+        buttonComposite.setLayout(layout);
+
+        /* Add a listener to each button */
+        checkSelectedButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                TreeSelection selection = (TreeSelection) fTree.getViewer().getSelection();
+
+                for (Object element : selection.toArray()) {
+                    checkElement(element);
+                }
+
+                updateOKStatus();
+            }
+        });
+
+        checkSubtreeButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                TreeSelection selection = (TreeSelection) fTree.getViewer().getSelection();
+
+                for (Object element : selection.toArray()) {
+                    checkElementAndSubtree(element);
+                }
+            }
+        });
+
+        checkAllButton.addSelectionListener(new SelectionAdapter() {
             @Override
             public void widgetSelected(SelectionEvent e) {
                 Object[] viewerElements = fContentProvider.getElements(fInput);
-                if (fContainerMode) {
-                    fViewer.setCheckedElements(viewerElements);
-                } else {
-                    for (int i = 0; i < viewerElements.length; i++) {
-                        fViewer.setSubtreeChecked(viewerElements[i], true);
-                    }
+
+                for (int i = 0; i < viewerElements.length; i++) {
+                    fTree.setSubtreeChecked(viewerElements[i], true);
                 }
+
                 updateOKStatus();
             }
-        };
-        selectButton.addSelectionListener(listener);
-        Button deselectButton = createButton(buttonComposite,
-                IDialogConstants.DESELECT_ALL_ID, Messages.TmfTimeFilterDialog_DESELECT_ALL,
-                false);
-        listener = new SelectionAdapter() {
+        });
+
+        uncheckSelectedButton.addSelectionListener(new SelectionAdapter() {
             @Override
             public void widgetSelected(SelectionEvent e) {
-                fViewer.setCheckedElements(new Object[0]);
+                TreeSelection selection = (TreeSelection) fTree.getViewer().getSelection();
+
+                for (Object element : selection.toArray()) {
+                    uncheckElement(element);
+                }
+
                 updateOKStatus();
             }
-        };
-        deselectButton.addSelectionListener(listener);
+        });
+
+        uncheckSubtreeButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                TreeSelection selection = (TreeSelection) fTree.getViewer().getSelection();
+
+                for (Object element : selection.toArray()) {
+                    uncheckElement(element);
+                }
+
+                updateOKStatus();
+            }
+        });
+
+        uncheckAllButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                Object[] viewerElements = fContentProvider.getElements(fInput);
+                for (Object element : viewerElements) {
+                    if (fTree.getViewer().testFindItem(element) != null) {
+                        // uncheck only visible roots and their children
+                        uncheckElement(element);
+                    }
+                }
+                updateOKStatus();
+            }
+        });
+
         return buttonComposite;
     }
 
+    /**
+     * Check an element and all its parents.
+     *
+     * @param element
+     *            The element to check.
+     */
+    private void checkElement(Object element) {
+        fTree.setChecked(element, true);
+
+        Object parent = fContentProvider.getParent(element);
+
+        if (parent != null && !fTree.getChecked(parent)) {
+            checkElement(parent);
+        }
+    }
+
+    /**
+     * Check an element, all its parents and all its children.
+     *
+     * @param element
+     *            The element to check.
+     */
+    private void checkElementAndSubtree(Object element) {
+        checkElement(element);
+
+        for (Object child : fContentProvider.getChildren(element)) {
+            checkElementAndSubtree(child);
+        }
+    }
+
+    /**
+     * Uncheck an element and all its children.
+     *
+     * @param element
+     *            The element to uncheck.
+     */
+    private void uncheckElement(Object element) {
+        fTree.setChecked(element, false);
+
+        for (Object child : fContentProvider.getChildren(element)) {
+            uncheckElement(child);
+        }
+    }
+
     private boolean evaluateIfTreeEmpty(Object input) {
         Object[] elements = fContentProvider.getElements(input);
-        if (elements.length > 0) {
-            if (fFilters != null) {
-                for (int i = 0; i < fFilters.size(); i++) {
-                    ViewerFilter curr = fFilters.get(i);
-                    elements = curr.filter(fViewer, input, elements);
-                }
+        if (elements.length > 0 && fFilters != null) {
+            for (int i = 0; i < fFilters.size(); i++) {
+                ViewerFilter curr = fFilters.get(i);
+                elements = curr.filter(fTree.getViewer(), input, elements);
             }
         }
         return elements.length == 0;
@@ -434,37 +547,23 @@ public class TimeGraphFilterDialog extends SelectionStatusDialog {
 
         CheckStateListener() {
         }
+
         @Override
         public void checkStateChanged(CheckStateChangedEvent event) {
             try {
                 ITimeGraphEntry entry = (ITimeGraphEntry) event.getElement();
                 boolean checked = event.getChecked();
-                if (!checked) {
-                    uncheckChildren(entry);
-                }
-                else
-                {
-                    checkParent(entry);
+                if (checked) {
+                    checkElement(entry);
+                } else {
+                    uncheckElement(entry);
                 }
             } catch (ClassCastException e) {
                 return;
+            } finally {
+                updateOKStatus();
             }
         }
 
-        private void uncheckChildren(ITimeGraphEntry entry) {
-
-            for (ITimeGraphEntry child : entry.getChildren()) {
-                getTreeViewer().setChecked(child, false);
-                uncheckChildren(child);
-            }
-        }
-
-        private void checkParent(ITimeGraphEntry entry) {
-
-            if (entry.getParent() != null) {
-                getTreeViewer().setChecked(entry.getParent(), true);
-                checkParent(entry.getParent());
-            }
-        }
     }
-}
+}
\ No newline at end of file
This page took 0.052111 seconds and 5 git commands to generate.