blob: f954f8a227535c6a9161b8e3404b2c5483d597b1 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2007, 2019 Stephan Wahlbrink 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, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.internal.r.ui.graphics;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.databinding.swt.typed.WidgetProperties;
import org.eclipse.jface.databinding.wizard.WizardPageSupport;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
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.Group;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.statushandlers.StatusManager;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.ecommons.io.FileValidator;
import org.eclipse.statet.ecommons.runtime.core.util.StatusUtils;
import org.eclipse.statet.ecommons.ui.dialogs.DialogUtils;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.util.UIAccess;
import org.eclipse.statet.ecommons.ui.workbench.ResourceInputComposite;
import org.eclipse.statet.ecommons.variables.core.StaticVariable;
import org.eclipse.statet.internal.r.ui.RUIPlugin;
import org.eclipse.statet.nico.ui.util.ToolInfoGroup;
import org.eclipse.statet.r.console.core.IRBasicAdapter;
import org.eclipse.statet.r.console.core.RProcess;
import org.eclipse.statet.r.core.RUtil;
import org.eclipse.statet.r.ui.RUI;
import org.eclipse.statet.rj.eclient.graphics.ERGraphic;
import org.eclipse.statet.rj.eclient.graphics.util.CopyToDevRunnable;
import org.eclipse.statet.rj.ts.core.RToolService;
/**
* Wizard to save R graphic to file.
*/
public class StatetRGraphicCopyToDevWizard extends Wizard {
private class ConfigPage extends WizardPage {
private static final String SETTINGS_HISTORY= "todev.file-"; //$NON-NLS-1$
private static final String SETTINGS_OPEN= "open.file-"; //$NON-NLS-1$
private final String settingType;
private final IObservableValue<String> newLocationValue;
private final IObservableValue<Boolean> openFileValue;
private ResourceInputComposite locationGroup;
private Button openFileControl;
private DataBindingContext dbc;
public ConfigPage() {
super("Config"); //$NON-NLS-1$
this.settingType= StatetRGraphicCopyToDevWizard.this.devAbbr.toLowerCase();
setTitle(NLS.bind("Save Graphic as {0} using R", StatetRGraphicCopyToDevWizard.this.devAbbr.toUpperCase()));
setDescription("Select the file to save the graphic to.");
final Realm realm= Realm.getDefault();
this.newLocationValue= new WritableValue<>(realm, "", String.class);
this.openFileValue= new WritableValue<>(realm, Boolean.FALSE, Boolean.class);
}
@Override
public void createControl(final Composite parent) {
initializeDialogUnits(parent);
final Composite container= new Composite(parent, SWT.NONE);
container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
container.setLayout(new GridLayout());
setControl(container);
createContents(container);
LayoutUtils.addSmallFiller(container, true);
final ToolInfoGroup info= new ToolInfoGroup(container, StatetRGraphicCopyToDevWizard.this.tool);
info.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
Dialog.applyDialogFont(container);
// initFields();
// validate();
setErrorMessage(null);
setMessage(null);
}
protected void createContents(final Composite container) {
this.locationGroup= new ResourceInputComposite(container,
ResourceInputComposite.STYLE_COMBO,
ResourceInputComposite.MODE_FILE | ResourceInputComposite.MODE_SAVE,
"Graphic File");
final IFileStore wd= StatetRGraphicCopyToDevWizard.this.tool.getWorkspaceData().getWorkspaceDir();
if (wd != null) {
this.locationGroup.getValidator().setRelative(
new StaticVariable("wd", null, wd.toString()), //$NON-NLS-1$
IStatus.WARNING);
}
else {
this.locationGroup.getValidator().setIgnoreRelative(true);
}
this.locationGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
this.locationGroup.setHistory(getDialogSettings().getArray(SETTINGS_HISTORY+this.settingType));
{ final Group group= new Group(container, SWT.DEFAULT);
group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
group.setLayout(LayoutUtils.newGroupGrid(1));
this.openFileControl= new Button(group, SWT.CHECK);
this.openFileControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
this.openFileControl.setText("&Open file when finished");
}
final Realm realm= Realm.getDefault();
this.dbc= new DataBindingContext(realm);
this.dbc.bindValue(
this.locationGroup.getObservable(),
this.newLocationValue,
new UpdateValueStrategy<String, String>()
.setAfterGetValidator(this.locationGroup.getValidator()),
null );
this.dbc.bindValue(
WidgetProperties.buttonSelection()
.observe(this.openFileControl),
this.openFileValue );
this.openFileValue.setValue(getDialogSettings().getBoolean(SETTINGS_OPEN + this.settingType));
WizardPageSupport.create(this, this.dbc);
}
public void saveSettings() {
final IDialogSettings settings= getDialogSettings();
DialogUtils.saveHistorySettings(settings, SETTINGS_HISTORY+this.settingType, this.newLocationValue.getValue());
settings.put(SETTINGS_OPEN+this.settingType, this.openFileValue.getValue().booleanValue());
}
public FileValidator getValidator() throws CoreException {
return this.locationGroup.getValidator();
}
public boolean getOpen() {
return this.openFileValue.getValue().booleanValue();
}
@Override
public void dispose() {
if (this.dbc != null) {
this.dbc.dispose();
this.dbc= null;
}
super.dispose();
}
}
private final RProcess tool;
private final ERGraphic graphic;
private final String devCmd;
private final String devAbbr;
private ConfigPage page;
public StatetRGraphicCopyToDevWizard(final RProcess tool, final ERGraphic graphic,
final String devCmd, final String devAbbr) {
this.tool= tool;
this.graphic= graphic;
this.devCmd= devCmd;
this.devAbbr= devAbbr;
setDialogSettings(DialogUtils.getDialogSettings(RUIPlugin.getInstance(), "GraphicCopyToDev-Wizard")); //$NON-NLS-1$
setWindowTitle("Save Graphic using R");
setNeedsProgressMonitor(false);
}
@Override
public void addPages() {
this.page= new ConfigPage();
addPage(this.page);
}
@Override
public boolean performFinish() {
if (!this.tool.isTerminated()) {
try {
final FileValidator validator= this.page.getValidator();
final IPath relative= (validator.isRelativeFile()) ?
validator.getRelativeFile() : null;
final IFileStore absolute= (relative == null) ? validator.getFileStore() : null;
final String path;
try {
path= (relative != null) ? relative.toString() :
this.tool.getWorkspaceData().toToolPath(absolute);
}
catch (final StatusException e) {
throw StatusUtils.convert(e);
}
final boolean open= this.page.getOpen();
final IWorkbenchPage workbenchPage= UIAccess.getActiveWorkbenchPage(true);
this.graphic.getRHandle().getQueue().add(new CopyToDevRunnable(
this.graphic, this.devCmd, RUtil.escapeCompletely(path),
"onefile= TRUE, paper= \"special\"") {
@Override
public void run(final RToolService r,
final ProgressMonitor m) throws StatusException {
super.run(r, m);
if (open) {
try {
final IFileStore fileName;
if (relative != null) {
((IRBasicAdapter) r).refreshWorkspaceData(0, m);
final IFileStore wd= StatetRGraphicCopyToDevWizard.this.tool.getWorkspaceData().getWorkspaceDir();
if (wd == null) {
return;
}
fileName= wd.getFileStore(relative);
}
else {
fileName= absolute;
}
if (fileName != null && fileName.fetchInfo(EFS.NONE, null).exists()) {
UIAccess.getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
try {
IWorkbenchPage page= workbenchPage;
if (page == null || page.getWorkbenchWindow().getShell() == null) {
page= UIAccess.getActiveWorkbenchPage(true);
}
if (page == null) {
return;
}
IDE.openEditorOnFileStore(page, fileName);
}
catch (final CoreException e) {
StatusManager.getManager().handle(new Status(IStatus.ERROR, RUI.BUNDLE_ID,
"An error occurred when opening the exported R graphic.",
e ));
}
}
});
}
}
catch (final CoreException e) {
StatusManager.getManager().handle(new Status(IStatus.ERROR, RUI.BUNDLE_ID,
"An error occurred when opening the exported R graphic.",
e ));
}
}
}
});
}
catch (final CoreException e) {
StatusManager.getManager().handle(new Status(IStatus.ERROR, RUI.BUNDLE_ID, NLS.bind(
"An error occurred when exporting the R graphic (Device {0}).",
this.graphic.getDevId() + 1 ),
e ),
StatusManager.SHOW | StatusManager.LOG );
return false;
}
}
this.page.saveSettings();
return true;
}
}