X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.charts%2Fsrc%2Forg%2Fsimantics%2Fcharts%2Feditor%2Fe4%2FChartCopyHandler.java;h=9d10ad313c65bca69473f27250ae35ba082f0c1b;hp=d6dcc5b18c54e40bab974275848d7f89147e91d9;hb=13edeabfa275ed09f6fa1b76923a96a1172fdc22;hpb=969bd23cab98a79ca9101af33334000879fb60c5 diff --git a/bundles/org.simantics.charts/src/org/simantics/charts/editor/e4/ChartCopyHandler.java b/bundles/org.simantics.charts/src/org/simantics/charts/editor/e4/ChartCopyHandler.java index d6dcc5b18..9d10ad313 100644 --- a/bundles/org.simantics.charts/src/org/simantics/charts/editor/e4/ChartCopyHandler.java +++ b/bundles/org.simantics.charts/src/org/simantics/charts/editor/e4/ChartCopyHandler.java @@ -1,222 +1,222 @@ -/******************************************************************************* - * Copyright (c) 2011 Association for Decentralized Information Management in - * Industry THTH ry. - * 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 - * - * Contributors: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -package org.simantics.charts.editor.e4; - -import java.awt.Toolkit; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.StringSelection; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.lang.reflect.InvocationTargetException; -import java.nio.charset.Charset; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; - -import javax.inject.Named; - -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.preferences.InstanceScope; -import org.eclipse.e4.core.di.annotations.CanExecute; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.services.IServiceConstants; -import org.eclipse.jface.action.IStatusLineManager; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.preferences.ScopedPreferenceStore; -import org.simantics.charts.ui.CSVProgressMonitor; -import org.simantics.databoard.binding.error.BindingException; -import org.simantics.databoard.parser.StringEscapeUtils; -import org.simantics.databoard.util.Bean; -import org.simantics.databoard.util.StreamUtil; -import org.simantics.history.HistoryException; -import org.simantics.history.ItemManager; -import org.simantics.history.csv.CSVFormatter; -import org.simantics.history.csv.ColumnSeparator; -import org.simantics.history.csv.DecimalSeparator; -import org.simantics.history.csv.ExportInterpolation; -import org.simantics.history.util.subscription.SamplingFormat; -import org.simantics.modeling.preferences.CSVPreferences; -import org.simantics.trend.configuration.TrendItem; -import org.simantics.trend.impl.TrendNode; -import org.simantics.utils.format.FormattingUtils; -import org.simantics.utils.ui.ErrorLogger; -import org.simantics.utils.ui.workbench.WorkbenchUtils; - -/** - * @author Tuukka Lehtonen - */ -public class ChartCopyHandler { - - String lastFile; - - @CanExecute - public boolean canExecute(@Named(IServiceConstants.ACTIVE_PART) MPart part) { - if (part == null) - return false; - if (part.getObject() instanceof TimeSeriesEditor == false) - return false; - return true; - } - - @Execute - public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part, @Named(IServiceConstants.ACTIVE_SHELL) Shell shell) throws ExecutionException { - if (part.getObject() instanceof TimeSeriesEditor == false) - return; - TimeSeriesEditor editor = (TimeSeriesEditor) part.getObject(); - final TrendNode trendNode = editor.trendNode; - IWorkbenchPart wbpart = WorkbenchUtils.getActiveWorkbenchPart(); - IStatusLineManager status = WorkbenchUtils.getStatusLine(wbpart); - - final AtomicBoolean result = new AtomicBoolean(false); - try { - PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() { - @Override - public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - result.set( copyDataToClipboard(monitor, trendNode, Format.JOINED_TIME, shell) ); - } - }); - if (!result.get()) { - status.setMessage("No data to copy"); - } else { - status.setMessage("Copied chart data to clipboard"); - } - status.setErrorMessage(null); - } catch (InvocationTargetException e) { - ErrorLogger.defaultLogError(e.getCause()); - } catch (InterruptedException e) { - ErrorLogger.defaultLogError(e); - } - } - - static enum Format { - TIME_VALUE_PAIRS, - JOINED_TIME - } - - public boolean copyDataToClipboard(IProgressMonitor monitor, TrendNode t, Format format, final Shell shell) { - Charset UTF8 = Charset.forName("UTF-8"); - try { - // String builder can be really slow when it is extended many times over. - // Instead stream to file with buffering -// StringBuilder sb = new StringBuilder(); - IPreferenceStore csvnode = new ScopedPreferenceStore( InstanceScope.INSTANCE, CSVPreferences.P_NODE ); - String ext = csvnode.getString(CSVPreferences.P_CSV_FILE_EXTENSION); - File tmpFile = File.createTempFile("clipboard", ext); - tmpFile.deleteOnExit(); - FileOutputStream fos = new FileOutputStream(tmpFile); - BufferedWriter w = new BufferedWriter(new OutputStreamWriter(fos, UTF8)); - try { - ItemManager im = new ItemManager( t.historian.getItems() ); - CSVFormatter formatter = new CSVFormatter(); - formatter.setTimeRange(t.horizRuler.from, t.horizRuler.end); - - // Write preferences - formatter.setStartTime( csvnode.getDouble(CSVPreferences.P_CSV_START_TIME) ); - formatter.setTimeStep( csvnode.getDouble(CSVPreferences.P_CSV_TIME_STEP) ); - formatter.setDecimalSeparator( DecimalSeparator.fromPreference(csvnode.getString(CSVPreferences.P_CSV_DECIMAL_SEPARATOR) ) ); - formatter.setColumnSeparator( ColumnSeparator.fromPreference(StringEscapeUtils.unescape( csvnode.getString(CSVPreferences.P_CSV_COLUMN_SEPARATOR) ) ) ); - formatter.setResample( csvnode.getBoolean(CSVPreferences.P_CSV_RESAMPLE) ); - formatter.setNumberInterpolation( ExportInterpolation.fromPreference (csvnode.getString(CSVPreferences.P_CSV_SAMPLING_MODE) ) ); - formatter.setTimeFormat( FormattingUtils.significantDigitFormat( csvnode.getInt(CSVPreferences.P_CSV_TIME_DIGITS) ) ); - formatter.setFloatFormat( FormattingUtils.significantDigitFormat( csvnode.getInt(CSVPreferences.P_CSV_FLOAT_DIGITS) ) ); - formatter.setNumberFormat( FormattingUtils.significantDigitFormat( csvnode.getInt(CSVPreferences.P_CSV_DOUBLE_DIGITS) ) ); - - for (TrendItem i : t.spec.items) { - if (i.hidden) continue; - List items = im.search("variableId", i.variableId); - Collections.sort(items, SamplingFormat.INTERVAL_COMPARATOR); - if (items.isEmpty()) continue; - Bean config = items.get(0); - String historyId = (String) config.getFieldUnchecked("id"); - formatter.addItem( t.historian, historyId, i.simpleLabel, i.variableReference, i.unit); - } - formatter.sort(); - switch (format) { - case TIME_VALUE_PAIRS: -// formatter.formulate1(new CSVProgressMonitor(monitor), w); - break; - case JOINED_TIME: - formatter.formulate2(new CSVProgressMonitor(monitor), w); - break; - default: - throw new UnsupportedOperationException("unsupported format " + format); - } - w.flush(); - - if (tmpFile.length()==0) return false; - - Toolkit toolkit = Toolkit.getDefaultToolkit(); - Clipboard clipboard = toolkit.getSystemClipboard(); - w.flush(); - fos.close(); - fos = null; - - System.out.println("Exported to "+tmpFile+" size: "+tmpFile.length()); - if ( tmpFile.length() > 10*1024*1024 ) { -// String msg = "The data has been written to temporary file:\n"+tmpFile.getCanonicalPath(); -// ShowMessage.showInformation( shell.getDisplay(), "Too much data for clipboard.", msg); - final File csvFile = tmpFile; - tmpFile = null; - shell.getDisplay().asyncExec( new Runnable() { - @Override - public void run() { - FileDialog fd = new FileDialog(shell, SWT.SAVE); - fd.setText("Write CSV to File"); - fd.setFileName( lastFile!=null ? lastFile : csvFile.getAbsolutePath() ); - String newFile = fd.open(); - if ( newFile != null ) { - lastFile = newFile; - File ff = new File( newFile ); - ff.delete(); - csvFile.renameTo( ff ); - } else { - csvFile.delete(); - } - }} ); - } else { - String str = StreamUtil.readString(tmpFile, UTF8); - - StringSelection strSel = new StringSelection(str); - clipboard.setContents(strSel, null); - } - - } catch (BindingException e1) { - ErrorLogger.defaultLogError(e1); - return false; - } catch (IOException e) { - ErrorLogger.defaultLogError(e); - } finally { - if ( fos != null ) try { fos.close(); } catch (IOException e) { ErrorLogger.defaultLogError(e); } - if ( tmpFile != null ) tmpFile.delete(); - } - - return true; - } catch (HistoryException e) { - ErrorLogger.defaultLogError(e); - } catch (IOException e) { - ErrorLogger.defaultLogError(e); - } - return false; - } - -} +/******************************************************************************* + * Copyright (c) 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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 + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.charts.editor.e4; + +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.lang.reflect.InvocationTargetException; +import java.nio.charset.Charset; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.inject.Named; + +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.services.IServiceConstants; +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.preferences.ScopedPreferenceStore; +import org.simantics.charts.ui.CSVProgressMonitor; +import org.simantics.databoard.binding.error.BindingException; +import org.simantics.databoard.parser.StringEscapeUtils; +import org.simantics.databoard.util.Bean; +import org.simantics.databoard.util.StreamUtil; +import org.simantics.history.HistoryException; +import org.simantics.history.ItemManager; +import org.simantics.history.csv.CSVFormatter; +import org.simantics.history.csv.ColumnSeparator; +import org.simantics.history.csv.DecimalSeparator; +import org.simantics.history.csv.ExportInterpolation; +import org.simantics.history.util.subscription.SamplingFormat; +import org.simantics.modeling.preferences.CSVPreferences; +import org.simantics.trend.configuration.TrendItem; +import org.simantics.trend.impl.TrendNode; +import org.simantics.utils.format.FormattingUtils; +import org.simantics.utils.ui.ErrorLogger; +import org.simantics.utils.ui.workbench.WorkbenchUtils; + +/** + * @author Tuukka Lehtonen + */ +public class ChartCopyHandler { + + String lastFile; + + @CanExecute + public boolean canExecute(@Named(IServiceConstants.ACTIVE_PART) MPart part) { + if (part == null) + return false; + if (part.getObject() instanceof TimeSeriesEditor == false) + return false; + return true; + } + + @Execute + public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part, @Named(IServiceConstants.ACTIVE_SHELL) Shell shell) throws ExecutionException { + if (part.getObject() instanceof TimeSeriesEditor == false) + return; + TimeSeriesEditor editor = (TimeSeriesEditor) part.getObject(); + final TrendNode trendNode = editor.trendNode; + IWorkbenchPart wbpart = WorkbenchUtils.getActiveWorkbenchPart(); + IStatusLineManager status = WorkbenchUtils.getStatusLine(wbpart); + + final AtomicBoolean result = new AtomicBoolean(false); + try { + PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() { + @Override + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + result.set( copyDataToClipboard(monitor, trendNode, Format.JOINED_TIME, shell) ); + } + }); + if (!result.get()) { + status.setMessage("No data to copy"); + } else { + status.setMessage("Copied chart data to clipboard"); + } + status.setErrorMessage(null); + } catch (InvocationTargetException e) { + ErrorLogger.defaultLogError(e.getCause()); + } catch (InterruptedException e) { + ErrorLogger.defaultLogError(e); + } + } + + static enum Format { + TIME_VALUE_PAIRS, + JOINED_TIME + } + + public boolean copyDataToClipboard(IProgressMonitor monitor, TrendNode t, Format format, final Shell shell) { + Charset UTF8 = Charset.forName("UTF-8"); + try { + // String builder can be really slow when it is extended many times over. + // Instead stream to file with buffering +// StringBuilder sb = new StringBuilder(); + IPreferenceStore csvnode = new ScopedPreferenceStore( InstanceScope.INSTANCE, CSVPreferences.P_NODE ); + String ext = csvnode.getString(CSVPreferences.P_CSV_FILE_EXTENSION); + File tmpFile = File.createTempFile("clipboard", ext); + tmpFile.deleteOnExit(); + FileOutputStream fos = new FileOutputStream(tmpFile); + BufferedWriter w = new BufferedWriter(new OutputStreamWriter(fos, UTF8)); + try { + ItemManager im = new ItemManager( t.historian.getItems() ); + CSVFormatter formatter = new CSVFormatter(); + formatter.setTimeRange(t.horizRuler.from, t.horizRuler.end); + + // Write preferences + formatter.setStartTime( csvnode.getDouble(CSVPreferences.P_CSV_START_TIME) ); + formatter.setTimeStep( csvnode.getDouble(CSVPreferences.P_CSV_TIME_STEP) ); + formatter.setDecimalSeparator( DecimalSeparator.fromPreference(csvnode.getString(CSVPreferences.P_CSV_DECIMAL_SEPARATOR) ) ); + formatter.setColumnSeparator( ColumnSeparator.fromPreference(StringEscapeUtils.unescape( csvnode.getString(CSVPreferences.P_CSV_COLUMN_SEPARATOR) ) ) ); + formatter.setResample( csvnode.getBoolean(CSVPreferences.P_CSV_RESAMPLE) ); + formatter.setNumberInterpolation( ExportInterpolation.fromPreference (csvnode.getString(CSVPreferences.P_CSV_SAMPLING_MODE) ) ); + formatter.setTimeFormat( FormattingUtils.significantDigitFormat( csvnode.getInt(CSVPreferences.P_CSV_TIME_DIGITS) ) ); + formatter.setFloatFormat( FormattingUtils.significantDigitFormat( csvnode.getInt(CSVPreferences.P_CSV_FLOAT_DIGITS) ) ); + formatter.setNumberFormat( FormattingUtils.significantDigitFormat( csvnode.getInt(CSVPreferences.P_CSV_DOUBLE_DIGITS) ) ); + + for (TrendItem i : t.spec.items) { + if (i.hidden) continue; + List items = im.search("variableId", i.variableId); + Collections.sort(items, SamplingFormat.INTERVAL_COMPARATOR); + if (items.isEmpty()) continue; + Bean config = items.get(0); + String historyId = (String) config.getFieldUnchecked("id"); + formatter.addItem( t.historian, historyId, i.simpleLabel, i.variableReference, i.unit); + } + formatter.sort(); + switch (format) { + case TIME_VALUE_PAIRS: +// formatter.formulate1(new CSVProgressMonitor(monitor), w); + break; + case JOINED_TIME: + formatter.formulate2(new CSVProgressMonitor(monitor), w); + break; + default: + throw new UnsupportedOperationException("unsupported format " + format); + } + w.flush(); + + if (tmpFile.length()==0) return false; + + Toolkit toolkit = Toolkit.getDefaultToolkit(); + Clipboard clipboard = toolkit.getSystemClipboard(); + w.flush(); + fos.close(); + fos = null; + + System.out.println("Exported to "+tmpFile+" size: "+tmpFile.length()); + if ( tmpFile.length() > 10*1024*1024 ) { +// String msg = "The data has been written to temporary file:\n"+tmpFile.getCanonicalPath(); +// ShowMessage.showInformation( shell.getDisplay(), "Too much data for clipboard.", msg); + final File csvFile = tmpFile; + tmpFile = null; + shell.getDisplay().asyncExec( new Runnable() { + @Override + public void run() { + FileDialog fd = new FileDialog(shell, SWT.SAVE); + fd.setText("Write CSV to File"); + fd.setFileName( lastFile!=null ? lastFile : csvFile.getAbsolutePath() ); + String newFile = fd.open(); + if ( newFile != null ) { + lastFile = newFile; + File ff = new File( newFile ); + ff.delete(); + csvFile.renameTo( ff ); + } else { + csvFile.delete(); + } + }} ); + } else { + String str = StreamUtil.readString(tmpFile, UTF8); + + StringSelection strSel = new StringSelection(str); + clipboard.setContents(strSel, null); + } + + } catch (BindingException e1) { + ErrorLogger.defaultLogError(e1); + return false; + } catch (IOException e) { + ErrorLogger.defaultLogError(e); + } finally { + if ( fos != null ) try { fos.close(); } catch (IOException e) { ErrorLogger.defaultLogError(e); } + if ( tmpFile != null ) tmpFile.delete(); + } + + return true; + } catch (HistoryException e) { + ErrorLogger.defaultLogError(e); + } catch (IOException e) { + ErrorLogger.defaultLogError(e); + } + return false; + } + +}