X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=tmf%2Forg.eclipse.tracecompass.tmf.ui%2Fsrc%2Forg%2Feclipse%2Ftracecompass%2Ftmf%2Fui%2Fwidgets%2Ftimegraph%2FTimeGraphCombo.java;h=0c27d2515b296c2fc8907e5f5217a580e6fa2457;hb=8cbbdf920cb9806aa12adf529138ac1d9154e127;hp=11d916eb1c981c7da44991ab12df84dafc10243e;hpb=83d0971d465d113d9a7ec857349c65cab57b549f;p=deliverable%2Ftracecompass.git diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphCombo.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphCombo.java index 11d916eb1c..0c27d2515b 100644 --- a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphCombo.java +++ b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphCombo.java @@ -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 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 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 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 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 null if none + * @param input + * the input of this time graph combo, or null 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 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 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;