timing.ui: add Export to TSV to tables and statistics
authorMatthew Khouzam <matthew.khouzam@ericsson.com>
Wed, 28 Sep 2016 17:55:51 +0000 (13:55 -0400)
committerMatthew Khouzam <matthew.khouzam@ericsson.com>
Mon, 3 Oct 2016 14:05:20 +0000 (10:05 -0400)
This allows exporting to tsv files.

Testing is done with reflection to avoid native dialog issues.

Some issues are present:
* In Linux, an invisible column is added at the end,
while this seems ok, it makes the output inconsistent
between Windows and Linux.
* SWTBot cannot test native windows, therefore, the user actual
actions are untested. All possible logic has been moved
elsewhere to accomodate.
* Tree and Table have no common parents, this will incur code
duplication due to their similarities.
* In Linux, tooltips are not well handled in menu items.

Change-Id: I506d0e7e50bd5ce8ecbd44675a0c404ab2dda431
Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/82111
Reviewed-by: Hudson CI
Reviewed-by: Genevieve Bastien <gbastien+lttng@versatic.net>
analysis/org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests/src/org/eclipse/tracecompass/analysis/os/linux/ui/swtbot/tests/latency/SystemCallLatencyStatisticsTableAnalysisTest.java
analysis/org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests/src/org/eclipse/tracecompass/analysis/os/linux/ui/swtbot/tests/latency/SystemCallLatencyTableAnalysisTest.java
analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/analysis/timing/ui/views/segmentstore/statistics/AbstractSegmentStoreStatisticsView.java
analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/analysis/timing/ui/views/segmentstore/table/AbstractSegmentStoreTableView.java
analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/internal/analysis/timing/ui/views/segmentstore/ExportToTsvAction.java [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/internal/analysis/timing/ui/views/segmentstore/Messages.java [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/internal/analysis/timing/ui/views/segmentstore/messages.properties [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/AbstractTmfTreeViewer.java

index 1e41b80c446bba2c6f9df6fdefa6edf67402da61..03b6c2827c10253ecb07b5c09fa1410bd650847e 100644 (file)
@@ -14,15 +14,21 @@ package org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests.latency;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.List;
 
 import org.apache.log4j.ConsoleAppender;
 import org.apache.log4j.Logger;
 import org.apache.log4j.SimpleLayout;
 import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
 import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
 import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
@@ -30,8 +36,10 @@ import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
 import org.eclipse.swtbot.swt.finder.results.BoolResult;
 import org.eclipse.swtbot.swt.finder.results.Result;
 import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu;
 import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
 import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.statistics.AbstractSegmentStoreStatisticsView;
 import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.latency.statistics.SystemCallLatencyStatisticsView;
 import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace;
 import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.ConditionHelpers;
@@ -159,9 +167,15 @@ public class SystemCallLatencyStatisticsTableAnalysisTest {
      *
      * @throws IOException
      *             trace not found?
+     * @throws SecurityException
+     *             Reflection error
+     * @throws NoSuchMethodException
+     *             Reflection error
+     * @throws IllegalArgumentException
+     *             Reflection error
      */
     @Test
-    public void testWithTrace() throws IOException {
+    public void testWithTrace() throws IOException, NoSuchMethodException, SecurityException, IllegalArgumentException {
         String tracePath;
         tracePath = FileLocator.toFileURL(CtfTestTrace.ARM_64_BIT_HEADER.getTraceURL()).getPath();
         SWTWorkbenchBot bot = new SWTWorkbenchBot();
@@ -185,11 +199,40 @@ public class SystemCallLatencyStatisticsTableAnalysisTest {
         validate(treeItem.getNode(3), "poll", "6.300 µs", "6.800 µs", "6.550 µs", "---", "2");
         validate(treeItem.getNode(5), "set_tid_address", "2.300 µs", "2.300 µs", "2.300 µs", "---", "1");
         validate(treeItem.getNode(7), "pipe", "27.900 µs", "29.700 µs", "28.800 µs", "---", "2");
+        testToTsv(view);
+        SWTBotMenu menuBot = view.viewMenu().menu("Export to TSV");
+        assertTrue(menuBot.isEnabled());
+        assertTrue(menuBot.isVisible());
 
         bot.closeAllEditors();
         SWTBotUtils.deleteProject(PROJECT_NAME, bot);
     }
 
+    private static void testToTsv(SWTBotView view) throws NoSuchMethodException {
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        assertNotNull(os);
+        IViewPart viewPart = view.getReference().getView(true);
+        assertTrue(viewPart instanceof SystemCallLatencyStatisticsView);
+        Class<@NonNull AbstractSegmentStoreStatisticsView> clazz = AbstractSegmentStoreStatisticsView.class;
+        Method method = clazz.getDeclaredMethod("exportToTsv", java.io.OutputStream.class);
+        method.setAccessible(true);
+        final Exception[] except = new Exception[1];
+        UIThreadRunnable.syncExec(() -> {
+            try {
+                method.invoke((SystemCallLatencyStatisticsView) viewPart, os);
+            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+                except[0] = e;
+            }
+        });
+        assertNull(except[0]);
+        @SuppressWarnings("null")
+        String[] lines = String.valueOf(os).split(System.getProperty("line.separator"));
+        assertNotNull(lines);
+        assertEquals("header", "Level\tMinimum\tMaximum\tAverage\tStandard Deviation\tCount\tTotal", lines[0]);
+        assertEquals("line 1", "Total\t1.000 µs\t5.904 s\t15.628 ms\t175.875 ms\t1801\t28.146 s", lines[1]);
+
+    }
+
     private static void validate(SWTBotTreeItem treeItem, final String nodeName, final String min, final String max, final String avg, final String stdev, final String count) {
         assertEquals(nodeName, treeItem.cell(0));
         assertEquals(min, treeItem.cell(MIN_COL));
index f952178b4d6bbd2c47b22bb9313337a876ee47f1..a5b312f3280fdc70476eb41ec15756fd3e23285c 100644 (file)
 
 package org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests.latency;
 
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Random;
@@ -33,7 +35,9 @@ import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
 import org.eclipse.swtbot.swt.finder.results.BoolResult;
 import org.eclipse.swtbot.swt.finder.results.Result;
 import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu;
 import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable;
+import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.table.AbstractSegmentStoreTableView;
 import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.table.AbstractSegmentStoreTableViewer;
 import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.latency.SystemCallLatencyView;
 import org.eclipse.tracecompass.segmentstore.core.BasicSegment;
@@ -285,6 +289,58 @@ public class SystemCallLatencyTableAnalysisTest {
         bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "998,001", 0, 2));
     }
 
+    /**
+     * Test creating a tsv
+     *
+     * @throws NoSuchMethodException
+     *             Error creating the tsv
+     */
+    @Test
+    public void testWriteToTsv() throws NoSuchMethodException {
+        List<@NonNull BasicSegment> fixture = new ArrayList<>();
+        for (int i = 1; i <= 20; i++) {
+            int start = i;
+            final int delta = i;
+            int end = start + delta * delta;
+            fixture.add(new BasicSegment(start, end));
+        }
+        assertNotNull(fTable);
+        fTable.updateModel(fixture);
+        SWTBotTable tableBot = new SWTBotTable(fTable.getTableViewer().getTable());
+        SWTBot bot = new SWTBot();
+        bot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "1", 0, 2));
+        SWTWorkbenchBot swtWorkbenchBot = new SWTWorkbenchBot();
+        SWTBotView viewBot = swtWorkbenchBot.viewById(VIEW_ID);
+        testToTsv(viewBot);
+        SWTBotMenu menuBot = viewBot.viewMenu().menu("Export to TSV");
+        assertTrue(menuBot.isEnabled());
+        assertTrue(menuBot.isVisible());
+    }
+
+    private void testToTsv(SWTBotView view) throws NoSuchMethodException {
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        assertNotNull(os);
+        Class<@NonNull AbstractSegmentStoreTableView> clazz = AbstractSegmentStoreTableView.class;
+        Method method = clazz.getDeclaredMethod("exportToTsv", java.io.OutputStream.class);
+        method.setAccessible(true);
+        final Exception[] except = new Exception[1];
+        UIThreadRunnable.syncExec(() -> {
+            try {
+                method.invoke(fLatencyView, os);
+            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+                except[0] = e;
+            }
+        });
+        assertNull(except[0]);
+        @SuppressWarnings("null")
+        String[] lines = String.valueOf(os).split(System.getProperty("line.separator"));
+        assertNotNull(lines);
+        assertEquals("number of lines", 21, lines.length);
+        assertEquals("header", "Start Time\tEnd Time\tDuration", lines[0]);
+        // not a straight up string compare due to time zones. Kathmandu and Eucla have 15 minute time zones.
+        assertTrue("line 1", lines[1].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s001\\t\\d\\d:\\d\\d:00.000 000 002\\t1"));
+    }
+
     /**
      * Test with an actual trace, this is more of an integration test than a
      * unit test. This test is a slow one too. If some analyses are not well
index 069c67442f6e4409eaec089777dea4e56a784ef9..0a18e3977a095ec291126b2530e7a1b1be4afc5f 100644 (file)
  *******************************************************************************/
 package org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.statistics;
 
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jface.action.Action;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
 import org.eclipse.tracecompass.common.core.NonNullUtils;
+import org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore.ExportToTsvAction;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
 import org.eclipse.tracecompass.tmf.ui.views.TmfView;
 
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Joiner;
+
 /**
  * Abstract view to to be extended to display segment store statistics.
  *
@@ -26,7 +39,20 @@ import org.eclipse.tracecompass.tmf.ui.views.TmfView;
  */
 public abstract class AbstractSegmentStoreStatisticsView extends TmfView {
 
-    @Nullable private AbstractSegmentStoreStatisticsViewer fStatsViewer = null;
+    private final Action fExportAction = new ExportToTsvAction() {
+        @Override
+        protected void exportToTsv(@Nullable OutputStream stream) {
+            AbstractSegmentStoreStatisticsView.this.exportToTsv(stream);
+        }
+
+        @Override
+        protected @Nullable Shell getShell() {
+            return getViewSite().getShell();
+        }
+
+    };
+
+    private @Nullable AbstractSegmentStoreStatisticsViewer fStatsViewer = null;
 
     /**
      * Constructor
@@ -44,6 +70,7 @@ public abstract class AbstractSegmentStoreStatisticsView extends TmfView {
             statsViewer.loadTrace(trace);
         }
         fStatsViewer = statsViewer;
+        getViewSite().getActionBars().getMenuManager().add(fExportAction);
     }
 
     @Override
@@ -72,4 +99,53 @@ public abstract class AbstractSegmentStoreStatisticsView extends TmfView {
      */
     protected abstract AbstractSegmentStoreStatisticsViewer createSegmentStoreStatisticsViewer(Composite parent);
 
+    /**
+     * Export a given items's TSV
+     *
+     * @param stream
+     *            an output stream to write the TSV to
+     * @since 1.2
+     */
+    @VisibleForTesting
+    protected void exportToTsv(@Nullable OutputStream stream) {
+        try (PrintWriter pw = new PrintWriter(stream)) {
+            AbstractSegmentStoreStatisticsViewer statsViewer = fStatsViewer;
+            if (statsViewer == null) {
+                return;
+            }
+            Tree tree = statsViewer.getTreeViewer().getTree();
+            int size = tree.getItemCount();
+            List<String> columns = new ArrayList<>();
+            for (int i = 0; i < tree.getColumnCount(); i++) {
+                String valueOf = String.valueOf(tree.getColumn(i).getText());
+                if (valueOf.isEmpty() && i == tree.getColumnCount() - 1) {
+                    // Linux "feature", an invisible column is added at the end
+                    // with gtk2
+                    break;
+                }
+                columns.add(valueOf);
+            }
+            String join = Joiner.on('\t').skipNulls().join(columns);
+            pw.println(join);
+            for (int i = 0; i < size; i++) {
+                TreeItem item = tree.getItem(i);
+                printItem(pw, columns, item);
+            }
+        }
+    }
+
+    private void printItem(PrintWriter pw, List<String> columns, @Nullable TreeItem item) {
+        if (item == null) {
+            return;
+        }
+        List<String> data = new ArrayList<>();
+        for (int col = 0; col < columns.size(); col++) {
+            data.add(String.valueOf(item.getText(col)));
+        }
+        pw.println(Joiner.on('\t').join(data));
+        for (TreeItem child : item.getItems()) {
+            printItem(pw, columns, child);
+        }
+    }
+
 }
index 4a1460d198ab4d897208d5e2c61192f31a4d9163..8b6fd47875c71696f85bee50d1d0c1282890a978 100644 (file)
 
 package org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.table;
 
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jface.action.Action;
 import org.eclipse.jface.viewers.TableViewer;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.SashForm;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore.ExportToTsvAction;
 import org.eclipse.tracecompass.tmf.ui.views.TmfView;
 
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Joiner;
+
 /**
  * View for displaying a segment store analysis in a table.
  *
@@ -32,6 +46,19 @@ public abstract class AbstractSegmentStoreTableView extends TmfView {
     // Attributes
     // ------------------------------------------------------------------------
 
+    private final Action fExportAction = new ExportToTsvAction() {
+        @Override
+        protected void exportToTsv(@Nullable OutputStream stream) {
+            AbstractSegmentStoreTableView.this.exportToTsv(stream);
+
+        }
+
+        @Override
+        protected @Nullable Shell getShell() {
+            return getViewSite().getShell();
+        }
+    };
+
     private @Nullable AbstractSegmentStoreTableViewer fSegmentStoreViewer;
 
     // ------------------------------------------------------------------------
@@ -54,6 +81,7 @@ public abstract class AbstractSegmentStoreTableView extends TmfView {
         SashForm sf = new SashForm(parent, SWT.NONE);
         TableViewer tableViewer = new TableViewer(sf, SWT.FULL_SELECTION | SWT.VIRTUAL);
         fSegmentStoreViewer = createSegmentStoreViewer(tableViewer);
+        getViewSite().getActionBars().getMenuManager().add(fExportAction);
         setInitialData();
     }
 
@@ -103,4 +131,48 @@ public abstract class AbstractSegmentStoreTableView extends TmfView {
             fSegmentStoreViewer.setData(fSegmentStoreViewer.getSegmentProvider());
         }
     }
+
+    /**
+     * Export a given items's TSV
+     *
+     * @param stream
+     *            an output stream to write the TSV to
+     * @since 1.2
+     */
+    @VisibleForTesting
+    protected void exportToTsv(@Nullable OutputStream stream) {
+        try (PrintWriter pw = new PrintWriter(stream)) {
+            AbstractSegmentStoreTableViewer segmentStoreViewer = getSegmentStoreViewer();
+            if (segmentStoreViewer == null) {
+                return;
+            }
+            Table table = segmentStoreViewer.getTableViewer().getTable();
+            int size = table.getItemCount();
+            List<String> columns = new ArrayList<>();
+            for (int i = 0; i < table.getColumnCount(); i++) {
+                TableColumn column = table.getColumn(i);
+                if (column == null) {
+                    return;
+                }
+                String columnName = String.valueOf(column.getText());
+                if (columnName.isEmpty() && i == table.getColumnCount() - 1) {
+                    // Linux GTK2 undocumented feature
+                    break;
+                }
+                columns.add(columnName);
+            }
+            pw.println(Joiner.on('\t').join(columns));
+            for (int i = 0; i < size; i++) {
+                TableItem item = table.getItem(i);
+                if (item == null) {
+                    continue;
+                }
+                List<String> data = new ArrayList<>();
+                for (int col = 0; col < columns.size(); col++) {
+                    data.add(String.valueOf(item.getText(col)));
+                }
+                pw.println(Joiner.on('\t').join(data));
+            }
+        }
+    }
 }
diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/internal/analysis/timing/ui/views/segmentstore/ExportToTsvAction.java b/analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/internal/analysis/timing/ui/views/segmentstore/ExportToTsvAction.java
new file mode 100644 (file)
index 0000000..1f5eb40
--- /dev/null
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson
+ *
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tracecompass.internal.analysis.timing.ui.Activator;
+
+/**
+ * The export to TSV abstract action
+ *
+ * TODO: improve testing when there is a way to test native widgets
+ *
+ * @author Matthew Khouzam
+ */
+public abstract class ExportToTsvAction extends Action {
+
+    private static final String[] EXTENSTIONS = { "*.tsv", "*.*" };//$NON-NLS-1$//$NON-NLS-2$
+
+    /**
+     * Gets the extension of TSV
+     *
+     * @return the extension of TSV
+     */
+    protected String[] getExtension() {
+        return EXTENSTIONS;
+    }
+
+    @Override
+    public String getText() {
+        return String.valueOf(Messages.AbstractSegmentStoreTableView_exportToTsv);
+    }
+
+    @Override
+    public String getToolTipText() {
+        return String.valueOf(Messages.ExportToTsvAction_exportToTsvToolTip);
+    }
+
+    @Override
+    public void run() {
+        Shell shell = getShell();
+        if (shell == null) {
+            return;
+        }
+        FileDialog fd = new FileDialog(shell);
+        fd.setFilterExtensions(getExtension());
+        String fileName = fd.open();
+        if (fileName == null) {
+            return;
+        }
+        try (FileOutputStream fos = new FileOutputStream(fileName)) {
+            exportToTsv(fos);
+        } catch (IOException e) {
+            Activator.getDefault().logError("IO Error " + fileName, e); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Get the shell to open the file dialog
+     *
+     * @return the shell
+     */
+    protected abstract @Nullable Shell getShell();
+
+    /**
+     * Export a given items's TSV
+     *
+     * @param stream
+     *            an output stream to write the TSV to
+     */
+    protected abstract void exportToTsv(OutputStream stream);
+}
diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/internal/analysis/timing/ui/views/segmentstore/Messages.java b/analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/internal/analysis/timing/ui/views/segmentstore/Messages.java
new file mode 100644 (file)
index 0000000..0b0ebda
--- /dev/null
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson
+ *
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Messages for segment store views
+ *
+ * @author Matthew Khouzam
+ */
+public class Messages extends NLS {
+    private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore.messages"; //$NON-NLS-1$
+    /**
+     * Export to TSV message
+     */
+    public static @Nullable String AbstractSegmentStoreTableView_exportToTsv;
+    /**
+     * Export to TSV tooltip
+     */
+    public static @Nullable String ExportToTsvAction_exportToTsvToolTip;
+    static {
+        // initialize resource bundle
+        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+    }
+
+    private Messages() {
+    }
+}
diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/internal/analysis/timing/ui/views/segmentstore/messages.properties b/analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/internal/analysis/timing/ui/views/segmentstore/messages.properties
new file mode 100644 (file)
index 0000000..d41d461
--- /dev/null
@@ -0,0 +1,11 @@
+###############################################################################
+# Copyright (c) 2016 Ericsson
+#
+# 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
+###############################################################################
+
+AbstractSegmentStoreTableView_exportToTsv=Export to TSV
+ExportToTsvAction_exportToTsvToolTip=Output the content of this view in a tab separated value text file. This can then be imported into any spreadsheet software.
index c44108b21bfb9555350ee500e8294bcd0a1bf321..3c78e7951b430053a8729ee6226e7044a93525e9 100644 (file)
@@ -192,6 +192,7 @@ public abstract class AbstractTmfTreeViewer extends TmfTimeViewer {
         fTreeViewer.setLabelProvider(new TreeLabelProvider());
         List<TmfTreeColumnData> columns = getColumnDataProvider().getColumnData();
         this.setTreeColumns(columns);
+
     }
 
     /**
@@ -277,8 +278,9 @@ public abstract class AbstractTmfTreeViewer extends TmfTimeViewer {
      * Get the tree viewer object
      *
      * @return The tree viewer object displayed by this viewer
+     * @since 2.2
      */
-    protected TreeViewer getTreeViewer() {
+    public TreeViewer getTreeViewer() {
         return fTreeViewer;
     }
 
This page took 0.032498 seconds and 5 git commands to generate.