diff options
Diffstat (limited to 'profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/dataviewers/charts/actions/SaveChartAction.java')
-rwxr-xr-x | profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/dataviewers/charts/actions/SaveChartAction.java | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/dataviewers/charts/actions/SaveChartAction.java b/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/dataviewers/charts/actions/SaveChartAction.java new file mode 100755 index 0000000000..ddd0ac7e2d --- /dev/null +++ b/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/dataviewers/charts/actions/SaveChartAction.java @@ -0,0 +1,226 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, Inc. + * 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: + * Marzia Maugeri <marzia.maugeri@st.com> - initial API and implementation + * Red Hat (various) - ongoing maintenance + *******************************************************************************/ +package org.eclipse.linuxtools.dataviewers.charts.actions; + +import java.io.File; +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.linuxtools.internal.dataviewers.charts.Activator; +import org.eclipse.linuxtools.internal.dataviewers.charts.Messages; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.ImageLoader; +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.ui.PlatformUI; +import org.swtchart.Chart; + +/** + * An action to save any {@link Composite} (typically a {@link Chart}) as an image (jpeg/jpg, bmp, png). + * + * @since 6.0 + */ +public class SaveChartAction extends Action { + + private static final String[] saveAsImageExt = + { "*.png", "*.bmp", "*.jpg", "*.jpeg", "*.*" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + private static final String DEFAULT_EXT = "png"; //$NON-NLS-1$ + private static final String DEFAULT_TITLE = "newChart"; //$NON-NLS-1$ + private static final Map<String, Integer> EXTENSION_MAP = new HashMap<>(); + + private Composite contents = null; + private String title = null; + + static { + EXTENSION_MAP.put("png", SWT.IMAGE_PNG); //$NON-NLS-1$ + EXTENSION_MAP.put("bmp", SWT.IMAGE_BMP); //$NON-NLS-1$ + EXTENSION_MAP.put("jpeg", SWT.IMAGE_JPEG); //$NON-NLS-1$ + EXTENSION_MAP.put("jpg", SWT.IMAGE_JPEG); //$NON-NLS-1$ + } + + public SaveChartAction() { + super(Messages.ChartConstants_SAVE_CHART_AS, Activator.getImageDescriptor("icons/chart-save.png")); //$NON-NLS-1$ + this.setEnabled(false); + } + + /** + * Sets the image plugin on the contents and enables the action if contents are not null. + * Also, a default title for the file to be saved is generated. + * @param contents The image contents to be saved. + */ + public void setChart(Composite contents) { + setChart(contents, null); + } + + /** + * The same as {@link #setChart(Composite)}, but allows specification of a custom default + * title for the image file to be saved. + * @param contents The image contents to be saved. + * @param title The default title of the image file when it is saved. Set this to <code>null</code> + * if a title should be generated from the {@link #contents}. + */ + public void setChart(Composite contents, String title) { + this.contents = contents; + if (contents != null) { + this.title = title != null ? title : getDefaultName(); + setEnabled(true); + } else { + setEnabled(false); + } + } + + private String getDefaultName() { + if (contents instanceof Chart) { + return ((Chart) contents).getTitle().getText().replaceAll(" ", "_"); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + return DEFAULT_TITLE; + } + } + + /** + * Open a dialog with which to save the contents at a user-specified path. + */ + @Override + public void run() { + if (problemExists()) { + return; + } + File file = askForAndPrepareFile(); + if (file == null) { + return; // Cancelled + } + generateImageFile(file); + } + + /** + * Save the previously-set contents as an image without the need for user input. + * @param path The path to save the image to. + */ + public void run(String path) { + if (problemExists()) { + return; + } + File file = new File(makePathWithVerifiedExt(path)); + if (shouldOverwrite(file, null)) { + generateImageFile(new File(path)); + } + } + + private boolean problemExists() { + IStatus status = null; + if (!isEnabled()) { + status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, + Messages.ChartConstants_ERROR_CHART_CLOSED); + } else if (contents.isDisposed()) { + status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, + Messages.ChartConstants_ERROR_CHART_DISPOSED); + } + + if (status != null) { + ErrorDialog.openError(getWorkbenchShell(), + Messages.ChartConstants_ERROR_SAVING_CHART, + Messages.ChartConstants_ERROR_SAVING_CHART_MESSAGE, status); + return true; + } + return false; + } + + /** + * Ask the user for the path to save the file at, and check if this path overwrites any existing file. + * (Note that using dialog.setOverwrite(true) is insufficient, as the path name may be appended with a + * file extension after the standard overwrite checks occur.) + * @return A file with the specified pathname, appended with an appropriate extension. + */ + private File askForAndPrepareFile() { + final Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); + final FileDialog dialog = new FileDialog(shell, SWT.SAVE); + dialog.setFilterExtensions(saveAsImageExt); + dialog.setText(Messages.ChartConstants_SAVE_CHART_DIALOG_TEXT); + dialog.setFileName(title); + + do { + String path = dialog.open(); + if (path == null) { + return null; // Cancelled + } + + path = makePathWithVerifiedExt(path); + + File file = new File(path); + if (shouldOverwrite(file, shell)) { + return file; + } + // If not overwriting, bring up dialog again (loop) + dialog.setFileName(file.getName()); + } while (true); + } + + private boolean shouldOverwrite(File file, Shell shell) { + if (!file.exists()) { + return true; + } + if (MessageDialog.openQuestion(shell != null ? shell : + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), + Messages.ChartConstants_CONFIRM_OVERWRITE_TITLE, + MessageFormat.format(Messages.ChartConstants_CONFIRM_OVERWRITE_MSG, file))) { + file.delete(); + return true; + } + return false; + } + + /** + * Checks if the provided path has a valid file extension supported by {@link ImageLoader#save(String, int)}. + * If not, a copy of the path is returned, with its extension replaced with a default one. + */ + private String makePathWithVerifiedExt(String path) { + String pathExt = Path.fromOSString(path).getFileExtension(); + if (pathExt == null) { + return path.concat('.' + DEFAULT_EXT); + } + if (EXTENSION_MAP.containsKey(pathExt)) { + return path; + } + return path.replaceAll(pathExt.concat("$"), DEFAULT_EXT); //$NON-NLS-1$ + } + + private void generateImageFile(File file) { + // Extension is chosen based on the file name, not the dialog filter selection. + int extension = EXTENSION_MAP.get(Path.fromOSString(file.getName()).getFileExtension()); + + Display dsp = Display.getCurrent(); + GC gc = new GC(contents); + Image img = new Image(dsp, contents.getSize().x, contents.getSize().y); + gc.copyArea(img, 0, 0); + gc.dispose(); + ImageLoader imageLoader = new ImageLoader(); + imageLoader.data = new ImageData[] { img.getImageData() }; + imageLoader.save(file.getAbsolutePath(), extension); + } + + private Shell getWorkbenchShell() { + return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); + } + +} |