/*******************************************************************************
* Copyright (c) 2015, 2016 Pivotal, Inc.
* 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:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.views;
import java.util.Collection;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.jdt.core.IType;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.springframework.ide.eclipse.boot.dash.BootDashActivator;
import org.springframework.ide.eclipse.boot.dash.cloudfoundry.deployment.CloudApplicationDeploymentProperties;
import org.springframework.ide.eclipse.boot.dash.cloudfoundry.deployment.DeploymentPropertiesDialog;
import org.springframework.ide.eclipse.boot.dash.cloudfoundry.deployment.ManifestDiffDialog;
import org.springframework.ide.eclipse.boot.dash.dialogs.CustomizeAppsManagerURLDialog;
import org.springframework.ide.eclipse.boot.dash.dialogs.CustomizeAppsManagerURLDialogModel;
import org.springframework.ide.eclipse.boot.dash.dialogs.DeploymentPropertiesDialogModel;
import org.springframework.ide.eclipse.boot.dash.dialogs.EditTemplateDialog;
import org.springframework.ide.eclipse.boot.dash.dialogs.EditTemplateDialogModel;
import org.springframework.ide.eclipse.boot.dash.dialogs.ManifestDiffDialogModel;
import org.springframework.ide.eclipse.boot.dash.dialogs.ManifestDiffDialogModel.Result;
import org.springframework.ide.eclipse.boot.dash.dialogs.PasswordDialogModel;
import org.springframework.ide.eclipse.boot.dash.dialogs.ReplaceExistingApplicationDialog;
import org.springframework.ide.eclipse.boot.dash.dialogs.SelectRemoteEurekaDialog;
import org.springframework.ide.eclipse.boot.dash.dialogs.ToggleFiltersDialog;
import org.springframework.ide.eclipse.boot.dash.dialogs.ToggleFiltersDialogModel;
import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel;
import org.springframework.ide.eclipse.boot.dash.model.UserInteractions;
import org.springframework.ide.eclipse.boot.dash.views.sections.BootDashTreeContentProvider;
import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable;
import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil;
import org.springsource.ide.eclipse.commons.ui.UiUtil;
/**
* An implementation of 'UserInteractions' that uses real Dialogs, for use in
* 'production'.
*
* @author Kris De Volder
*/
public class DefaultUserInteractions implements UserInteractions {
public interface UIContext {
Shell getShell();
}
private UIContext context;
public DefaultUserInteractions(UIContext context) {
this.context = context;
}
@Override
public ILaunchConfiguration chooseConfigurationDialog(final String dialogTitle, final String message,
final Collection<ILaunchConfiguration> configs) {
final LiveVariable<ILaunchConfiguration> chosen = new LiveVariable<>();
context.getShell().getDisplay().syncExec(new Runnable() {
public void run() {
IDebugModelPresentation labelProvider = DebugUITools.newDebugModelPresentation();
try {
ElementListSelectionDialog dialog = new ElementListSelectionDialog(getShell(), labelProvider);
dialog.setElements(configs.toArray());
dialog.setTitle(dialogTitle);
dialog.setMessage(message);
dialog.setMultipleSelection(false);
int result = dialog.open();
labelProvider.dispose();
if (result == Window.OK) {
chosen.setValue((ILaunchConfiguration) dialog.getFirstResult());
}
} finally {
labelProvider.dispose();
}
}
});
return chosen.getValue();
}
private Shell getShell() {
return context.getShell();
}
@Override
public IType chooseMainType(final IType[] mainTypes, final String dialogTitle, final String message) {
if (mainTypes.length == 1) {
return mainTypes[0];
} else if (mainTypes.length > 0) {
// Take care the UI interactions don't bork if called from non-ui
// thread.
final LiveVariable<IType> chosenType = new LiveVariable<>();
getShell().getDisplay().syncExec(new Runnable() {
public void run() {
IDebugModelPresentation labelProvider = DebugUITools.newDebugModelPresentation();
try {
ElementListSelectionDialog dialog = new ElementListSelectionDialog(getShell(), labelProvider);
dialog.setElements(mainTypes);
dialog.setTitle(dialogTitle);
dialog.setMessage(message);
dialog.setMultipleSelection(false);
int result = dialog.open();
labelProvider.dispose();
if (result == Window.OK) {
chosenType.setValue((IType) dialog.getFirstResult());
}
} finally {
labelProvider.dispose();
}
}
});
return chosenType.getValue();
}
return null;
}
@Override
public void errorPopup(final String title, final String message) {
getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
MessageDialog.openError(getShell(), title, message);
}
});
}
@Override
public void openLaunchConfigurationDialogOnGroup(final ILaunchConfiguration conf, final String launchGroup) {
getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
IStructuredSelection selection = new StructuredSelection(new Object[] { conf });
DebugUITools.openLaunchConfigurationDialogOnGroup(getShell(), selection, launchGroup);
}
});
}
@Override
public void openUrl(final String url) {
getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
if (url != null) {
UiUtil.openUrl(url);
}
}
});
}
@Override
public boolean confirmOperation(final String title, final String message) {
final boolean[] confirm = { false };
getShell().getDisplay().syncExec(new Runnable() {
public void run() {
confirm[0] = MessageDialog.openConfirm(getShell(), title, message);
}
});
return confirm[0];
}
@Override
public void openDialog(final ToggleFiltersDialogModel model) {
final Shell shell = getShell();
shell.getDisplay().syncExec(new Runnable() {
public void run() {
ToggleFiltersDialog dlg = new ToggleFiltersDialog("Select Filters", model, shell);
dlg.open();
}
});
}
@Override
public String chooseFile(String title, String file) {
FileDialog fileDialog = new FileDialog(getShell());
fileDialog.setText(title);
fileDialog.setFileName(file);
String result = fileDialog.open();
return result;
}
@Override
public String selectRemoteEureka(BootDashViewModel model, String title, String message, String initialValue, IInputValidator validator) {
SelectRemoteEurekaDialog dialog = new SelectRemoteEurekaDialog(getShell(), new BootDashTreeContentProvider());
dialog.setInput(model);
dialog.setTitle("Select Eureka instance");
dialog.setMessage("Select the Eureka instance this local app should be registered with");
int open = dialog.open();
if (open == Window.OK) {
String result = dialog.getSelectedEurekaURL();
return result;
}
return null;
}
@Override
public CloudApplicationDeploymentProperties promptApplicationDeploymentProperties(DeploymentPropertiesDialogModel model)
throws Exception {
final Shell shell = getShell();
if (shell != null) {
shell.getDisplay().syncExec(new Runnable() {
@Override
public void run() {
new DeploymentPropertiesDialog(shell, model).open();
}
});
}
return model.getDeploymentProperties();
}
@Override
public boolean yesNoWithToggle(final String propertyKey, final String title, final String message, final String toggleMessage) {
final String ANSWER = propertyKey+".answer";
final String TOGGLE = propertyKey+".toggle";
final IPreferenceStore store = getPreferencesStore();
store.setDefault(ANSWER, true);
boolean toggleState = store.getBoolean(TOGGLE);
boolean answer = store.getBoolean(ANSWER);
if (toggleState) {
return answer;
}
final boolean[] dialog = new boolean[2];
getShell().getDisplay().syncExec(new Runnable() {
@Override
public void run() {
MessageDialogWithToggle result = MessageDialogWithToggle.openYesNoQuestion(getShell(), title , message, toggleMessage, false, null, null);
dialog[0] = result.getReturnCode()==IDialogConstants.YES_ID;
dialog[1] = result.getToggleState();
}
});
store.setValue(TOGGLE, dialog[1]);
store.setValue(ANSWER, dialog[0]);
return dialog[0];
}
@Override
public boolean confirmWithToggle(final String propertyKey, final String title, final String message, final String toggleMessage) {
final IPreferenceStore store = getPreferencesStore();
boolean toggleState = store.getBoolean(propertyKey);
if (toggleState) {
return true;
}
final boolean[] dialog = new boolean[2];
getShell().getDisplay().syncExec(new Runnable() {
@Override
public void run() {
MessageDialogWithToggle result = MessageDialogWithToggle.openOkCancelConfirm(getShell(), title , message, toggleMessage, false, null, null);
dialog[0] = result.getReturnCode()==IDialogConstants.OK_ID;
dialog[1] = result.getToggleState();
}
});
store.setValue(propertyKey, dialog[0] && dialog[1]);
return dialog[0];
}
protected IPreferenceStore getPreferencesStore() {
return BootDashActivator.getDefault().getPreferenceStore();
}
@Override
public Result openManifestDiffDialog(ManifestDiffDialogModel model) throws CoreException {
LiveVariable<Integer> resultCode = new LiveVariable<>();
LiveVariable<Throwable> error = new LiveVariable<>();
getShell().getDisplay().syncExec(() -> {
try {
resultCode.setValue(new ManifestDiffDialog(getShell(), model).open());
} catch (Exception e) {
error.setValue(e);
}
});
if (error.getValue()!=null) {
throw ExceptionUtil.coreException(error.getValue());
} else {
return ManifestDiffDialog.getResultForCode(resultCode.getValue());
}
}
@Override
public void openEditTemplateDialog(final EditTemplateDialogModel model) {
getShell().getDisplay().syncExec(new Runnable() {
public void run() {
new EditTemplateDialog(model, getShell()).open();
}
});
}
@Override
public void openEditAppsManagerURLDialog(CustomizeAppsManagerURLDialogModel model) {
getShell().getDisplay().syncExec(new Runnable() {
public void run() {
new CustomizeAppsManagerURLDialog(model, getShell()).open();
}
});
}
@Override
public int confirmOperation(String title, String message, String[] buttonLabels, int defaultButtonIndex) {
return new MessageDialog(getShell(), title, null, message,
MessageDialog.QUESTION, buttonLabels, defaultButtonIndex).open();
}
@Override
public void openPasswordDialog(PasswordDialogModel model) {
getShell().getDisplay().syncExec(new Runnable() {
public void run() {
new UpdatePasswordDialog(getShell(), model).open();
}
});
}
@Override
public void warningPopup(String title, String message) {
getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
MessageDialog.openWarning(getShell(), title, message);
}
});
}
@Override
public boolean confirmApplicationReplacement(String title, String message, List<String> services) {
final boolean[] result = new boolean[] { false };
getShell().getDisplay().syncExec(new Runnable() {
@Override
public void run() {
ReplaceExistingApplicationDialog dialog = new ReplaceExistingApplicationDialog(getShell(), title, message,
services);
result[0] = dialog.open() == IDialogConstants.OK_ID;
}
});
return result[0];
}
}