/*=============================================================================#
# Copyright (c) 2012-2016 Stephan Wahlbrink (WalWare.de) and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# Contributors:
# Stephan Wahlbrink - initial API and implementation
#=============================================================================*/
package de.walware.statet.r.ui.pkgmanager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import de.walware.ecommons.ui.util.UIAccess;
import de.walware.statet.nico.ui.util.ToolMessageDialog;
import de.walware.rj.eclient.IRToolService;
import de.walware.statet.r.console.core.RProcess;
import de.walware.statet.r.core.pkgmanager.IRPkgManager;
import de.walware.statet.r.core.pkgmanager.IRPkgSet;
import de.walware.statet.r.core.renv.IREnv;
import de.walware.statet.r.internal.ui.pkgmanager.RPkgManagerDialog;
public class RPkgManagerUI {
private static final Map<IREnv, RPkgManagerDialog> DIALOGS= new HashMap<>();
private static Shell getShell(final IShellProvider shellProvider) {
Shell shell = null;
if (shellProvider != null) {
shell = shellProvider.getShell();
}
if (shell == null) {
shell = UIAccess.getActiveWorkbenchShell(false);
}
return shell;
}
public static RPkgManagerDialog openDialog(final IRPkgManager.Ext manager,
final RProcess tool, final Shell parentShell, final StartAction startAction) {
final IREnv rEnv = manager.getREnv();
RPkgManagerDialog dialog = DIALOGS.get(rEnv);
if (dialog != null && dialog.getShell() != null && !dialog.getShell().isDisposed()) {
dialog.close();
}
dialog = new RPkgManagerDialog(manager, tool, parentShell);
dialog.setBlockOnOpen(false);
DIALOGS.put(rEnv, dialog);
dialog.open();
dialog.getShell().addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(final DisposeEvent e) {
final RPkgManagerDialog d = DIALOGS.get(rEnv);
if (d != null && d.getShell() == e.getSource()) {
DIALOGS.remove(rEnv);
}
}
});
if (startAction != null) {
dialog.start(startAction);
}
return dialog;
}
public static boolean requestRequiredRPkgs(final IRPkgManager.Ext manager,
final List<String> pkgNames,
final IRToolService r, final IProgressMonitor monitor,
final IShellProvider shellProvider, final String message,
final Runnable okRunnable, final Runnable cancelRunnable) throws CoreException {
if (manager.requiresUpdate()) {
manager.update(r, monitor);
}
final IRPkgSet rPkgSet = manager.getRPkgSet();
final List<String> missingPkgs= new ArrayList<>(pkgNames.size());
final StringBuilder sb = new StringBuilder();
for (final String pkgName : pkgNames) {
if (rPkgSet.getInstalled().containsByName(pkgName)) {
continue;
}
missingPkgs.add(pkgName);
sb.append("\n\t"); //$NON-NLS-1$
sb.append(pkgName);
}
if (sb.length() == 0) {
return true;
}
sb.insert(0, message);
sb.append("\n\nDo you want to install the packages now?");
final RProcess tool = (RProcess) r.getTool();
final Shell shell = getShell(shellProvider);
final Display display = (shell != null) ? shell.getDisplay() : UIAccess.getDisplay();
display.asyncExec(new Runnable() {
@Override
public void run() {
final boolean yes = ToolMessageDialog.openQuestion(tool, shell,
"Required R Packages", sb.toString());
if (yes) {
final RPkgManagerDialog dialog = openDialog(manager, tool, shell,
new StartAction(StartAction.INSTALL, missingPkgs) );
if (okRunnable != null) {
dialog.getShell().addListener(SWT.Close, new Listener() {
@Override
public void handleEvent(final Event event) {
display.asyncExec(okRunnable);
}
});
}
return;
}
if (cancelRunnable != null) {
cancelRunnable.run();
}
}
});
return false;
}
}