/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.components.optimizer.gui.view; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import de.rcenvironment.components.optimizer.common.Dimension; import de.rcenvironment.components.optimizer.common.Measure; import de.rcenvironment.components.optimizer.common.OptimizerComponentConstants; import de.rcenvironment.components.optimizer.common.OptimizerResultSet; import de.rcenvironment.components.optimizer.common.ResultStructure; import de.rcenvironment.components.optimizer.gui.properties.Messages; import de.rcenvironment.core.component.execution.api.ComponentExecutionInformation; import de.rcenvironment.core.gui.utils.common.ClipboardHelper; import de.rcenvironment.core.gui.utils.common.configuration.ExcelFileExporterDialog; import de.rcenvironment.core.gui.utils.incubator.StudyDataExportMessageHelper; import de.rcenvironment.core.utils.common.variables.legacy.TypedValue; import de.rcenvironment.core.utils.common.variables.legacy.VariableType; /** * The {@link Composite} displaying the data backing a chart. * * @author Sascha Zur */ @SuppressWarnings("deprecation") // This is a legacy class which will not be adapted to the new Data Types. Thus, the deprecation // warnings are suppressed here. public class ChartDataComposite extends Composite implements ISelectionProvider { private static final int DEFAULT_COLUMN_WIDTH = 100; private static final String SAVE_LOCATION_PROPERTIES_NODE = "de.rcenvironment.core.gui.resources.savelocations"; private static final String EXPORT_TO_EXCEL_PROPERTIES_IDENTIFIER = "export_to_excel_save_location"; private ComponentExecutionInformation componentExecutionInformation; /** The button to save data to an excel file. */ private Button saveDataButton; /** The table viewer. */ private TableViewer tableViewer; /** The table. */ private Table table; /** The study datastore. */ private OptimizerDatastore resultDatastore; /** The dataset add listener. */ private final OptimizerDatastore.OptimizerResultSetAddListener datasetAddListener = new OptimizerDatastore.OptimizerResultSetAddListener() { @Override public void handleStudyDatasetAdd(final OptimizerResultSet dataset) { Display.getDefault().asyncExec(new Runnable() { @Override public void run() { if (ChartDataComposite.this.isDisposed()) { return; } ChartDataComposite.this.tableViewer.add(dataset); ChartDataComposite.this.update(); } }); } }; /** * Instantiates a new chart data composite. * * @param parent the parent * @param style the style * @param componentExecutionInformation */ public ChartDataComposite(final Composite parent, final int style, ComponentExecutionInformation componentExecutionInformation) { super(parent, style); this.componentExecutionInformation = componentExecutionInformation; } /** * {@inheritDoc} * * @see org.eclipse.swt.widgets.Widget#dispose() */ @Override public void dispose() { if (resultDatastore != null) { resultDatastore.removeDatasetAddListener(datasetAddListener); } super.dispose(); } /** * Creates the controls. */ public void createControls() { // layout final GridLayout layout = new GridLayout(2, false); layout.marginWidth = 0; layout.marginHeight = 0; layout.marginBottom = 5; setLayout(layout); GridData layoutData; // table viewer tableViewer = new TableViewer(this, SWT.MULTI | SWT.FULL_SELECTION); table = tableViewer.getTable(); table.setHeaderVisible(true); table.setLinesVisible(true); layoutData = new GridData(GridData.FILL_BOTH); layoutData.horizontalIndent = 0; layoutData.verticalIndent = 0; layoutData.horizontalSpan = 2; table.setLayoutData(layoutData); // copy to clipboard final Button copyToClipboardButton = new Button(this, SWT.PUSH); copyToClipboardButton.setText(Messages.copyToClipboardLabel); layoutData = new GridData(); copyToClipboardButton.setLayoutData(layoutData); // copy to clipboard button is only enabled, if a selection is made copyToClipboardButton.setEnabled(false); addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { copyToClipboardButton.setEnabled(!event.getSelection() .isEmpty()); } }); copyToClipboardButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { final ISelection selection = getSelection(); final List<String> keys = new LinkedList<String>(); for (final TableColumn column : table.getColumns()) { keys.add(column.getText()); } final int keysCount = keys.size(); final StringBuilder builder = new StringBuilder(); if (selection != null && selection instanceof IStructuredSelection) { final IStructuredSelection structuredSelection = (IStructuredSelection) selection; @SuppressWarnings("unchecked") final Iterator<OptimizerResultSet> iterator = structuredSelection .iterator(); while (iterator.hasNext()) { final OptimizerResultSet o = iterator.next(); for (int index = 0; index < keysCount; index++) { final String key = keys.get(index); if (o != null && o.getComponent() != null) { final double value = o.getValue(key); builder.append(value); } if (index < (keysCount - 1)) { builder.append("\t"); } } if (iterator.hasNext()) { builder.append("\n"); } } final String content = builder.toString(); ClipboardHelper.setContent(content); } } }); saveDataButton = new Button(this, SWT.PUSH); saveDataButton.setText(Messages.excelExport); saveDataButton.setEnabled(false); saveDataButton.addSelectionListener(new ExportDataListener(this)); } /** * * * @author Sascha Zur */ private class ExportDataListener implements SelectionListener { private IEclipsePreferences preferences = InstanceScope.INSTANCE.getNode(SAVE_LOCATION_PROPERTIES_NODE); private final Shell cdc; ExportDataListener(ChartDataComposite cd) { cdc = cd.getShell(); } @Override public void widgetDefaultSelected(SelectionEvent arg0) { } @Override public void widgetSelected(SelectionEvent arg0) { boolean success = true; FileDialog fd = new FileDialog(cdc, SWT.SAVE); fd.setText("Save"); fd.setOverwrite(true); String lastSaveLocation = preferences.get(EXPORT_TO_EXCEL_PROPERTIES_IDENTIFIER, System.getProperty("user.dir")); fd.setFilterPath(lastSaveLocation); String[] filterExt = { "*.xls" }; fd.setFilterExtensions(filterExt); String selected = fd.open(); if (selected != null) { File excelFile = null; if (resultDatastore != null) { if (!selected.substring(selected.lastIndexOf('.') + 1).toLowerCase().equals("xls")) { selected += ".xls"; } excelFile = new File(selected); // or "e.xls" TypedValue[][] values = new TypedValue[resultDatastore.getDatasetCount() + 1][]; Iterator<OptimizerResultSet> it = resultDatastore.getDatasets().iterator(); List<Dimension> dimensions = getSortedDimensions(resultDatastore.getStructure()); List<Measure> measures = getSortedMeasures(resultDatastore.getStructure()); int i = 0; while (it.hasNext()) { OptimizerResultSet next = it.next(); if (i == 0) { values[i] = new TypedValue[next.getValues().size()]; values[i][0] = new TypedValue(VariableType.String, OptimizerComponentConstants.ITERATION_COUNT_ENDPOINT_NAME); for (int j = 0; j < dimensions.size(); j++) { values[0][j + 1] = new TypedValue(VariableType.String, dimensions.get(j).getName()); } for (int j = dimensions.size() + 1; j < measures.size() + dimensions.size() + 1; j++) { values[0][j] = new TypedValue(VariableType.String, measures.get(j - dimensions.size() - 1).getName()); } i++; } values[i] = new TypedValue[next.getValues().size()]; values[i][0] = new TypedValue(next.getValue(OptimizerComponentConstants.ITERATION_COUNT_ENDPOINT_NAME)); for (int j = 0; j < dimensions.size(); j++) { values[i][j + 1] = new TypedValue(next.getValue("Output: " + dimensions.get(j).getName())); } for (int j = dimensions.size() + 1; j < measures.size() + dimensions.size() + 1; j++) { values[i][j] = new TypedValue(next.getValue(measures.get(j - dimensions.size() - 1).getName())); } i++; } success = ExcelFileExporterDialog.exportExcelFile(excelFile, values); } else { success = false; } if (excelFile != null) { StudyDataExportMessageHelper.showConfirmationOrWarningMessageDialog(success, excelFile.getPath()); preferences.put(EXPORT_TO_EXCEL_PROPERTIES_IDENTIFIER, excelFile.getParent()); } } } } /** * Sets the study datastore. * * @param studyDatastore the new study datastore */ public void setStudyDatastore(final OptimizerDatastore studyDatastore) { if (this.resultDatastore == studyDatastore) { return; } if (this.resultDatastore == null) { this.resultDatastore = studyDatastore; final StudyDatastoreContentProvider contentProvider = new StudyDatastoreContentProvider(); initializeStructure(); // content studyDatastore.addDatasetAddListener(datasetAddListener); tableViewer.setContentProvider(contentProvider); tableViewer.setInput(studyDatastore); // getParent().update(); } } /* * /** Initialize structure. */ private void initializeStructure() { final ResultStructure structure = resultDatastore.getStructure(); /** * A {@link ColumnLabelProvider} displaying the values of a parametric study. * * @author Christian Weiss */ class ValueLabelProvider extends ColumnLabelProvider { /** The key to use to lookup the values in a dataset (which is a map-like structure). */ private final String key; private boolean isMeasure; /** * Instantiates a new {@link ValueLabelProvider} providing labels for the values with * the given key. * * @param key * @param isMeasure */ ValueLabelProvider(final String key, boolean isMeasure) { this.key = key; this.isMeasure = isMeasure; } /** * {@inheritDoc} * * @see org.eclipse.jface.viewers.ColumnLabelProvider#getText(java.lang.Object) */ @Override public String getText(Object element) { if (!(element instanceof OptimizerResultSet)) { return null; } String keyToLookup = key; if (isMeasure) { keyToLookup = "Output: " + keyToLookup; } final double value = ((OptimizerResultSet) element).getValue(keyToLookup); String result; result = String.valueOf(value); return result; } } List<Dimension> list = getSortedDimensions(structure); final TableViewerColumn itColumn = new TableViewerColumn(tableViewer, SWT.NONE); itColumn.getColumn().setText(OptimizerComponentConstants.ITERATION_COUNT_ENDPOINT_NAME); itColumn.getColumn().setWidth(DEFAULT_COLUMN_WIDTH); itColumn.getColumn().setMoveable(true); itColumn.setLabelProvider(new ValueLabelProvider(OptimizerComponentConstants.ITERATION_COUNT_ENDPOINT_NAME, false)); for (final Dimension dimension : list) { final TableViewerColumn column = new TableViewerColumn(tableViewer, SWT.NONE); column.getColumn().setText(dimension.getName()); column.getColumn().setWidth(DEFAULT_COLUMN_WIDTH); column.getColumn().setMoveable(true); column.setLabelProvider(new ValueLabelProvider(dimension.getName(), true)); } List<Measure> measureList = getSortedMeasures(structure); for (final Measure measure : measureList) { final TableViewerColumn column = new TableViewerColumn(tableViewer, SWT.NONE); column.getColumn().setText(measure.getName()); column.getColumn().setWidth(DEFAULT_COLUMN_WIDTH); column.getColumn().setMoveable(true); column.setLabelProvider(new ValueLabelProvider(measure.getName(), false)); } } private List<Measure> getSortedMeasures(final ResultStructure structure) { Collection<Measure> measureCollection = structure.getMeasures(); List<Measure> measureList = new ArrayList<Measure>(measureCollection); Collections.sort(measureList, new Comparator<Measure>() { @Override public int compare(Measure o1, Measure o2) { return o1.getName().compareTo(o2.getName()); } }); return measureList; } private List<Dimension> getSortedDimensions(final ResultStructure structure) { Collection<Dimension> collection = structure.getDimensions(); List<Dimension> list = new ArrayList<Dimension>(collection); Collections.sort(list, new Comparator<Dimension>() { @Override public int compare(Dimension o1, Dimension o2) { return o1.getName().compareTo(o2.getName()); } }); Dimension iteration = null; for (final Dimension dimension : list) { if (dimension.getName().equals(OptimizerComponentConstants.ITERATION_COUNT_ENDPOINT_NAME)) { iteration = dimension; } } list.remove(iteration); return list; } /** * {@inheritDoc} * * @see org.eclipse.swt.widgets.Control#update() */ @Override public void update() { super.update(); if (!resultDatastore.getDatasets().isEmpty()) { saveDataButton.setEnabled(true); } } /** * {@inheritDoc} * * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener) */ @Override public void addSelectionChangedListener(ISelectionChangedListener listener) { tableViewer.addSelectionChangedListener(listener); } /** * {@inheritDoc} * * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection() */ @Override public ISelection getSelection() { return tableViewer.getSelection(); } /** * {@inheritDoc} * * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener) */ @Override public void removeSelectionChangedListener( ISelectionChangedListener listener) { tableViewer.removeSelectionChangedListener(listener); } /** * {@inheritDoc} * * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection) */ @Override public void setSelection(ISelection selection) { tableViewer.setSelection(selection); } /** * The {@link IStructuredContentProvider} for the data table. */ private final class StudyDatastoreContentProvider implements IStructuredContentProvider { /** * {@inheritDoc} * * @see org.eclipse.jface.viewers.IContentProvider#dispose() */ @Override public void dispose() {} /** * {@inheritDoc} * * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, * java.lang.Object, java.lang.Object) */ @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {} /** * {@inheritDoc} * * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) */ @Override public Object[] getElements(Object inputElement) { if (!resultDatastore.getDatasets().isEmpty()) { // enabled if study data is available saveDataButton.setEnabled(true); } return resultDatastore.getDatasets().toArray(new OptimizerResultSet[0]); } } }