blob: 2f33263331e5bcf26d8ab0251793e62e67e02976 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2017 Ericsson and others
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Mathieu Denis <mathieu.denis@polymtl.ca> - Generalized version based on LTTng
* Bernd Hufmann - Updated to use trace reference in TmfEvent and streaming
* Mathieu Denis - New request added to update the statistics from the selected time range
* Mathieu Denis - Generalization of the view to instantiate a viewer specific to a trace type
*
*******************************************************************************/
package org.eclipse.tracecompass.internal.tmf.ui.views.statistics;
import java.io.OutputStream;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jface.action.Action;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.tracecompass.internal.tmf.ui.commands.ExportToTsvAction;
import org.eclipse.tracecompass.internal.tmf.ui.viewers.statistics.TmfStatisticsViewer;
import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceRangeUpdatedSignal;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
import org.eclipse.tracecompass.tmf.ui.viewers.ITmfViewer;
import org.eclipse.tracecompass.tmf.ui.views.ITmfAllowMultiple;
import org.eclipse.tracecompass.tmf.ui.views.TmfView;
import org.eclipse.tracecompass.tmf.ui.widgets.tabsview.TmfViewerFolder;
/**
* The generic Statistics View displays statistics for any kind of traces.
*
* It is implemented according to the MVC pattern. - The model is a
* TmfStatisticsTreeNode built by the State Manager. - The view is built with a
* TreeViewer. - The controller that keeps model and view synchronized is an
* observer of the model.
*
* @author Mathieu Denis
*/
public class TmfStatisticsViewImpl extends TmfView implements ITmfAllowMultiple {
/**
* The view name.
*/
public static final String TMF_STATISTICS_VIEW = "StatisticsView"; //$NON-NLS-1$
/**
* The viewer that builds the columns to show the statistics.
*/
protected final TmfViewerFolder fStatsViewers;
/**
* Stores a reference to the selected trace.
*/
private ITmfTrace fTrace;
private final Action fExportAction = new ExportToTsvAction() {
@Override
protected void exportToTsv(@Nullable OutputStream stream) {
ITmfViewer viewer = fStatsViewers.getViewer();
if (viewer instanceof TmfStatisticsViewer) {
((TmfStatisticsViewer) viewer).exportToTsv(stream);
}
}
@Override
protected @Nullable Shell getShell() {
return getViewSite().getShell();
}
};
/**
* Constructor of a statistics view.
*
* @param viewName The name to give to the view.
*/
public TmfStatisticsViewImpl(String viewName) {
super(viewName);
/*
* Create a fake parent for initialization purpose, than set the parent
* as soon as createPartControl is called.
*/
Composite temporaryParent = new Shell();
fStatsViewers = new TmfViewerFolder(temporaryParent);
}
/**
* Default constructor.
*/
public TmfStatisticsViewImpl() {
this(TMF_STATISTICS_VIEW);
}
@Override
public void createPartControl(Composite parent) {
super.createPartControl(parent);
fStatsViewers.setParent(parent);
createStatisticsViewers();
ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace();
if (trace != null) {
traceSelected(new TmfTraceSelectedSignal(this, trace));
}
getViewSite().getActionBars().getMenuManager().add(fExportAction);
}
@Override
public void dispose() {
super.dispose();
fStatsViewers.dispose();
}
/**
* Handler called when an trace is opened.
*
* @param signal
* Contains the information about the selection.
*/
@TmfSignalHandler
public void traceOpened(TmfTraceOpenedSignal signal) {
/*
* Dispose the current viewer and adapt the new one to the trace
* type of the trace opened
*/
fStatsViewers.clear();
// Update the current trace
fTrace = signal.getTrace();
createStatisticsViewers();
fStatsViewers.layout();
}
/**
* Handler called when an trace is selected. Checks if the trace
* has changed and requests the selected trace if it has not yet been
* cached.
*
* @param signal
* Contains the information about the selection.
*/
@TmfSignalHandler
public void traceSelected(TmfTraceSelectedSignal signal) {
// Does not reload the same trace if already opened
if (signal.getTrace() != fTrace) {
/*
* Dispose the current viewer and adapt the new one to the trace
* type of the trace selected
*/
fStatsViewers.clear();
// Update the current trace
fTrace = signal.getTrace();
createStatisticsViewers();
fStatsViewers.layout();
TmfTraceRangeUpdatedSignal updateSignal = new TmfTraceRangeUpdatedSignal(this, fTrace, fTrace.getTimeRange());
for (ITmfViewer viewer : fStatsViewers.getViewers()) {
TmfStatisticsViewer statsViewer = (TmfStatisticsViewer) viewer;
statsViewer.sendPartialRequestOnNextUpdate();
statsViewer.traceRangeUpdated(updateSignal);
}
} else {
/*
* If the same trace is reselected, sends a notification to
* the viewers to make sure they reload correctly their partial
* event count.
*/
for (ITmfViewer viewer : fStatsViewers.getViewers()) {
TmfStatisticsViewer statsViewer = (TmfStatisticsViewer) viewer;
// Will update the partial event count if needed.
statsViewer.sendPartialRequestOnNextUpdate();
}
}
}
/**
* @param signal the incoming signal
*/
@TmfSignalHandler
public void traceClosed(TmfTraceClosedSignal signal) {
if (signal.getTrace() != fTrace) {
return;
}
// Clear the internal data
fTrace = null;
// Clear the UI widgets
fStatsViewers.clear(); // Also cancels ongoing requests
createStatisticsViewers();
fStatsViewers.layout();
}
@Override
public void setFocus() {
fStatsViewers.setFocus();
}
/**
* Creates the statistics viewers for all traces in an experiment and
* populates a viewer folder. Each viewer is placed in a different tab and
* the first one is selected automatically.
*
* It uses the extension point that defines the statistics viewer to build
* from the trace type. If no viewer is defined, another tab won't be
* created, since the global viewer already contains all the basic
* statistics. If there is no trace selected, a global statistics viewer will
* still be created.
*/
protected void createStatisticsViewers() {
// Default style for the tabs that will be created
int defaultStyle = SWT.NONE;
// The folder composite that will contain the tabs
Composite folder = fStatsViewers.getParentFolder();
// Instantiation of the global viewer
if (fTrace != null) {
// Shows the name of the trace in the global tab
TmfStatisticsViewer globalViewer = new TmfStatisticsViewer(folder, Messages.TmfStatisticsView_GlobalTabName + " - " + fTrace.getName(), fTrace); //$NON-NLS-1$
fStatsViewers.addTab(globalViewer, Messages.TmfStatisticsView_GlobalTabName, defaultStyle);
} else {
// There is no trace selected. Shows an empty global tab
TmfStatisticsViewer globalViewer = new TmfStatisticsViewer(folder, Messages.TmfStatisticsView_GlobalTabName, fTrace);
fStatsViewers.addTab(globalViewer, Messages.TmfStatisticsView_GlobalTabName, defaultStyle);
}
// Makes the global viewer visible
fStatsViewers.setSelection(0);
}
}