blob: cb633f5d10810beba69ebab6915654db10f56ad0 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2007, 2021 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.r.launching.ui;
import org.eclipse.core.databinding.Binding;
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.IFileStore;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.statet.ecommons.databinding.core.validation.UpdateableErrorValidator;
import org.eclipse.statet.ecommons.debug.ui.config.LaunchConfigTabWithDbc;
import org.eclipse.statet.ecommons.io.FileValidator;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.util.MessageUtils;
import org.eclipse.statet.internal.r.debug.ui.RLaunchingMessages;
import org.eclipse.statet.internal.r.ui.REnvSelectionComposite;
import org.eclipse.statet.r.core.RCore;
import org.eclipse.statet.r.launching.core.RLaunching;
import org.eclipse.statet.r.ui.RUI;
import org.eclipse.statet.rj.renv.core.REnv;
import org.eclipse.statet.rj.renv.core.REnvConfiguration;
import org.eclipse.statet.rj.renv.core.REnvUtils;
/**
* Launch configuration tab allowing to configure the R environment
*/
public class REnvTab extends LaunchConfigTabWithDbc {
public static String readWorkingDirectory(final ILaunchConfiguration configuration)
throws CoreException {
String wd= configuration.getAttribute(RLaunching.ATTR_WORKING_DIRECTORY, (String) null);
if (wd == null) {
wd= ""; //$NON-NLS-1$
}
return wd;
}
public static void setWorkingDirectory(final ILaunchConfigurationWorkingCopy configuration,
final String wd) {
if (wd != null && wd.length() > 0) {
configuration.setAttribute(RLaunching.ATTR_WORKING_DIRECTORY, wd);
}
else {
configuration.removeAttribute(RLaunching.ATTR_WORKING_DIRECTORY);
}
}
/**
* Reads the setting from the configuration, resolves the path and validates the directory.
* @param configuration
* @return
* @throws CoreException
*/
public static IFileStore getWorkingDirectory(final ILaunchConfiguration configuration) throws CoreException {
return getWorkingDirectoryValidator(configuration, true).getFileStore();
}
public static FileValidator getWorkingDirectoryValidator(final ILaunchConfiguration configuration, final boolean validate) throws CoreException {
String path= readWorkingDirectory(configuration);
if (path == null || path.trim().isEmpty()) {
path= System.getProperty("user.dir"); //$NON-NLS-1$
}
final FileValidator validator= new FileValidator(true);
validator.setOnDirectory(IStatus.OK);
validator.setOnFile(IStatus.ERROR);
validator.setResourceLabel(MessageUtils.removeMnemonics(RLaunchingMessages.REnv_Tab_WorkingDir_label));
validator.setExplicit(path);
if (validate && validator.validate(null).getSeverity() == IStatus.ERROR) {
throw new CoreException(validator.getStatus());
}
return validator;
}
/*-- --*/
private final boolean local;
private final IObservableValue<String> rEnvSettingValue;
private Binding rEnvBinding;
private REnvSelectionComposite rEnvControl;
public REnvTab(final boolean local) {
super();
this.local= local;
final Realm realm= getRealm();
this.rEnvSettingValue= new WritableValue<>(realm, null, String.class);
}
@Override
public String getName() {
return RLaunchingMessages.REnv_Tab_title;
}
@Override
public Image getImage() {
return RUI.getImage(RUI.IMG_OBJ_R_RUNTIME_ENV);
}
@Override
public void createControl(final Composite parent) {
final Composite mainComposite= new Composite(parent, SWT.NONE);
setControl(mainComposite);
mainComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
mainComposite.setLayout(GridLayoutFactory.swtDefaults().create());
Group group;
group= new Group(mainComposite, SWT.NONE);
group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
group.setText(RLaunchingMessages.REnv_Tab_REnvConfig_label+':');
group.setLayout(LayoutUtils.newGroupGrid(1));
if (this.local) {
this.rEnvControl= new REnvSelectionComposite(group) {
@Override
protected boolean isValid(final REnvConfiguration rEnvConfig) {
return super.isValid(rEnvConfig) && rEnvConfig.isLocal();
}
};
}
else {
this.rEnvControl= new REnvSelectionComposite(group, true);
}
this.rEnvControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
Dialog.applyDialogFont(parent);
initBindings();
}
@Override
protected void addBindings(final DataBindingContext dbc, final Realm realm) {
this.rEnvBinding= dbc.bindValue(
this.rEnvControl.createObservable(realm),
this.rEnvSettingValue,
new UpdateValueStrategy<String, String>()
.setAfterGetValidator(new UpdateableErrorValidator<>(
this.rEnvControl.createValidator(dbc) )),
null );
}
@Override
public void setDefaults(final ILaunchConfigurationWorkingCopy configuration) {
if (this.local) {
configuration.setAttribute(RLaunching.ATTR_RENV_CODE, RCore.DEFAULT_WORKBENCH_ENV_ID);
}
}
@Override
protected void doInitialize(final ILaunchConfiguration configuration) {
try {
final String code= configuration.getAttribute(RLaunching.ATTR_RENV_CODE, (String)null);
this.rEnvSettingValue.setValue(code);
} catch (final CoreException e) {
this.rEnvSettingValue.setValue(null);
logReadingError(e);
}
}
@Override
protected void doSave(final ILaunchConfigurationWorkingCopy configuration) {
final String code= this.rEnvSettingValue.getValue();
configuration.setAttribute(RLaunching.ATTR_RENV_CODE, code);
}
public REnv getSelectedEnv() {
if (this.rEnvBinding != null) {
final IStatus validationStatus= this.rEnvBinding.getValidationStatus().getValue();
if (validationStatus != null && validationStatus.getSeverity() < IStatus.WARNING) { // note: warning means error which can be saved
return REnvUtils.decode(this.rEnvSettingValue.getValue(), RCore.getREnvManager());
}
}
return null;
}
}