/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.components.parametricstudy.gui.view; import java.io.File; import java.io.Serializable; 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.KeyAdapter; import org.eclipse.swt.events.KeyEvent; 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.parametricstudy.common.Dimension; import de.rcenvironment.components.parametricstudy.common.Measure; import de.rcenvironment.components.parametricstudy.common.StudyDataset; import de.rcenvironment.components.parametricstudy.common.StudyStructure; 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 Christian Weiss */ @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"; /** 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 StudyDatastore studyDatastore; /** The dataset add listener. */ private final StudyDatastore.StudyDatasetAddListener datasetAddListener = new StudyDatastore.StudyDatasetAddListener() { @Override public void handleStudyDatasetAdd(final StudyDataset 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 */ public ChartDataComposite(final Composite parent, final int style) { super(parent, style); } /** * {@inheritDoc} * * @see org.eclipse.swt.widgets.Widget#dispose() */ @Override public void dispose() { if (studyDatastore != null) { studyDatastore.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) { copyToClipboard(); } }); table.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if (e.stateMask == SWT.CTRL && e.keyCode == 'c') { copyToClipboard(); } else if (e.stateMask == SWT.CTRL && e.keyCode == 'a') { table.selectAll(); } } }); saveDataButton = new Button(this, SWT.PUSH); saveDataButton.setText(Messages.excelExport); saveDataButton.setEnabled(false); saveDataButton.addSelectionListener(new MySelectionListener(this)); } private void copyToClipboard() { final ISelection selection = getSelection(); // keys will contain the column header strings 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<StudyDataset> iterator = structuredSelection .iterator(); while (iterator.hasNext()) { final StudyDataset o = iterator.next(); for (int index = 0; index < keysCount; index++) { final String key = keys.get(index); final Serializable value = o.getValue(key); if (value != null) { builder.append(value); } // add a tab to separate several values in a single row if (index < (keysCount - 1)) { builder.append("\t"); } } if (iterator.hasNext()) { builder.append("\n"); } } final String content = builder.toString(); ClipboardHelper.setContent(content); } } /** * Sets the study datastore. * * @param studyDatastore the new study datastore */ public void setStudyDatastore(final StudyDatastore studyDatastore) { if (this.studyDatastore == studyDatastore) { return; } if (this.studyDatastore == null) { this.studyDatastore = studyDatastore; final StudyDatastoreContentProvider contentProvider = new StudyDatastoreContentProvider(); initializeStructure(); // content studyDatastore.addDatasetAddListener(datasetAddListener); tableViewer.setContentProvider(contentProvider); tableViewer.setInput(studyDatastore); } } /** * * * @author zur_sa */ private class MySelectionListener implements SelectionListener { private IEclipsePreferences preferences = InstanceScope.INSTANCE.getNode(SAVE_LOCATION_PROPERTIES_NODE); private final Shell cdc; MySelectionListener(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; excelFile = new File(selected); // or "e.xls" if (studyDatastore != null) { if (!selected.substring(selected.lastIndexOf('.') + 1).toLowerCase().equals("xls")) { selected += ".xls"; } TypedValue[][] values = new TypedValue[studyDatastore.getDatasetCount() + 1][]; Iterator<StudyDataset> it = studyDatastore.getDatasets().iterator(); int i = 0; List<Dimension> dimensions = getSortedDimensions(studyDatastore.getStructure()); List<Measure> measures = getSortedMeasures(studyDatastore.getStructure()); while (it.hasNext()) { StudyDataset next = it.next(); if (i == 0) { values[i] = new TypedValue[dimensions.size() + measures.size()]; for (int j = 0; j < dimensions.size(); j++) { values[0][j] = new TypedValue(VariableType.String, dimensions.get(j).getName()); } for (int j = dimensions.size(); j < measures.size() + dimensions.size(); j++) { values[0][j] = new TypedValue(VariableType.String, measures.get(j - dimensions.size()).getName()); } i++; } values[i] = new TypedValue[dimensions.size() + measures.size()]; for (int j = 0; j < dimensions.size(); j++) { values[i][j] = new TypedValue(next.getValue(dimensions.get(j).getName())); } for (int j = dimensions.size(); j < measures.size() + dimensions.size(); j++) { values[i][j] = new TypedValue(next.getValue(measures.get(j - dimensions.size()).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()); } } } } private List<Measure> getSortedMeasures(final StudyStructure 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 StudyStructure 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()); } }); return list; } /** * Initialize structure. */ private void initializeStructure() { final StudyStructure structure = studyDatastore.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; /** * Instantiates a new {@link ValueLabelProvider} providing labels for the values with * the given key. * * @param key */ ValueLabelProvider(final String key) { this.key = key; } /** * {@inheritDoc} * * @see org.eclipse.jface.viewers.ColumnLabelProvider#getText(java.lang.Object) */ @Override public String getText(Object element) { if (!(element instanceof StudyDataset)) { return null; } final Serializable value = ((StudyDataset) element) .getValue(key); String result; if (value == null) { result = ""; } else { result = value.toString(); } return result; } } for (final Dimension dimension : getSortedDimensions(structure)) { final TableViewerColumn column = new TableViewerColumn(tableViewer, SWT.NONE); column.getColumn().setText(dimension.getName()); column.getColumn().setImage(Activator.getImage("cube.dimension")); column.getColumn().setWidth(DEFAULT_COLUMN_WIDTH); column.getColumn().setMoveable(true); column.setLabelProvider(new ValueLabelProvider(dimension.getName())); } for (final Measure measure : getSortedMeasures(structure)) { final TableViewerColumn column = new TableViewerColumn(tableViewer, SWT.NONE); column.getColumn().setText(measure.getName()); column.getColumn().setImage(Activator.getImage("cube.measure")); column.getColumn().setWidth(DEFAULT_COLUMN_WIDTH); column.getColumn().setMoveable(true); column.setLabelProvider(new ValueLabelProvider(measure.getName())); } } /** * {@inheritDoc} * * @see org.eclipse.swt.widgets.Control#update() */ @Override public void update() { super.update(); if (table.getItem(0).getText().equals("")) { table.remove(0); } } /** * {@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 (!studyDatastore.getDatasets().isEmpty()) { // enabled if study data is available saveDataButton.setEnabled(true); } return studyDatastore.getDatasets().toArray(new StudyDataset[0]); } } }