tmf.ui: bug 505695 fix time graph views with GTK
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / widgets / timegraph / TimeGraphCombo.java
index 11d916eb1c981c7da44991ab12df84dafc10243e..0c27d2515b296c2fc8907e5f5217a580e6fa2457 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson, others
+ * Copyright (c) 2012, 2016 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
@@ -41,17 +41,17 @@ import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.SashForm;
 import org.eclipse.swt.events.ControlAdapter;
 import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.MouseAdapter;
 import org.eclipse.swt.events.MouseEvent;
 import org.eclipse.swt.events.MouseTrackAdapter;
-import org.eclipse.swt.events.MouseWheelListener;
 import org.eclipse.swt.events.PaintEvent;
 import org.eclipse.swt.events.PaintListener;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.graphics.Font;
 import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.GC;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.graphics.Rectangle;
@@ -75,8 +75,10 @@ import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs.ITimeGraphEntry
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs.ShowFilterDialogAction;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ILinkEvent;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.ITimeDataProvider;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphColorScheme;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphMarkerAxis;
 
 import com.google.common.collect.Iterables;
 
@@ -92,7 +94,9 @@ public class TimeGraphCombo extends Composite {
     // Constants
     // ------------------------------------------------------------------------
 
-    /** Constant indicating that all levels of the time graph should be expanded */
+    /**
+     * Constant indicating that all levels of the time graph should be expanded
+     */
     public static final int ALL_LEVELS = AbstractTreeViewer.ALL_LEVELS;
 
     private static final Object FILLER = new Object();
@@ -177,13 +181,111 @@ public class TimeGraphCombo extends Composite {
                 public void resetVerticalZoom() {
                     TimeGraphCombo.this.resetVerticalZoom();
                 }
+
+                @Override
+                public void setElementPosition(ITimeGraphEntry entry, int y) {
+                    /*
+                     * Queue the update to make sure the time graph combo has
+                     * finished updating the item heights.
+                     */
+                    getDisplay().asyncExec(() -> {
+                        if (isDisposed()) {
+                            return;
+                        }
+                        super.setElementPosition(entry, y);
+                        alignTreeItems(false);
+                    });
+                }
             };
         }
