1
/*******************************************************************************
2
* Copyright (c) 2014 Red Hat, Inc.
3
* All rights reserved. This program and the accompanying materials
4
* are made available under the terms of the Eclipse Public License v1.0
5
* which accompanies this distribution, and is available at
6
* http://www.eclipse.org/legal/epl-v10.html
9
* Marzia Maugeri <marzia.maugeri@st.com> - initial API and implementation
10
* Red Hat (various) - ongoing maintenance
11
*******************************************************************************/
12
package org.eclipse.linuxtools.dataviewers.charts.actions;
15
import java.text.MessageFormat;
16
import java.util.HashMap;
19
import org.eclipse.core.runtime.IStatus;
20
import org.eclipse.core.runtime.Path;
21
import org.eclipse.core.runtime.Status;
22
import org.eclipse.jface.action.Action;
23
import org.eclipse.jface.dialogs.ErrorDialog;
24
import org.eclipse.jface.dialogs.MessageDialog;
25
import org.eclipse.linuxtools.internal.dataviewers.charts.Activator;
26
import org.eclipse.linuxtools.internal.dataviewers.charts.Messages;
27
import org.eclipse.swt.SWT;
28
import org.eclipse.swt.graphics.GC;
29
import org.eclipse.swt.graphics.Image;
30
import org.eclipse.swt.graphics.ImageData;
31
import org.eclipse.swt.graphics.ImageLoader;
32
import org.eclipse.swt.widgets.Composite;
33
import org.eclipse.swt.widgets.Display;
34
import org.eclipse.swt.widgets.FileDialog;
35
import org.eclipse.swt.widgets.Shell;
36
import org.eclipse.ui.PlatformUI;
37
import org.swtchart.Chart;
40
* An action to save any {@link Composite} (typically a {@link Chart}) as an image (jpeg/jpg, bmp, png).
44
public class SaveChartAction extends Action {
46
private static final String[] EXTENSIONS =
47
{ "*.png", "*.bmp", "*.jpg", "*.jpeg", "*.*" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
48
private static final String DEFAULT_EXT = "png"; //$NON-NLS-1$
49
private static final String DEFAULT_TITLE = "newChart"; //$NON-NLS-1$
50
private static final Map<String, Integer> EXTENSION_MAP = new HashMap<>();
52
private Composite contents = null;
53
private String title = null;
56
EXTENSION_MAP.put("png", SWT.IMAGE_PNG); //$NON-NLS-1$
57
EXTENSION_MAP.put("bmp", SWT.IMAGE_BMP); //$NON-NLS-1$
58
EXTENSION_MAP.put("jpeg", SWT.IMAGE_JPEG); //$NON-NLS-1$
59
EXTENSION_MAP.put("jpg", SWT.IMAGE_JPEG); //$NON-NLS-1$
62
public SaveChartAction() {
63
super(Messages.ChartConstants_SAVE_CHART_AS, Activator.getImageDescriptor("icons/chart-save.png")); //$NON-NLS-1$
64
this.setEnabled(false);
68
* Sets the image plugin on the contents and enables the action if contents are not null.
69
* Also, a default title for the file to be saved is generated.
70
* @param contents The image contents to be saved.
72
public void setChart(Composite contents) {
73
setChart(contents, null);
77
* The same as {@link #setChart(Composite)}, but allows specification of a custom default
78
* title for the image file to be saved.
79
* @param contents The image contents to be saved.
80
* @param title The default title of the image file when it is saved. Set this to <code>null</code>
81
* if a title should be generated from the {@link #contents}.
83
public void setChart(Composite contents, String title) {
84
this.contents = contents;
85
if (contents != null) {
86
this.title = title != null ? title : getDefaultName();
93
private String getDefaultName() {
94
if (contents instanceof Chart) {
95
return ((Chart) contents).getTitle().getText().replaceAll(" ", "_"); //$NON-NLS-1$ //$NON-NLS-2$
102
* Open a dialog with which to save the contents at a user-specified path.
106
if (problemExists()) {
109
File file = askForAndPrepareFile();
113
generateImageFile(file);
117
* Save the previously-set contents as an image without the need for user input.
118
* @param path The path to save the image to.
120
public void run(String path) {
121
if (problemExists()) {
124
File file = new File(makePathWithVerifiedExt(path));
125
if (shouldOverwrite(file, null)) {
126
generateImageFile(new File(path));
130
private boolean problemExists() {
131
IStatus status = null;
133
status = new Status(IStatus.ERROR, Activator.PLUGIN_ID,
134
Messages.ChartConstants_ERROR_CHART_CLOSED);
135
} else if (contents.isDisposed()) {
136
status = new Status(IStatus.ERROR, Activator.PLUGIN_ID,
137
Messages.ChartConstants_ERROR_CHART_DISPOSED);
140
if (status != null) {
141
ErrorDialog.openError(getWorkbenchShell(),
142
Messages.ChartConstants_ERROR_SAVING_CHART,
143
Messages.ChartConstants_ERROR_SAVING_CHART_MESSAGE, status);
150
* Ask the user for the path to save the file at, and check if this path overwrites any existing file.
151
* (Note that using dialog.setOverwrite(true) is insufficient, as the path name may be appended with a
152
* file extension after the standard overwrite checks occur.)
153
* @return A file with the specified pathname, appended with an appropriate extension.
155
private File askForAndPrepareFile() {
156
final Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
157
final FileDialog dialog = new FileDialog(shell, SWT.SAVE);
158
dialog.setFilterExtensions(EXTENSIONS);
159
dialog.setText(Messages.ChartConstants_SAVE_CHART_DIALOG_TEXT);
160
dialog.setFileName(title);
163
String path = dialog.open();
165
return null; // Cancelled
168
path = makePathWithVerifiedExt(path);
170
File file = new File(path);
171
if (shouldOverwrite(file, shell)) {
174
// If not overwriting, bring up dialog again (loop)
175
dialog.setFileName(file.getName());
179
private boolean shouldOverwrite(File file, Shell shell) {
180
if (!file.exists()) {
183
if (MessageDialog.openQuestion(shell != null ? shell :
184
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
185
Messages.ChartConstants_CONFIRM_OVERWRITE_TITLE,
186
MessageFormat.format(Messages.ChartConstants_CONFIRM_OVERWRITE_MSG, file))) {
194
* Checks if the provided path has a valid file extension supported by {@link ImageLoader#save(String, int)}.
195
* If not, a copy of the path is returned, with its extension replaced with a default one.
197
private String makePathWithVerifiedExt(String path) {
198
String pathExt = Path.fromOSString(path).getFileExtension();
199
if (pathExt == null) {
200
return path.concat('.' + DEFAULT_EXT);
202
if (EXTENSION_MAP.containsKey(pathExt)) {
205
return path.replaceAll(pathExt.concat("$"), DEFAULT_EXT); //$NON-NLS-1$
208
private void generateImageFile(File file) {
209
// Extension is chosen based on the file name, not the dialog filter selection.
210
int extension = EXTENSION_MAP.get(Path.fromOSString(file.getName()).getFileExtension());
212
Display dsp = Display.getCurrent();
213
GC gc = new GC(contents);
214
Image img = new Image(dsp, contents.getSize().x, contents.getSize().y);
215
gc.copyArea(img, 0, 0);
217
ImageLoader imageLoader = new ImageLoader();
218
imageLoader.data = new ImageData[] { img.getImageData() };
219
imageLoader.save(file.getAbsolutePath(), extension);
222
private Shell getWorkbenchShell() {
223
return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();