| /******************************************************************************* |
| * Copyright (c) 2014, 2018 Red Hat, Inc. and others. |
| * |
| * This program and the accompanying materials are made |
| * available under the terms of the Eclipse Public License 2.0 |
| * which is available at https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * 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 |
| * @deprecated Use org.eclipse.swtchart.extensions.charts.InteractiveChart and its builtin safe functionality. |
| */ |
| @Deprecated |
| public class SaveChartAction extends Action { |
| |
| private static final String[] EXTENSIONS = |
| { "*.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(EXTENSIONS); |
| 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(); |
| } |
| |
| } |