TMF: Add an abstract tree viewer class
authorGeneviève Bastien <gbastien+lttng@versatic.net>
Mon, 17 Feb 2014 15:26:19 +0000 (10:26 -0500)
committerGenevieve Bastien <gbastien+lttng@versatic.net>
Tue, 25 Feb 2014 21:12:42 +0000 (16:12 -0500)
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 <gbastien+lttng@versatic.net>
Reviewed-on: https://git.eclipse.org/r/22184
Tested-by: Hudson CI
Reviewed-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
IP-Clean: Bernd Hufmann <bernd.hufmann@ericsson.com>
Tested-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
org.eclipse.linuxtools.tmf.ui/META-INF/MANIFEST.MF
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/AbstractTmfTreeViewer.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/ITmfTreeColumnDataProvider.java [new file with mode: 0755]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/ITmfTreeViewerEntry.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/TmfTreeColumnData.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/tree/TmfTreeViewerEntry.java [new file with mode: 0644]

index 600c51fa3ae42731d707b0eff295e88a3d87255e..e121d5f524ed4324f7e59e1e64852ccddeab94b3 100644 (file)
@@ -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 (file)
index 0000000..99dc163
--- /dev/null
@@ -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<? extends ITmfTreeViewerEntry> 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<TmfTreeColumnData> 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<TmfTreeColumnData> 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:
+     *
+     * <pre>
+     * getTreeViewer().addSelectionChangeListener(new ISelectionChangedListener() {
+     *     &#064;Override
+     *     public void selectionChanged(SelectionChangedEvent event) {
+     *         if (event.getSelection() instanceof IStructuredSelection) {
+     *             Object selection = ((IStructuredSelection) event.getSelection()).getFirstElement();
+     *             if (selection instanceof ITmfTreeViewerEntry) {
+     *                 // Do something
+     *             }
+     *         }
+     *     }
+     * });
+     * </pre>
+     *
+     * @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
+     *            <code>true</code> if this time range is for a selection,
+     *            <code>false</code> 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<ITmfTreeViewerEntry> 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 <code>null</code>. 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
+     *            <code>true</code> if this time range is for a selection,
+     *            <code>false</code> for the visible time range
+     * @return The list of entries to display or <code>null</code> if no update
+     *         necessary
+     */
+    protected abstract List<ITmfTreeViewerEntry> 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 (executable)
index 0000000..26a62da
--- /dev/null
@@ -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<TmfTreeColumnData> 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 (file)
index 0000000..7abe667
--- /dev/null
@@ -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 <code>null</code> if it has none.
+     *
+     * @return the parent element, or <code>null</code> if it has none
+     */
+    ITmfTreeViewerEntry getParent();
+
+    /**
+     * Returns whether this entry has children.
+     *
+     * @return <code>true</code> if the given element has children,
+     *  and <code>false</code> if it has no children
+     */
+    boolean hasChildren();
+
+    /**
+     * Returns the child elements of this entry.
+     *
+     * @return an array of child elements
+     */
+    List<? extends ITmfTreeViewerEntry> 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 (file)
index 0000000..3f3053b
--- /dev/null
@@ -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 <code>null</code>, 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 <code>null</code> 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 (file)
index 0000000..b79ae72
--- /dev/null
@@ -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<ITmfTreeViewerEntry> 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<ITmfTreeViewerEntry> 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);
+    }
+
+}
This page took 0.035569 seconds and 5 git commands to generate.