From c0188b25658f23420d6a12d9af7ad7d817dc966d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Genevi=C3=A8ve=20Bastien?= Date: Mon, 17 Feb 2014 10:26:19 -0500 Subject: [PATCH] TMF: Add an abstract tree viewer class MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Provides default functionalities for all tree viewers, like how to set the column data, basic classes to manage the content of the tree, provide easy abstract method to fetch the data to fill the tree. Change-Id: I0b19027f24f9e612304bb89f32a03f8c67d8edf7 Signed-off-by: Geneviève Bastien Reviewed-on: https://git.eclipse.org/r/22184 Tested-by: Hudson CI Reviewed-by: Bernd Hufmann IP-Clean: Bernd Hufmann Tested-by: Bernd Hufmann --- .../META-INF/MANIFEST.MF | 1 + .../viewers/tree/AbstractTmfTreeViewer.java | 473 ++++++++++++++++++ .../tree/ITmfTreeColumnDataProvider.java | 33 ++ .../ui/viewers/tree/ITmfTreeViewerEntry.java | 54 ++ .../ui/viewers/tree/TmfTreeColumnData.java | 266 ++++++++++ .../ui/viewers/tree/TmfTreeViewerEntry.java | 99 ++++ 6 files changed, 926 insertions(+) create mode 100644 org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/AbstractTmfTreeViewer.java create mode 100755 org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/ITmfTreeColumnDataProvider.java create mode 100644 org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/ITmfTreeViewerEntry.java create mode 100644 org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/TmfTreeColumnData.java create mode 100644 org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/TmfTreeViewerEntry.java diff --git a/org.eclipse.linuxtools.tmf.ui/META-INF/MANIFEST.MF b/org.eclipse.linuxtools.tmf.ui/META-INF/MANIFEST.MF index 600c51fa3a..e121d5f524 100644 --- a/org.eclipse.linuxtools.tmf.ui/META-INF/MANIFEST.MF +++ b/org.eclipse.linuxtools.tmf.ui/META-INF/MANIFEST.MF @@ -39,6 +39,7 @@ Export-Package: org.eclipse.linuxtools.internal.tmf.ui;x-friends:="org.eclipse.l org.eclipse.linuxtools.tmf.ui.viewers.events, org.eclipse.linuxtools.tmf.ui.viewers.statistics, org.eclipse.linuxtools.tmf.ui.viewers.statistics.model, + org.eclipse.linuxtools.tmf.ui.viewers.tree, org.eclipse.linuxtools.tmf.ui.viewers.xycharts;x-internal:=true, org.eclipse.linuxtools.tmf.ui.viewers.xycharts.barcharts;x-internal:=true, org.eclipse.linuxtools.tmf.ui.viewers.xycharts.linecharts;x-internal:=true, diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/AbstractTmfTreeViewer.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/AbstractTmfTreeViewer.java new file mode 100644 index 0000000000..99dc163944 --- /dev/null +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/AbstractTmfTreeViewer.java @@ -0,0 +1,473 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.tmf.ui.viewers.tree; + +import java.util.List; + +import org.eclipse.jface.viewers.AbstractTreeViewer; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ITableColorProvider; +import org.eclipse.jface.viewers.ITableFontProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal; +import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; +import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; +import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; +import org.eclipse.linuxtools.tmf.ui.viewers.TmfTimeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; + +/** + * Abstract class for viewers who will display data using a TreeViewer. It + * automatically synchronizes with time information of the UI. It also + * implements some common functionalities for all tree viewer, such as managing + * the column data, content initialization and update. The viewer implementing + * this does not have to worry about whether some code runs in the UI thread or + * not. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public abstract class AbstractTmfTreeViewer extends TmfTimeViewer { + + private final TreeViewer fTreeViewer; + + // ------------------------------------------------------------------------ + // Internal classes + // ------------------------------------------------------------------------ + + /* The elements of the tree viewer are of type ITmfTreeViewerEntry */ + private class TreeContentProvider implements ITreeContentProvider { + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + @Override + public Object[] getElements(Object inputElement) { + if (inputElement != null) { + try { + return ((List) inputElement).toArray(new ITmfTreeViewerEntry[0]); + } catch (ClassCastException e) { + } + } + return new ITmfTreeViewerEntry[0]; + } + + @Override + public Object[] getChildren(Object parentElement) { + ITmfTreeViewerEntry entry = (ITmfTreeViewerEntry) parentElement; + List children = entry.getChildren(); + return children.toArray(new ITmfTreeViewerEntry[children.size()]); + } + + @Override + public Object getParent(Object element) { + ITmfTreeViewerEntry entry = (ITmfTreeViewerEntry) element; + return entry.getParent(); + } + + @Override + public boolean hasChildren(Object element) { + ITmfTreeViewerEntry entry = (ITmfTreeViewerEntry) element; + return entry.hasChildren(); + } + + } + + /** + * Base class to provide the labels for the tree viewer. Views extending + * this class typically need to override the getColumnText method if they + * have more than one column to display. It also allows to change the font + * and colors of the cells. + */ + protected static class TreeLabelProvider implements ITableLabelProvider, ITableFontProvider, ITableColorProvider { + + @Override + public void addListener(ILabelProviderListener listener) { + } + + @Override + public void dispose() { + } + + @Override + public boolean isLabelProperty(Object element, String property) { + return false; + } + + @Override + public void removeListener(ILabelProviderListener listener) { + } + + @Override + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + if ((element instanceof ITmfTreeViewerEntry) && (columnIndex == 0)) { + ITmfTreeViewerEntry entry = (ITmfTreeViewerEntry) element; + return entry.getName(); + } + return new String(); + } + + @Override + public Color getForeground(Object element, int columnIndex) { + return Display.getCurrent().getSystemColor(SWT.COLOR_LIST_FOREGROUND); + } + + @Override + public Color getBackground(Object element, int columnIndex) { + return Display.getCurrent().getSystemColor(SWT.COLOR_LIST_BACKGROUND); + } + + @Override + public Font getFont(Object element, int columnIndex) { + return null; + } + + } + + // ------------------------------------------------------------------------ + // Constructors and initialization methods + // ------------------------------------------------------------------------ + + /** + * Constructor + * + * @param parent + * The parent composite that holds this viewer + * @param allowMultiSelect + * Whether multiple selections are allowed + */ + public AbstractTmfTreeViewer(Composite parent, boolean allowMultiSelect) { + super(parent); + + int flags = SWT.FULL_SELECTION | SWT.H_SCROLL; + if (allowMultiSelect) { + flags |= SWT.MULTI; + } + + /* Build the tree viewer part of the view */ + fTreeViewer = new TreeViewer(parent, flags); + fTreeViewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS); + final Tree tree = fTreeViewer.getTree(); + tree.setHeaderVisible(true); + tree.setLinesVisible(true); + fTreeViewer.setContentProvider(new TreeContentProvider()); + fTreeViewer.setLabelProvider(new TreeLabelProvider()); + List columns = getColumnDataProvider().getColumnData(); + this.setTreeColumns(columns); + } + + /** + * Get the column data provider that will contain the list of columns to be + * part of this viewer. It is called once during the constructor. + * + * @return The tree column data provider for this viewer. + */ + protected abstract ITmfTreeColumnDataProvider getColumnDataProvider(); + + /** + * Sets the tree columns for this tree viewer + * + * @param columns + * The tree column data + */ + public void setTreeColumns(final List columns) { + boolean hasPercentProvider = false; + for (final TmfTreeColumnData columnData : columns) { + columnData.createColumn(fTreeViewer); + hasPercentProvider |= (columnData.getPercentageProvider() != null); + } + + if (hasPercentProvider) { + /* + * Handler that will draw bar charts in the cell using a percentage + * value. + */ + fTreeViewer.getTree().addListener(SWT.EraseItem, new Listener() { + @Override + public void handleEvent(Event event) { + if (columns.get(event.index).getPercentageProvider() != null) { + + double percentage = columns.get(event.index).getPercentageProvider().getPercentage(event.item.getData()); + if (percentage == 0) { // No bar to draw + return; + } + + if ((event.detail & SWT.SELECTED) > 0) { + /* + * The item is selected. Draw our own background to + * avoid overwriting the bar. + */ + event.gc.fillRectangle(event.x, event.y, event.width, event.height); + event.detail &= ~SWT.SELECTED; + } + + int barWidth = (int) ((fTreeViewer.getTree().getColumn(event.index).getWidth() - 8) * percentage); + int oldAlpha = event.gc.getAlpha(); + Color oldForeground = event.gc.getForeground(); + Color oldBackground = event.gc.getBackground(); + /* + * Draws a transparent gradient rectangle from the color + * of foreground and background. + */ + event.gc.setAlpha(64); + event.gc.setForeground(event.item.getDisplay().getSystemColor(SWT.COLOR_BLUE)); + event.gc.setBackground(event.item.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + event.gc.fillGradientRectangle(event.x, event.y, barWidth, event.height, true); + event.gc.drawRectangle(event.x, event.y, barWidth, event.height); + /* Restores old values */ + event.gc.setForeground(oldForeground); + event.gc.setBackground(oldBackground); + event.gc.setAlpha(oldAlpha); + event.detail &= ~SWT.BACKGROUND; + } + } + }); + } + } + + /** + * Set the label provider that will fill the columns of the tree viewer + * + * @param labelProvider + * The label provider to fill the columns + */ + protected void setLabelProvider(IBaseLabelProvider labelProvider) { + fTreeViewer.setLabelProvider(labelProvider); + } + + /** + * Get the tree viewer object + * + * @return The tree viewer object displayed by this viewer + */ + protected TreeViewer getTreeViewer() { + return fTreeViewer; + } + + // ------------------------------------------------------------------------ + // ITmfViewer + // ------------------------------------------------------------------------ + + @Override + public Control getControl() { + return fTreeViewer.getControl(); + } + + @Override + public void refresh() { + Tree tree = fTreeViewer.getTree(); + tree.setRedraw(false); + fTreeViewer.refresh(); + fTreeViewer.expandAll(); + tree.setRedraw(true); + } + + @Override + public void loadTrace(ITmfTrace trace) { + super.loadTrace(trace); + Thread thread = new Thread() { + @Override + public void run() { + initializeDataSource(); + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + clearContent(); + updateContent(getWindowStartTime(), getWindowEndTime(), false); + } + }); + } + }; + thread.start(); + } + + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + + /** + * Add a selection listener to the tree viewer. This will be called when the + * selection changes and contain all the selected items. + * + * The selection change listener can be used like this: + * + *
+     * getTreeViewer().addSelectionChangeListener(new ISelectionChangedListener() {
+     *     @Override
+     *     public void selectionChanged(SelectionChangedEvent event) {
+     *         if (event.getSelection() instanceof IStructuredSelection) {
+     *             Object selection = ((IStructuredSelection) event.getSelection()).getFirstElement();
+     *             if (selection instanceof ITmfTreeViewerEntry) {
+     *                 // Do something
+     *             }
+     *         }
+     *     }
+     * });
+     * 
+ * + * @param listener + * The {@link ISelectionChangedListener} + */ + public void addSelectionChangeListener(ISelectionChangedListener listener) { + fTreeViewer.addSelectionChangedListener(listener); + } + + /** + * Method called when the trace is loaded, to initialize any data once the + * trace has been set, but before the first call to update the content of + * the viewer. + */ + protected void initializeDataSource() { + + } + + /** + * Clears the current content of the viewer. + */ + protected void clearContent() { + fTreeViewer.setInput(null); + } + + /** + * Requests an update of the viewer's content in a given time range or + * selection time range. An extra parameter defines whether these times + * correspond to the selection or the visible range, as the viewer may + * update differently in those cases. + * + * @param start + * The start time of the requested content + * @param end + * The end time of the requested content + * @param isSelection + * true if this time range is for a selection, + * false for the visible time range + */ + protected void updateContent(final long start, final long end, final boolean isSelection) { + Thread thread = new Thread() { + @Override + public void run() { + final List entries = updateElements(start, end, isSelection); + /* Set the input in main thread only if it didn't change */ + if (entries != null) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if (entries != fTreeViewer.getInput()) { + fTreeViewer.setInput(entries); + } else { + fTreeViewer.refresh(); + } + // FIXME should add a bit of padding + for (TreeColumn column : fTreeViewer.getTree().getColumns()) { + column.pack(); + } + } + }); + } + } + }; + thread.start(); + } + + /** + * Update the entries to the given start/end time. An extra parameter + * defines whether these times correspond to the selection or the visible + * range, as the viewer may update differently in those cases. If no update + * is necessary, the method should return null. To empty the + * tree, an empty list should be returned. + * + * This method is not called in the UI thread when using the default viewer + * content update. Resource-intensive calculations here should not block the + * UI. + * + * @param start + * The start time of the requested content + * @param end + * The end time of the requested content + * @param isSelection + * true if this time range is for a selection, + * false for the visible time range + * @return The list of entries to display or null if no update + * necessary + */ + protected abstract List updateElements(long start, long end, boolean isSelection); + + /** + * Get the current input displayed by the viewer + * + * @return The input of the tree viewer + */ + protected Object getInput() { + return fTreeViewer.getInput(); + } + + // ------------------------------------------------------------------------ + // Signal Handler + // ------------------------------------------------------------------------ + + /** + * Signal handler for handling of the time synch signal. The times + * correspond to the selection by the user, not the visible time range. + * + * @param signal + * The time synch signal {@link TmfTimeSynchSignal} + */ + @Override + @TmfSignalHandler + public void selectionRangeUpdated(TmfTimeSynchSignal signal) { + super.selectionRangeUpdated(signal); + if ((signal.getSource() != this) && (getTrace() != null)) { + updateContent(this.getSelectionBeginTime(), this.getSelectionEndTime(), true); + } + } + + /** + * Signal handler for handling of the time range synch signal. This time + * range is the visible zone of the view. + * + * @param signal + * The time range synch signal {@link TmfRangeSynchSignal} + */ + @Override + @TmfSignalHandler + public void timeRangeUpdated(TmfRangeSynchSignal signal) { + super.timeRangeUpdated(signal); + updateContent(this.getWindowStartTime(), this.getWindowEndTime(), false); + } + +} diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/ITmfTreeColumnDataProvider.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/ITmfTreeColumnDataProvider.java new file mode 100755 index 0000000000..26a62da2ed --- /dev/null +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/ITmfTreeColumnDataProvider.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial API and Implementation + * Geneviève Bastien - Moved class and adapted it to abstract tree viewer + *******************************************************************************/ + +package org.eclipse.linuxtools.tmf.ui.viewers.tree; + +import java.util.List; + +/** + * Basic methods that must be implemented in a column data provider. Tree + * viewers will use class implementing this to populate the columns. + * + * @author Mathieu Denis + * @since 3.0 + */ +public interface ITmfTreeColumnDataProvider { + + /** + * Return a list of the column created for the view + * + * @return columns list + */ + List getColumnData(); +} \ No newline at end of file diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/ITmfTreeViewerEntry.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/ITmfTreeViewerEntry.java new file mode 100644 index 0000000000..7abe667484 --- /dev/null +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/ITmfTreeViewerEntry.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.tmf.ui.viewers.tree; + +import java.util.List; + +/** + * Interface for an entry (row) in a TMF tree viewer + * + * @author Geneviève Bastien + * @since 3.0 + */ +public interface ITmfTreeViewerEntry { + + /** + * Returns the parent of this entry, or null if it has none. + * + * @return the parent element, or null if it has none + */ + ITmfTreeViewerEntry getParent(); + + /** + * Returns whether this entry has children. + * + * @return true if the given element has children, + * and false if it has no children + */ + boolean hasChildren(); + + /** + * Returns the child elements of this entry. + * + * @return an array of child elements + */ + List getChildren(); + + /** + * Returns the name of this entry. + * + * @return the entry name + */ + String getName(); + +} diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/TmfTreeColumnData.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/TmfTreeColumnData.java new file mode 100644 index 0000000000..3f3053b798 --- /dev/null +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/TmfTreeColumnData.java @@ -0,0 +1,266 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mathieu Denis - Initial Implementation and API (in TmfBaseColumnData of + * statistics framework) + * Bernd Hufmann - Added Annotations + * Geneviève Bastien - Moved TmfBaseColumnData to this class and adapted + * it for the abstract tree viewer + *******************************************************************************/ + +package org.eclipse.linuxtools.tmf.ui.viewers.tree; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.Tree; + +/** + * Represents a column in an abstract tree viewer. It allows to define the + * column's characteristics: text, width, alignment, tooltip, comparators, + * percent providers, whether the column is movable, etc. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfTreeColumnData { + /** Name of the column. */ + private final String fText; + /** Width of the column. */ + private int fWidth = -1; + /** Alignment of the column. */ + private int fAlignment = SWT.LEAD; + /** Tooltip of the column. */ + private String fTooltip = null; + /** Used to sort elements of this column. If null, column is not sortable. */ + private ViewerComparator fComparator = null; + /** Whether the column is movable */ + private boolean fMovable = false; + /** Used to draw bar charts in this column. Can be null. */ + private ITmfColumnPercentageProvider fPercentageProvider = null; + + /** Used to draw bar charts in columns. */ + public interface ITmfColumnPercentageProvider { + + /** + * Percentage provider. Returns a percentage (between 0 and 100) from + * the given object. The object is usually an entry (a line of the tree + * viewer). + * + * @param data + * The data object corresponding to a line in the tree. + * @return The value as a percentage (between 0 and 100) + */ + public double getPercentage(Object data); + } + + /** + * Constructor with parameters + * + * @param text + * Text of the column. The name will be shown at the top of the + * column. + */ + public TmfTreeColumnData(String text) { + fText = text; + } + + /** + * Get the header text of a column + * + * @return The header text + */ + public String getText() { + return fText; + } + + /** + * Get the width of the column + * + * @return The column width + */ + public int getWidth() { + return fWidth; + } + + /** + * Get the alignment of the column + * + * @return The alignment (for example SWT.LEAD, SWT.RIGHT, etc) + */ + public int getAlignment() { + return fAlignment; + } + + /** + * Get the tooltip text to go with this column + * + * @return The tooltip text + */ + public String getTooltip() { + return fTooltip; + } + + /** + * Get the comparator used to sort columns. If null, then the + * column is not sortable + * + * @return The column comparator + */ + public ViewerComparator getComparator() { + return fComparator; + } + + /** + * Get the percentage provider for this column. This will allow to draw a + * bar chart inside the cells of this columns + * + * @return The percentage provider + */ + public ITmfColumnPercentageProvider getPercentageProvider() { + return fPercentageProvider; + } + + /** + * Return whether the column is movable or not + * + * @return True if column can be moved, false otherwise. + */ + public boolean isMovable() { + return fMovable; + } + + /** + * Set the width of the column. If not set, -1 is used. + * + * @param width + * Width of the column. Use -1 for tree viewer's default + * behavior. + */ + public void setWidth(int width) { + fWidth = width; + } + + /** + * Set the alignment of this column. If not set, default value is SWT.LEAD. + * + * @param alignment + * Alignment of the column. For example, SWT.LEAD, SWT.RIGHT, + * SWT.LEFT + */ + public void setAlignment(int alignment) { + fAlignment = alignment; + } + + /** + * Set the tooltip associated with this column + * + * @param tooltip + * the tooltip text + */ + public void setTooltip(String tooltip) { + fTooltip = tooltip; + } + + /** + * Set the comparator used to sort the column + * + * @param comparator + * The comparator. Use null to not sort the column. + */ + public void setComparator(ViewerComparator comparator) { + fComparator = comparator; + } + + /** + * Set the percentage provider that will provide a percentage value to draw + * a bar chart inside the cells of this column + * + * @param percentProvider + * The percentage provider + */ + public void setPercentageProvider(ITmfColumnPercentageProvider percentProvider) { + fPercentageProvider = percentProvider; + } + + /** + * Set whether the column can be moved in the tree viewer. Default is false. + * + * @param movable + * true if the column can be moved, false otherwise + */ + public void setMovable(boolean movable) { + fMovable = movable; + } + + /** + * Create a TreeColumn with this column's data and adds it to a {@link Tree} + * + * @param treeViewer + * The {@link TreeViewer} object to add the column to + * @return The newly created {@link TreeViewerColumn} + */ + @NonNull + public TreeViewerColumn createColumn(final TreeViewer treeViewer) { + final TreeViewerColumn column = new TreeViewerColumn(treeViewer, getAlignment()); + final TmfTreeColumnData columnData = this; + column.getColumn().setText(getText()); + if (getWidth() != -1) { + column.getColumn().setWidth(getWidth()); + } + if (getTooltip() != null) { + column.getColumn().setToolTipText(getTooltip()); + } + column.getColumn().setMoveable(isMovable()); + + /* Add the comparator to sort the column */ + if (getComparator() != null) { + column.getColumn().addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + + if (treeViewer.getTree().getSortDirection() == SWT.UP || treeViewer.getTree().getSortColumn() != column.getColumn()) { + /* + * Puts the descendant order if the old order was up + * or if the selected column has changed. + */ + treeViewer.setComparator(columnData.getComparator()); + treeViewer.getTree().setSortDirection(SWT.DOWN); + } else { + ViewerComparator reverseComparator; + /* Initializes the reverse comparator. */ + reverseComparator = new ViewerComparator() { + @Override + public int compare(Viewer viewer, Object e1, Object + e2) { + return -1 * columnData.getComparator().compare(viewer, e1, e2); + } + }; + + /* + * Puts the ascendant ordering if the selected + * column hasn't changed. + */ + treeViewer.setComparator(reverseComparator); + treeViewer.getTree().setSortDirection(SWT.UP); + } + treeViewer.getTree().setSortColumn(column.getColumn()); + } + }); + } + + return column; + } +} diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/TmfTreeViewerEntry.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/TmfTreeViewerEntry.java new file mode 100644 index 0000000000..b79ae72b73 --- /dev/null +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/TmfTreeViewerEntry.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.tmf.ui.viewers.tree; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Basic implementation of an entry for the TMF tree viewer. A name is all that is needed for this entry. + * + * @author Geneviève Bastien + * @since 3.0 + */ +public class TmfTreeViewerEntry implements ITmfTreeViewerEntry { + + /** Entry's parent */ + private ITmfTreeViewerEntry fParent = null; + + /** List of child entries */ + private final List fChildren = new CopyOnWriteArrayList<>(); + + /** Name of this entry (default text to show in first column) */ + private String fName; + + /** + * Constructor + * + * @param name + * The name of this entry + */ + public TmfTreeViewerEntry(String name) { + fName = name; + } + + // --------------------------------------------- + // Getters and setters + // --------------------------------------------- + + @Override + public ITmfTreeViewerEntry getParent() { + return fParent; + } + + /** + * Sets the entry's parent + * + * @param entry The new parent entry + */ + protected void setParent(ITmfTreeViewerEntry entry) { + fParent = entry; + } + + @Override + public boolean hasChildren() { + return fChildren.size() > 0; + } + + @Override + public List getChildren() { + return fChildren; + } + + @Override + public String getName() { + return fName; + } + + /** + * Update the entry name + * + * @param name + * the updated entry name + */ + public void setName(String name) { + fName = name; + } + + /** + * Add a child entry to this one + * + * @param child + * The child entry + */ + public void addChild(TmfTreeViewerEntry child) { + child.fParent = this; + fChildren.add(child); + } + +} -- 2.34.1