+
+        private class TimeGraphMarkerAxisExtension extends TimeGraphMarkerAxis {
+            private int fMargin = 0;
+
+            public TimeGraphMarkerAxisExtension(Composite parent, @NonNull TimeGraphColorScheme colorScheme, @NonNull ITimeDataProvider timeProvider) {
+                super(parent, colorScheme, timeProvider);
+            }
+
+            @Override
+            public Point computeSize(int wHint, int hHint, boolean changed) {
+                Point size = super.computeSize(wHint, hHint, changed);
+                if (size.y > 0) {
+                    size.y += fMargin;
+                }
+                return size;
+            }
+
+            @Override
+            public void redraw() {
+                super.redraw();
+                fTreeViewer.getControl().redraw();
+            }
+
+            @Override
+            protected void drawMarkerAxis(Rectangle bounds, int nameSpace, GC gc) {
+                super.drawMarkerAxis(bounds, nameSpace, gc);
+            }
+
+            private Rectangle getAxisBounds() {
+                Tree tree = fTreeViewer.getTree();
+                Rectangle axisBounds = getBounds();
+                Rectangle treeClientArea = tree.getClientArea();
+                if (axisBounds.isEmpty()) {
+                    treeClientArea.y += treeClientArea.height;
+                    treeClientArea.height = 0;
+                    return treeClientArea;
+                }
+                Composite axisParent = getParent();
+                Point axisDisplayCoordinates = axisParent.toDisplay(axisBounds.x, axisBounds.y);
+                Point axisTreeCoordinates = tree.toControl(axisDisplayCoordinates);
+                int height = treeClientArea.y + treeClientArea.height - axisTreeCoordinates.y;
+                int margin = Math.max(0, axisBounds.height - height);
+                if (fMargin != margin) {
+                    fMargin = margin;
+                    getParent().layout();
+                    redraw();
+                    axisTreeCoordinates.y -= margin;
+                    height += margin;
+                }
+                return new Rectangle(treeClientArea.x, axisTreeCoordinates.y, treeClientArea.width, height);
+            }
+        }
+
+        @Override
+        protected TimeGraphMarkerAxis createTimeGraphMarkerAxis(Composite parent, @NonNull TimeGraphColorScheme colorScheme, @NonNull ITimeDataProvider timeProvider) {
+            TimeGraphMarkerAxisExtension timeGraphMarkerAxis = new TimeGraphMarkerAxisExtension(parent, colorScheme, timeProvider);
+            Tree tree = fTreeViewer.getTree();
+            tree.addPaintListener(e -> {
+                /*
+                 * Draw the marker axis over the tree. Only the name area will
+                 * be drawn, since the time area has zero width.
+                 */
+                Rectangle bounds = timeGraphMarkerAxis.getAxisBounds();
+                e.gc.setBackground(timeGraphMarkerAxis.getBackground());
+                timeGraphMarkerAxis.drawMarkerAxis(bounds, bounds.width, e.gc);
+            });
+            tree.addMouseListener(new MouseAdapter() {
+                @Override
+                public void mouseDown(MouseEvent e) {
+                    Rectangle bounds = timeGraphMarkerAxis.getAxisBounds();
+                    if (bounds.contains(e.x, e.y)) {
+                        timeGraphMarkerAxis.mouseDown(e, bounds, bounds.width);
+                    }
+                }
+            });
+            tree.getHorizontalBar().addSelectionListener(new SelectionAdapter() {
+                @Override
+                public void widgetSelected(SelectionEvent e) {
+                    tree.redraw();
+                }
+            });
+            return timeGraphMarkerAxis;
+        }
     }
 
     /**
-     * The TreeContentProviderWrapper is used to insert filler items after
-     * the elements of the tree's real content provider.
+     * The TreeContentProviderWrapper is used to insert filler items after the
+     * elements of the tree's real content provider.
      */
     private class TreeContentProviderWrapper implements ITreeContentProvider {
         private final ITreeContentProvider contentProvider;
@@ -239,10 +341,10 @@ public class TimeGraphCombo extends Composite {
     }
 
     /**
-     * The TreeLabelProviderWrapper is used to intercept the filler items
-     * from the calls to the tree's real label provider.
+     * The TreeLabelProviderWrapper is used to intercept the filler items from
+     * the calls to the tree's real label provider.
      */
-    private class TreeLabelProviderWrapper implements ITableLabelProvider {
+    private static class TreeLabelProviderWrapper implements ITableLabelProvider {
         private final ITableLabelProvider labelProvider;
 
         public TreeLabelProviderWrapper(ITableLabelProvider labelProvider) {
@@ -330,11 +432,11 @@ 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.
+     * 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 static class ViewerFilterWrapper extends ViewerFilter {
 
         private ViewerFilter fWrappedFilter;
 
@@ -358,11 +460,14 @@ public class TimeGraphCombo extends Composite {
     // ------------------------------------------------------------------------
 
     /**
-     * Constructs a new instance of this class given its parent
-     * and a style value describing its behavior and appearance.
+     * 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 parent
+     *            a widget which will be the parent of the new instance (cannot
+     *            be null)
+     * @param style
+     *            the style of widget to construct
      */
     public TimeGraphCombo(Composite parent, int style) {
         this(parent, style, DEFAULT_WEIGHTS);
@@ -427,7 +532,8 @@ public class TimeGraphCombo extends Composite {
         // This work around used to be done on control resized but the header
         // height was not initialized on the initial resize on GTK3.
         tree.addPaintListener(new PaintListener() {
-            @Override
+
+    @Override
             public void paintControl(PaintEvent e) {
                 int headerHeight = tree.getHeaderHeight();
                 if (headerHeight > 0) {
@@ -437,12 +543,9 @@ public class TimeGraphCombo extends Composite {
             }
         });
 
-        tree.addDisposeListener(new DisposeListener() {
-            @Override
-            public void widgetDisposed(DisposeEvent e) {
-                if (fTreeFont != null) {
-                    fTreeFont.dispose();
-                }
+        tree.addDisposeListener(e -> {
+            if (fTreeFont != null) {
+                fTreeFont.dispose();
             }
         });
 
@@ -507,77 +610,75 @@ public class TimeGraphCombo extends Composite {
         });
 
         // prevent mouse button from selecting a filler tree item
-        tree.addListener(SWT.MouseDown, new Listener() {
-            @Override
-            public void handleEvent(Event event) {
-                TreeItem treeItem = tree.getItem(new Point(event.x, event.y));
-                if (treeItem == null || treeItem.getData() == FILLER) {
-                    event.doit = false;
-                    List<TreeItem> treeItems = getVisibleExpandedItems(tree, false);
-                    if (treeItems.size() == 0) {
-                        fTreeViewer.setSelection(new StructuredSelection());
-                        fTimeGraphViewer.setSelection(null);
-                        return;
-                    }
-                    // this prevents from scrolling up when selecting
-                    // the partially visible tree item at the bottom
-                    tree.select(treeItems.get(treeItems.size() - 1));
-                    fTreeViewer.setSelection(new StructuredSelection());
-                    fTimeGraphViewer.setSelection(null);
-                }
+        tree.addListener(SWT.MouseDown, event -> {
+            List<TreeItem> treeItems = getVisibleExpandedItems(tree, false);
+            if (treeItems.isEmpty()) {
+                event.doit = false;
+                fTreeViewer.setSelection(new StructuredSelection());
+                fTimeGraphViewer.setSelection(null);
+                return;
+            }
+            TreeItem lastTreeItem = treeItems.get(treeItems.size() - 1);
+            if (event.y >= lastTreeItem.getBounds().y + lastTreeItem.getBounds().height) {
+                event.doit = false;
+                // this prevents from scrolling up when selecting
+                // the partially visible tree item at the bottom
+                tree.select(treeItems.get(treeItems.size() - 1));
+                fTreeViewer.setSelection(new StructuredSelection());
+                fTimeGraphViewer.setSelection(null);
             }
         });
 
         // prevent mouse wheel from scrolling down into filler tree items
-        tree.addListener(SWT.MouseWheel, new Listener() {
-            @Override
-            public void handleEvent(Event event) {
-                event.doit = false;
-                Slider scrollBar = fTimeGraphViewer.getVerticalBar();
-                fTimeGraphViewer.setTopIndex(scrollBar.getSelection() - event.count);
-                alignTreeItems(false);
+        tree.addListener(SWT.MouseWheel, event -> {
+            event.doit = false;
+            if (event.count == 0) {
+                return;
             }
+            Slider scrollBar = fTimeGraphViewer.getVerticalBar();
+            fTimeGraphViewer.setTopIndex(scrollBar.getSelection() - event.count);
+            alignTreeItems(false);
         });
 
         // prevent key stroke from selecting a filler tree item
-        tree.addListener(SWT.KeyDown, new Listener() {
-            @Override
-            public void handleEvent(Event event) {
-                List<TreeItem> treeItems = getVisibleExpandedItems(tree, false);
-                if (treeItems.size() == 0) {
-                    fTreeViewer.setSelection(new StructuredSelection());
-                    event.doit = false;
-                    return;
-                }
-                if (event.keyCode == SWT.ARROW_DOWN) {
-                    int index = Math.min(fTimeGraphViewer.getSelectionIndex() + 1, treeItems.size() - 1);
-                    fTimeGraphViewer.setSelection((ITimeGraphEntry) treeItems.get(index).getData());
-                    event.doit = false;
-                } else if (event.keyCode == SWT.PAGE_DOWN) {
-                    int height = tree.getSize().y - tree.getHeaderHeight() - tree.getHorizontalBar().getSize().y;
-                    int countPerPage = height / getItemHeight(tree, false);
-                    int index = Math.min(fTimeGraphViewer.getSelectionIndex() + countPerPage - 1, treeItems.size() - 1);
-                    fTimeGraphViewer.setSelection((ITimeGraphEntry) treeItems.get(index).getData());
-                    event.doit = false;
-                } else if (event.keyCode == SWT.END) {
-                    fTimeGraphViewer.setSelection((ITimeGraphEntry) treeItems.get(treeItems.size() - 1).getData());
-                    event.doit = false;
-                } else if ((event.character == '+' || event.character == '=') && ((event.stateMask & SWT.CTRL) != 0)) {
-                    verticalZoom(true);
-                } else if (event.character == '-' && ((event.stateMask & SWT.CTRL) != 0)) {
-                    verticalZoom(false);
-                } else if (event.character == '0' && ((event.stateMask & SWT.CTRL) != 0)) {
-                    resetVerticalZoom();
-                } else {
-                    return;
-                }
-                if (fTimeGraphViewer.getSelectionIndex() >= 0) {
-                    fTreeViewer.setSelection(new StructuredSelection(fTimeGraphViewer.getSelection()));
-                } else {
-                    fTreeViewer.setSelection(new StructuredSelection());
-                }
-                alignTreeItems(false);
+        tree.addListener(SWT.KeyDown, event -> {
+            List<TreeItem> treeItems = getVisibleExpandedItems(tree, false);
+            if (treeItems.size() == 0) {
+                fTreeViewer.setSelection(new StructuredSelection());
+                event.doit = false;
+                return;
             }
+            if (event.keyCode == SWT.ARROW_DOWN) {
+                int index = Math.min(fTimeGraphViewer.getSelectionIndex() + 1, treeItems.size() - 1);
+                fTimeGraphViewer.setSelection((ITimeGraphEntry) treeItems.get(index).getData());
+                event.doit = false;
+            } else if (event.keyCode == SWT.PAGE_DOWN) {
+                int height = tree.getSize().y - tree.getHeaderHeight() - tree.getHorizontalBar().getSize().y;
+                int countPerPage = height / getItemHeight(tree, false);
+                int index = Math.min(fTimeGraphViewer.getSelectionIndex() + countPerPage - 1, treeItems.size() - 1);
+                fTimeGraphViewer.setSelection((ITimeGraphEntry) treeItems.get(index).getData());
+                event.doit = false;
+            } else if (event.keyCode == SWT.END) {
+                fTimeGraphViewer.setSelection((ITimeGraphEntry) treeItems.get(treeItems.size() - 1).getData());
+                event.doit = false;
+            } else if ((event.character == '+' || event.character == '=') && ((event.stateMask & SWT.CTRL) != 0)) {
+                fTimeGraphViewer.getTimeGraphControl().keyPressed(new KeyEvent(event));
+                return;
+            } else if (event.character == '-' && ((event.stateMask & SWT.CTRL) != 0)) {
+                fTimeGraphViewer.getTimeGraphControl().keyPressed(new KeyEvent(event));
+                return;
+            } else if (event.character == '0' && ((event.stateMask & SWT.CTRL) != 0)) {
+                fTimeGraphViewer.getTimeGraphControl().keyPressed(new KeyEvent(event));
+                return;
+            } else {
+                return;
+            }
+            if (fTimeGraphViewer.getSelectionIndex() >= 0) {
+                fTreeViewer.setSelection(new StructuredSelection(fTimeGraphViewer.getSelection()));
+            } else {
+                fTreeViewer.setSelection(new StructuredSelection());
+            }
+            alignTreeItems(false);
         });
 
         // ensure alignment of top item between tree and time graph
@@ -589,53 +690,40 @@ public class TimeGraphCombo extends Composite {
         });
 
         // ensure synchronization of selected item between tree and time graph
-        fTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
-            @Override
-            public void selectionChanged(SelectionChangedEvent event) {
-                if (fInhibitTreeSelection) {
-                    return;
-                }
-                if (event.getSelection() instanceof IStructuredSelection) {
-                    Object selection = ((IStructuredSelection) event.getSelection()).getFirstElement();
-                    if (selection instanceof ITimeGraphEntry) {
-                        fTimeGraphViewer.setSelection((ITimeGraphEntry) selection);
-                    }
-                    alignTreeItems(false);
+        fTreeViewer.addSelectionChangedListener(event -> {
+            if (fInhibitTreeSelection) {
+                return;
+            }
+            if (event.getSelection() instanceof IStructuredSelection) {
+                Object selection = ((IStructuredSelection) event.getSelection()).getFirstElement();
+                if (selection instanceof ITimeGraphEntry) {
+                    fTimeGraphViewer.setSelection((ITimeGraphEntry) selection);
                 }
+                alignTreeItems(false);
             }
         });
 
         // ensure synchronization of selected item between tree and time graph
-        fTimeGraphViewer.addSelectionListener(new ITimeGraphSelectionListener() {
-            @Override
-            public void selectionChanged(TimeGraphSelectionEvent event) {
-                ITimeGraphEntry entry = fTimeGraphViewer.getSelection();
-                fInhibitTreeSelection = true; // block the tree selection changed listener
-                if (entry != null) {
-                    StructuredSelection selection = new StructuredSelection(entry);
-                    fTreeViewer.setSelection(selection);
-                } else {
-                    fTreeViewer.setSelection(new StructuredSelection());
-                }
-                fInhibitTreeSelection = false;
-                alignTreeItems(false);
-            }
+        fTimeGraphViewer.addSelectionListener(event -> {
+            ITimeGraphEntry entry = fTimeGraphViewer.getSelection();
+            setSelectionInTree(entry);
         });
 
         // ensure alignment of top item between tree and time graph
         fTimeGraphViewer.getVerticalBar().addSelectionListener(new SelectionAdapter() {
-            @Override
+
+    @Override
             public void widgetSelected(SelectionEvent e) {
                 alignTreeItems(false);
             }
         });
 
         // ensure alignment of top item between tree and time graph
-        fTimeGraphViewer.getTimeGraphControl().addMouseWheelListener(new MouseWheelListener() {
-            @Override
-            public void mouseScrolled(MouseEvent e) {
-                alignTreeItems(false);
+        fTimeGraphViewer.getTimeGraphControl().addMouseWheelListener(e -> {
+            if (e.count == 0) {
+                return;
             }
+            alignTreeItems(false);
         });
 
         // ensure the tree has focus control when mouse is over it if the time graph had control
@@ -764,7 +852,7 @@ public class TimeGraphCombo extends Composite {
      * Get the show filter dialog action.
      *
      * @return The Action object
-     * @since 2.0
+     * @since 1.2
      */
     public ShowFilterDialogAction getShowFilterDialogAction() {
         if (fShowFilterDialogAction == null) {
@@ -814,7 +902,8 @@ public class TimeGraphCombo extends Composite {
     /**
      * Sets the tree content provider used by this time graph combo.
      *
-     * @param contentProvider the tree content provider
+     * @param contentProvider
+     *            the tree content provider
      */
     public void setTreeContentProvider(ITreeContentProvider contentProvider) {
         fTreeViewer.setContentProvider(new TreeContentProviderWrapper(contentProvider));
@@ -823,7 +912,8 @@ public class TimeGraphCombo extends Composite {
     /**
      * Sets the tree label provider used by this time graph combo.
      *
-     * @param labelProvider the tree label provider
+     * @param labelProvider
+     *            the tree label provider
      */
     public void setTreeLabelProvider(ITableLabelProvider labelProvider) {
         fTreeViewer.setLabelProvider(new TreeLabelProviderWrapper(labelProvider));
@@ -832,7 +922,8 @@ public class TimeGraphCombo extends Composite {
     /**
      * Sets the tree content provider used by the filter dialog
      *
-     * @param contentProvider the tree content provider
+     * @param contentProvider
+     *            the tree content provider
      */
     public void setFilterContentProvider(ITreeContentProvider contentProvider) {
         getShowFilterDialogAction().getFilterDialog().setContentProvider(contentProvider);
@@ -841,7 +932,8 @@ public class TimeGraphCombo extends Composite {
     /**
      * Sets the tree label provider used by the filter dialog
      *
-     * @param labelProvider the tree label provider
+     * @param labelProvider
+     *            the tree label provider
      */
     public void setFilterLabelProvider(ITableLabelProvider labelProvider) {
         getShowFilterDialogAction().getFilterDialog().setLabelProvider(labelProvider);
@@ -872,12 +964,14 @@ public class TimeGraphCombo extends Composite {
     /**
      * Sets the tree columns for this time graph combo.
      *
-     * @param columnNames the tree column names
+     * @param columnNames
+     *            the tree column names
      */
     public void setTreeColumns(String[] columnNames) {
         final Tree tree = fTreeViewer.getTree();
         for (String columnName : columnNames) {
             TreeColumn column = new TreeColumn(tree, SWT.LEFT);
+            column.setMoveable(true);
             column.setText(columnName);
             column.pack();
         }
@@ -886,7 +980,8 @@ public class TimeGraphCombo extends Composite {
     /**
      * Sets the tree columns for this time graph combo's filter dialog.
      *
-     * @param columnNames the tree column names
+     * @param columnNames
+     *            the tree column names
      */
     public void setFilterColumns(String[] columnNames) {
         getShowFilterDialogAction().getFilterDialog().setColumnNames(columnNames);
@@ -905,7 +1000,8 @@ public class TimeGraphCombo extends Composite {
     /**
      * Sets the time graph presentation provider used by this time graph combo.
      *
-     * @param timeGraphProvider the time graph provider
+     * @param timeGraphProvider
+     *            the time graph provider
      */
     public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider) {
         fTimeGraphViewer.setTimeGraphProvider(timeGraphProvider);
@@ -914,7 +1010,9 @@ public class TimeGraphCombo extends Composite {
     /**
      * Sets or clears the input for this time graph combo.
      *
-     * @param input the input of this time graph combo, or <code>null</code> if none
+     * @param input
+     *            the input of this time graph combo, or <code>null</code> if
+     *            none
      */
     public void setInput(Object input) {
         fInhibitTreeSelection = true;
@@ -935,8 +1033,12 @@ public class TimeGraphCombo extends Composite {
         getDisplay().asyncExec(new Runnable() {
             @Override
             public void run() {
+                if (isDisposed()) {
+                    return;
+                }
                 alignTreeItems(true);
-            }});
+            }
+        });
     }
 
     /**
@@ -951,14 +1053,16 @@ public class TimeGraphCombo extends Composite {
     /**
      * Sets or clears the list of links to display on this combo
      *
-     * @param links the links to display in this time graph combo
+     * @param links
+     *            the links to display in this time graph combo
      */
     public void setLinks(List<ILinkEvent> links) {
         fTimeGraphViewer.setLinks(links);
     }
 
     /**
-     * @param filter The filter object to be attached to the view
+     * @param filter
+     *            The filter object to be attached to the view
      */
     public void addFilter(@NonNull ViewerFilter filter) {
         fInhibitTreeSelection = true;
@@ -971,7 +1075,8 @@ public class TimeGraphCombo extends Composite {
     }
 
     /**
-     * @param filter The filter object to be removed from the view
+     * @param filter
+     *            The filter object to be removed from the view
      */
     public void removeFilter(@NonNull ViewerFilter filter) {
         fInhibitTreeSelection = true;
@@ -987,7 +1092,7 @@ public class TimeGraphCombo extends Composite {
      * Returns this viewer's filters.
      *
      * @return an array of viewer filters
-     * @since 2.0
+     * @since 1.2
      */
     public @NonNull ViewerFilter[] getFilters() {
         return fTimeGraphViewer.getFilters();
@@ -999,7 +1104,7 @@ public class TimeGraphCombo extends Composite {
      *
      * @param filters
      *            an array of viewer filters, or null
-     * @since 2.0
+     * @since 1.2
      */
     public void setFilters(@NonNull ViewerFilter[] filters) {
         fInhibitTreeSelection = true;
@@ -1020,7 +1125,8 @@ public class TimeGraphCombo extends Composite {
     }
 
     /**
-     * Refreshes this time graph completely with information freshly obtained from its model.
+     * Refreshes this time graph completely with information freshly obtained
+     * from its model.
      */
     public void refresh() {
         fInhibitTreeSelection = true;
@@ -1039,7 +1145,8 @@ public class TimeGraphCombo extends Composite {
     /**
      * Adds a listener for selection changes in this time graph combo.
      *
-     * @param listener a selection listener
+     * @param listener
+     *            a selection listener
      */
     public void addSelectionListener(ITimeGraphSelectionListener listener) {
         SelectionListenerWrapper listenerWrapper = new SelectionListenerWrapper(listener);
@@ -1051,7 +1158,8 @@ public class TimeGraphCombo extends Composite {
     /**
      * Removes the given selection listener from this time graph combo.
      *
-     * @param listener a selection changed listener
+     * @param listener
+     *            a selection changed listener
      */
     public void removeSelectionListener(ITimeGraphSelectionListener listener) {
         SelectionListenerWrapper listenerWrapper = fSelectionListenerMap.remove(listener);
@@ -1062,11 +1170,36 @@ public class TimeGraphCombo extends Composite {
     /**
      * Sets the current selection for this time graph combo.
      *
-     * @param selection the new selection
+     * @param selection
+     *            the new selection
      */
     public void setSelection(ITimeGraphEntry selection) {
         fTimeGraphViewer.setSelection(selection);
-        fInhibitTreeSelection = true; // block the tree selection changed listener
+        setSelectionInTree(selection);
+    }
+
+    /**
+     * Sets the current selection for this time graph combo and reveal it if
+     * needed.
+     *
+     * @param selection
+     *            The new selection
+     * @since 2.0
+     */
+    public void selectAndReveal(@NonNull ITimeGraphEntry selection) {
+        fTimeGraphViewer.selectAndReveal(selection);
+        setSelectionInTree(selection);
+    }
+
+    /**
+     * Select the entry in the tree structure
+     *
+     * @param selection
+     *            The new selection
+     */
+    private void setSelectionInTree(ITimeGraphEntry selection) {
+        fInhibitTreeSelection = true; // block the tree selection changed
+                                      // listener
         if (selection != null) {
             StructuredSelection structuredSelection = new StructuredSelection(selection);
             fTreeViewer.setSelection(structuredSelection);
@@ -1111,6 +1244,18 @@ public class TimeGraphCombo extends Composite {
         return fTimeGraphViewer.getAutoExpandLevel();
     }
 
+    /**
+     * Get the expanded state of an entry.
+     *
+     * @param entry
+     *            The entry
+     * @return true if the entry is expanded, false if collapsed
+     * @since 2.0
+     */
+    public boolean getExpandedState(ITimeGraphEntry entry) {
+        return fTimeGraphViewer.getExpandedState(entry);
+    }
+
     /**
      * Set the expanded state of an entry
      *
@@ -1176,7 +1321,8 @@ public class TimeGraphCombo extends Composite {
 
     private int getItemHeight(final Tree tree, boolean force) {
         /*
-         * Bug in Linux.  The method getItemHeight doesn't always return the correct value.
+         * Bug in Linux. The method getItemHeight doesn't always return the
+         * correct value.
          */
         if (fLinuxItemHeight >= 0 && System.getProperty("os.name").contains("Linux")) { //$NON-NLS-1$ //$NON-NLS-2$
             if (fLinuxItemHeight != 0 && !force) {
@@ -1207,12 +1353,14 @@ public class TimeGraphCombo extends Composite {
                 tree.addPaintListener(paintListener);
             }
         } else {
-            fLinuxItemHeight = -1; // Not Linux, don't perform os.name check anymore
+            fLinuxItemHeight = -1; // Not Linux, don't perform os.name check
+                                   // anymore
         }
         return tree.getItemHeight();
     }
 
     private void alignTreeItems(boolean refreshExpandedItems) {
+
         // align the tree top item with the time graph top item
         Tree tree = fTreeViewer.getTree();
         List<TreeItem> treeItems = getVisibleExpandedItems(tree, refreshExpandedItems);
@@ -1222,7 +1370,6 @@ public class TimeGraphCombo extends Composite {
         }
         TreeItem item = treeItems.get(topIndex);
         tree.setTopItem(item);
-
         /*
          * In GTK3, the bounds of the tree items are only sure to be correct
          * after the tree has been painted.
@@ -1233,16 +1380,6 @@ public class TimeGraphCombo extends Composite {
                 tree.removePaintListener(this);
                 doAlignTreeItems();
                 redraw();
-                /*
-                 * Bug in GTK. Calling setTopItem() can scroll to the wrong item
-                 * when the 'tree view' is dirty. Set it again once it is clean.
-                 */
-                if (SWT.getPlatform().equals("gtk")) { //$NON-NLS-1$
-                    TreeItem topItem = tree.getTopItem();
-                    tree.getDisplay().asyncExec(() -> {
-                        tree.setTopItem(topItem);
-                    });
-                }
             }
         });
         /* Make sure the paint event is triggered. */
@@ -1297,8 +1434,9 @@ public class TimeGraphCombo extends Composite {
 
     private Rectangle alignTreeItem(TreeItem item, Rectangle bounds, TreeItem nextItem) {
         /*
-         * Bug in Linux. The method getBounds doesn't always return the correct height.
-         * Use the difference of y position between items to calculate the height.
+         * Bug in Linux. The method getBounds doesn't always return the correct
+         * height. Use the difference of y position between items to calculate
+         * the height.
          */
         Rectangle nextBounds = nextItem.getBounds();
         Integer itemHeight = nextBounds.y - bounds.y;
This page took 0.033457 seconds and 5 git commands to generate.