blob: 80b8a1562f7ae0eee64bcf0c5bb83fe53c496b96 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2012, 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.internal.r.ui.pkgmanager;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.databinding.swt.typed.WidgetProperties;
import org.eclipse.jface.databinding.viewers.typed.ViewerProperties;
import org.eclipse.jface.databinding.wizard.WizardPageSupport;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.statet.jcommons.ts.core.Tool;
import org.eclipse.statet.ecommons.databinding.jface.DataBindingSupport;
import org.eclipse.statet.ecommons.ui.dialogs.DialogUtils;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.internal.r.ui.RUIPlugin;
import org.eclipse.statet.r.core.pkgmanager.IRPkgManager;
import org.eclipse.statet.r.core.pkgmanager.RPkgAction;
import org.eclipse.statet.r.core.pkgmanager.RPkgActionHelper;
import org.eclipse.statet.r.core.pkgmanager.RPkgResolver;
import org.eclipse.statet.r.core.pkgmanager.RPkgUtils;
import org.eclipse.statet.rj.renv.core.RLibLocation;
import org.eclipse.statet.rj.renv.runtime.RuntimeRLibPaths;
public class InstallPkgsWizard extends Wizard {
static final int MODE_INSTALL= 1;
static final int MODE_UPDATE= 2;
static final int MODE_REINSTALL= 3;
class Page extends WizardPage {
private Button sameTargetControl;
private RLibrarySelectionComposite selectTargetControl;
private IObservableValue<Boolean> sameTargetValue;
private IObservableValue<RLibLocation> targetLibraryValue;
public Page() {
super("InstallPkgsTargetPage"); //$NON-NLS-1$
setTitle(InstallPkgsWizard.this.title);
setDescription("Select the target location.");
}
@Override
public void createControl(final Composite parent) {
initializeDialogUnits(parent);
final Composite composite= new Composite(parent, SWT.NONE);
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
composite.setLayout(LayoutUtils.newContentGrid(1));
final RuntimeRLibPaths rLibPaths= InstallPkgsWizard.this.rPkgManager.getRLibPaths();
{ final Group group= new Group(composite, SWT.NONE);
group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
group.setText("Target Library:");
group.setLayout(LayoutUtils.newGroupGrid(1));
this.selectTargetControl= new RLibrarySelectionComposite(group);
this.selectTargetControl.setLayoutData(this.selectTargetControl.createGD());
this.selectTargetControl.getValidator().setWritable(true);
this.selectTargetControl.setInput(rLibPaths);
if (InstallPkgsWizard.this.mode == MODE_UPDATE) {
this.sameTargetControl= new Button(group, SWT.CHECK);
this.sameTargetControl.setText("Install updates to the library of the installed package, if possible.");
this.sameTargetControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
}
}
Dialog.applyDialogFont(composite);
setControl(composite);
final DataBindingSupport databinding= new DataBindingSupport(composite);
addBindings(databinding);
this.targetLibraryValue.setValue(RPkgUtils.getDefaultInstallLocation(rLibPaths));
WizardPageSupport.create(this, databinding.getContext());
}
protected void addBindings(final DataBindingSupport databinding) {
if (this.sameTargetControl != null) {
this.sameTargetValue= new WritableValue<>(databinding.getRealm(), Boolean.FALSE, Boolean.class);
databinding.getContext().bindValue(
WidgetProperties.buttonSelection()
.observe(this.sameTargetControl),
this.sameTargetValue );
}
this.targetLibraryValue= new WritableValue<>(databinding.getRealm(), null, RLibLocation.class);
databinding.getContext().bindValue(
ViewerProperties.singleSelection(Object.class)
.observe(this.selectTargetControl.getSelectionViewer()),
this.targetLibraryValue,
new UpdateValueStrategy<Object, RLibLocation>()
.setAfterGetValidator(this.selectTargetControl.getValidator()),
null );
}
public boolean getInstallSameLocation() {
return (this.sameTargetValue != null && this.sameTargetValue.getValue().booleanValue());
}
public RLibLocation getInstallTargetLocation() {
return this.targetLibraryValue.getValue();
}
}
private final Tool rTool;
private final IRPkgManager.Ext rPkgManager;
private Page page;
private StatusPage statusPage;
private SummaryPage summaryPage;
private final RPkgResolver resolver;
private List<RPkgAction.Install> actions;
private RPkgActionHelper actionsHelper;
private final int mode;
private final String title;
public InstallPkgsWizard(final Tool rTool, final IRPkgManager.Ext manager,
final int mode, final RPkgResolver plan) {
this.rTool= rTool;
this.rPkgManager= manager;
this.mode= mode;
switch (this.mode) {
case MODE_INSTALL:
this.title= "Install Selected R Packages";
break;
case MODE_UPDATE:
this.title= "Update Selected R Packages";
break;
case MODE_REINSTALL:
this.title= "Reinstall R Packages";
break;
default:
throw new IllegalArgumentException("mode"); //$NON-NLS-1$
}
this.resolver= plan;
setWindowTitle("R Package Manager");
setNeedsProgressMonitor(true);
setDialogSettings(DialogUtils.getDialogSettings(RUIPlugin.getInstance(), "pkgmanager/InstallPkgsWizard"));
}
@Override
public void addPages() {
if (this.resolver.getStatus().getSeverity() >= IStatus.WARNING) {
this.statusPage= new StatusPage(this.title, true);
this.statusPage.setStatus(this.resolver.getStatus());
addPage(this.statusPage);
}
if (this.mode != MODE_REINSTALL) {
this.page= new Page();
addPage(this.page);
}
this.summaryPage= new SummaryPage(this.rPkgManager, this.resolver, this.title) {
@Override
public void updateInput() {
setActions(getActions(createHelper()));
}
};
addPage(this.summaryPage);
}
private List<? extends RPkgAction> getActions(final RPkgActionHelper helper) {
if (this.actions == null) {
this.actions= this.resolver.createActions();
}
if (this.actionsHelper == null || !this.actionsHelper.equals(helper)) {
this.actionsHelper= helper;
helper.update(this.actions);
}
return this.actions;
}
private RPkgActionHelper createHelper() {
switch (this.mode) {
case MODE_REINSTALL:
return new RPkgActionHelper(true, null, this.rPkgManager.getRLibPaths());
default:
return new RPkgActionHelper(
this.page.getInstallSameLocation(),
this.page.getInstallTargetLocation(),
this.rPkgManager.getRLibPaths() );
}
}
@Override
public boolean performFinish() {
final RPkgActionHelper helper= createHelper();
try {
getContainer().run(true, true, new IRunnableWithProgress() {
@Override
public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
final List<? extends RPkgAction> actions= getActions(helper);
InstallPkgsWizard.this.rPkgManager.perform(InstallPkgsWizard.this.rTool, actions);
}
});
}
catch (final InvocationTargetException e) {
}
catch (final InterruptedException e) {
}
return true;
}
}