blob: c63a71512038b54363c7e0da980ba613e31975e4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2017 É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 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.scatter;
import java.util.Comparator;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.tracecompass.analysis.timing.core.segmentstore.IAnalysisProgressListener;
import org.eclipse.tracecompass.analysis.timing.core.segmentstore.ISegmentStoreProvider;
import org.eclipse.tracecompass.internal.analysis.timing.core.segmentstore.SegmentStoreScatterDataProvider;
import org.eclipse.tracecompass.internal.tmf.ui.commands.Messages;
import org.eclipse.tracecompass.segmentstore.core.ISegment;
import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderManager;
import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel;
import org.eclipse.tracecompass.tmf.core.model.xy.ITmfTreeXYDataProvider;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
import org.eclipse.tracecompass.tmf.ui.viewers.tree.AbstractSelectTreeViewer;
import org.eclipse.tracecompass.tmf.ui.viewers.tree.ITmfTreeColumnDataProvider;
import org.eclipse.tracecompass.tmf.ui.viewers.tree.TmfGenericTreeEntry;
import org.eclipse.tracecompass.tmf.ui.viewers.tree.TmfTreeColumnData;
import com.google.common.collect.ImmutableList;
/**
* Abstract tree viewer to go along with the scatter chart viewer in segment
* store scatter views
*
* @author Geneviève Bastien
* @since 3.0
*/
public class AbstractSegmentStoreScatterChartTreeViewer extends AbstractSelectTreeViewer {
private final String fAnalysisId;
private @Nullable ISegmentStoreProvider fSegmentProvider = null;
private SegmentStoreProviderProgressListener fListener = new SegmentStoreProviderProgressListener();
private final class SegStoreScatterLabelProvider extends TreeLabelProvider {
@Override
public @Nullable Image getColumnImage(@Nullable Object element, int columnIndex) {
if (columnIndex == 1 && element instanceof TmfGenericTreeEntry && isChecked(element)) {
TmfGenericTreeEntry<TmfTreeDataModel> entry = (TmfGenericTreeEntry<TmfTreeDataModel>) element;
if (!entry.hasChildren()) {
// ensures that only leaf nodes return images
return getLegendImage(String.valueOf(entry.getModel().getId()));
}
}
return null;
}
}
/**
* Listener to update the model with the segment store provider results once
* its store is fully completed
*/
private final class SegmentStoreProviderProgressListener implements IAnalysisProgressListener {
@Override
public void onComplete(ISegmentStoreProvider activeProvider, ISegmentStore<ISegment> data) {
/*
* Check if the active trace was changed while the provider was building its
* segment store
*/
if (activeProvider.equals(fSegmentProvider)) {
updateContent(getWindowStartTime(), getWindowEndTime(), false);
}
}
}
/**
* Constructor
*
* @param parent
* The parent composite
* @param analysisId
* The ID of the analysis to show in this viewer
*/
public AbstractSegmentStoreScatterChartTreeViewer(Composite parent, String analysisId) {
super(parent, 1, SegmentStoreScatterDataProvider.ID);
fAnalysisId = analysisId;
setLabelProvider(new SegStoreScatterLabelProvider());
}
/**
* Get the analysis ID used to retrieve the scatter data provider. Extenders may
* override this method to return another analysis ID than the one in the
* constructor
*
* @return The analysis ID
*/
protected String getAnalysisId() {
return fAnalysisId;
}
@Override
protected @Nullable ITmfTreeDataProvider<@NonNull ITmfTreeDataModel> getProvider(@NonNull ITmfTrace trace) {
String analysisId = getAnalysisId();
/* Support legacy code, get the analysis ID of the segment store */
if (analysisId.isEmpty()) {
return null;
}
/* End support of legacy */
// TODO: Find another mechanism to update the view rather than listeners, so
// that we don't need to expose the analysis to the view
IAnalysisModule module = TmfTraceUtils.getAnalysisModuleOfClass(trace, IAnalysisModule.class, analysisId);
if (!(module instanceof ISegmentStoreProvider)) {
return null;
}
fSegmentProvider = (ISegmentStoreProvider) module;
((ISegmentStoreProvider) module).addListener(fListener);
return DataProviderManager.getInstance().getDataProvider(trace, SegmentStoreScatterDataProvider.ID + ':' + analysisId, ITmfTreeXYDataProvider.class);
}
@Override
protected ITmfTreeColumnDataProvider getColumnDataProvider() {
return () -> ImmutableList.of(
createColumn(Messages.AbstractSegmentStoreScatterView_Type, Comparator.comparing(TmfGenericTreeEntry::getName)),
new TmfTreeColumnData(Messages.AbstractSegmentStoreScatterView_Legend));
}
}