/*******************************************************************************
* Copyright (c) 2017 Red Hat Inc. 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:
* Red Hat - Initial Contribution
*******************************************************************************/
package org.eclipse.linuxtools.internal.docker.ui.wizards;
import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.linuxtools.docker.core.DockerException;
import org.eclipse.linuxtools.docker.core.IDockerConnection;
import org.eclipse.linuxtools.docker.core.IDockerImage;
import org.eclipse.linuxtools.docker.ui.Activator;
import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
/**
* A {@link WizardPage} to let the user select the CPU and memory allocation for
* the container, as well as the volumes to mount.
*
* @author jjohnstn
*
*/
public class ImageRunNetworkPage extends WizardPage {
private final int COLUMNS = 2;
private final static String NETWORK_MODE = "networkMode"; //$NON-NLS-1$
private final DataBindingContext dbc = new DataBindingContext();
private final ImageRunNetworkModel model;
private final ILaunchConfiguration lastLaunchConfiguration;
private Control containerControl; // control selecting container
private Control otherControl; // control selecting other selection
/**
* Default constructor.
*
* @param connection
* the {@link IDockerConnection} to use
* @throws DockerException
* if obtaining info from the given {@link IDockerConnection}
* failed
*
*/
public ImageRunNetworkPage(final IDockerConnection connection) {
super("ImageRunNetworkPage", //$NON-NLS-1$
WizardMessages.getString("ImageRunNetworkPage.title"), //$NON-NLS-1$
SWTImagesFactory.DESC_BANNER_REPOSITORY);
setPageComplete(true);
this.model = new ImageRunNetworkModel(connection);
this.lastLaunchConfiguration = null;
}
/**
* Default constructor.
*
* @param selectedImage
* the {@link IDockerImage} to run
* @param connection
* the {@link IDockerConnection} to use
* @throws DockerException
* if obtaining info from the given {@link IDockerConnection}
* failed
*
*/
public ImageRunNetworkPage(
final IDockerImage selectedImage,
final ILaunchConfiguration lastLaunchConfiguration) {
super("ImageRunNetworkPage", //$NON-NLS-1$
WizardMessages.getString("ImageRunNetworkPage.title"), //$NON-NLS-1$
SWTImagesFactory.DESC_BANNER_REPOSITORY);
setPageComplete(true);
this.model = new ImageRunNetworkModel(selectedImage);
this.lastLaunchConfiguration = lastLaunchConfiguration;
}
public ImageRunNetworkModel getModel() {
return model;
}
@Override
public void createControl(Composite parent) {
final ScrolledComposite scrollTop = new ScrolledComposite(parent,
SWT.H_SCROLL | SWT.V_SCROLL);
scrollTop.setExpandVertical(true);
scrollTop.setExpandHorizontal(true);
final Composite container = new Composite(scrollTop, SWT.NONE);
container.setLayout(new GridLayout());
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).span(1, 1)
.grab(true, false).applyTo(container);
GridLayoutFactory.fillDefaults().numColumns(COLUMNS).margins(6, 6)
.applyTo(container);
createNetworkModeContainer(container);
setDefaultValues();
scrollTop.setContent(container);
Point point = container.computeSize(SWT.DEFAULT, SWT.DEFAULT);
scrollTop.setSize(point);
scrollTop.setMinSize(point);
setControl(scrollTop);
}
@SuppressWarnings("unchecked")
private void createNetworkModeContainer(final Composite parent) {
final Composite container = new Composite(parent, SWT.NONE);
container.setLayout(new GridLayout());
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
.span(COLUMNS, 1).grab(true, false).applyTo(container);
GridLayoutFactory.fillDefaults().spacing(10, 2).applyTo(container);
// specify default network
final Label modeLabel = new Label(container, SWT.NONE);
modeLabel.setText(WizardMessages.getString("ImageRunNetworkPage.mode")); //$NON-NLS-1$
// $NON-NLS-1$
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).span(2, 1)
.grab(false, false).applyTo(modeLabel);
final int COLUMNS = 2;
final int INDENT = 20;
final Composite subContainer = new Composite(container, SWT.NONE);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
.indent(INDENT, 0).span(COLUMNS, 1).grab(true, false)
.applyTo(subContainer);
GridLayoutFactory.fillDefaults().numColumns(COLUMNS).margins(6, 6)
.spacing(10, 5).applyTo(subContainer);
modeLabel.setEnabled(true);
final Button defaultButton = new Button(subContainer, SWT.RADIO);
bindButton(defaultButton, ImageRunNetworkModel.DEFAULT_MODE);
defaultButton.setText(
WizardMessages.getString("ImageRunNetworkPage.mode.default")); //$NON-NLS-1$
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).span(2, 1)
.applyTo(defaultButton);
final Button bridgeButton = new Button(subContainer, SWT.RADIO);
bridgeButton.setText(
WizardMessages.getString("ImageRunNetworkPage.mode.bridge")); //$NON-NLS-1$
bindButton(bridgeButton, ImageRunNetworkModel.BRIDGE_MODE);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).span(2, 1)
.applyTo(bridgeButton);
final Button hostButton = new Button(subContainer, SWT.RADIO);
hostButton.setText(
WizardMessages.getString("ImageRunNetworkPage.mode.host")); //$NON-NLS-1$
bindButton(hostButton, ImageRunNetworkModel.HOST_MODE);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).span(2, 1)
.applyTo(hostButton);
final Button noneButton = new Button(subContainer, SWT.RADIO);
noneButton.setText(
WizardMessages.getString("ImageRunNetworkPage.mode.none")); // $NON-NLS-1$
bindButton(noneButton, ImageRunNetworkModel.NONE_MODE);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).span(2, 1)
.applyTo(noneButton);
final Button containerButton = new Button(subContainer, SWT.RADIO);
containerButton.setText(
WizardMessages.getString("ImageRunNetworkPage.mode.container")); //$NON-NLS-1$
// $NON-NLS-1$
bindButton(containerButton, ImageRunNetworkModel.CONTAINER_MODE);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.applyTo(containerButton);
// Container list
final Combo containerList = new Combo(subContainer, SWT.BORDER);
setContainerControl(containerList);
containerList
.setItems(model.getContainerNames().toArray(new String[] {}));
if (containerList.getItemCount() > 0)
containerList.select(0);
containerList.setEnabled(false);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(true, false).applyTo(containerList);
dbc.bindValue(WidgetProperties.selection().observe(containerList),
BeanProperties
.value(ImageRunNetworkModel.class,
ImageRunNetworkModel.SELECTED_CONTAINER)
.observe(model));
containerButton.addSelectionListener(
onContainerSelection(containerButton, containerList));
final Button otherButton = new Button(subContainer, SWT.RADIO);
otherButton.setText(
WizardMessages.getString("ImageRunNetworkPage.mode.other"));
// $NON-NLS-1$
bindButton(otherButton, ImageRunNetworkModel.OTHER_MODE);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.applyTo(otherButton);
// Container list
final Text otherText = new Text(subContainer, SWT.SINGLE | SWT.BORDER);
setOtherControl(otherText);
otherText.setEnabled(false);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(true, false).applyTo(otherText);
dbc.bindValue(WidgetProperties.text(SWT.Modify).observe(otherText),
BeanProperties
.value(ImageRunNetworkModel.class,
ImageRunNetworkModel.OTHER_STRING)
.observe(model));
otherButton
.addSelectionListener(onOtherSelection(otherButton, otherText));
}
@Override
public boolean isPageComplete() {
if (model == null)
return false;
if (ImageRunNetworkModel.CONTAINER_MODE.equals(model.getNetworkMode())) {
if (((Combo)getContainerControl()).getText().isEmpty()) {
setMessage(
WizardMessages
.getString("WarningNoContainerSelected.msg"), //$NON-NLS-1$
IMessageProvider.WARNING);
return false;
} else if (ImageRunNetworkModel.OTHER_MODE
.equals(model.getNetworkMode())) {
if (((Text) getOtherControl()).getText().isEmpty()) {
setMessage(
WizardMessages
.getString("WarningOtherFieldEmpty.msg"), //$NON-NLS-1$
IMessageProvider.WARNING);
return false;
}
}
}
setMessage(null, IMessageProvider.WARNING);
return true;
}
private Control getContainerControl() {
return containerControl;
}
private void setContainerControl(Control containerControl) {
this.containerControl = containerControl;
}
private Control getOtherControl() {
return otherControl;
}
private void setOtherControl(Control containerControl) {
this.otherControl = containerControl;
}
/**
* Binds the given <code>network mode</code> value to the given
* {@link Button} when it is selected.
*
* @param button
* the {@link Button} to bind
* @param strValue
* the <code>network mode</code> to bind to the {@link Button}
* @return
*/
@SuppressWarnings("unchecked")
private Binding bindButton(final Button button, final String strValue) {
return dbc.bindValue(WidgetProperties.selection().observe(button),
BeanProperties
.value(ImageRunNetworkModel.class,
ImageRunNetworkModel.NETWORK_MODE)
.observe(model),
new UpdateValueStrategy() {
@Override
public Object convert(Object value) {
if (value.equals(Boolean.TRUE)) {
return strValue;
}
return null;
}
}, new UpdateValueStrategy() {
@Override
public Object convert(final Object value) {
return value.equals(strValue);
}
});
}
private SelectionListener onContainerSelection(final Button containerButton,
final Combo containerList) {
return new SelectionAdapter() {
@Override
public void widgetSelected(final SelectionEvent e) {
final boolean selection = containerButton.getSelection();
containerList.setEnabled(selection);
}
};
}
private SelectionListener onOtherSelection(final Button otherButton,
final Text otherText) {
return new SelectionAdapter() {
@Override
public void widgetSelected(final SelectionEvent e) {
final boolean selection = otherButton.getSelection();
otherText.setEnabled(selection);
}
};
}
private void setDefaultValues() {
try {
if (lastLaunchConfiguration != null) {
String networkModeString = lastLaunchConfiguration.getAttribute(
NETWORK_MODE, ImageRunNetworkModel.DEFAULT_MODE);
if (networkModeString
.startsWith(ImageRunNetworkModel.CONTAINER_MODE)) {
String[] token = networkModeString.split(":");
model.setNetworkMode(ImageRunNetworkModel.CONTAINER_MODE);
if (token.length > 1)
model.setSelectedContainer(token[1]);
getContainerControl().setEnabled(true);
} else {
switch (networkModeString) {
case ImageRunNetworkModel.BRIDGE_MODE:
case ImageRunNetworkModel.HOST_MODE:
case ImageRunNetworkModel.NONE_MODE:
case ImageRunNetworkModel.DEFAULT_MODE:
model.setNetworkMode(networkModeString);
break;
default:
model.setNetworkMode(ImageRunNetworkModel.OTHER_MODE);
model.setOtherString(networkModeString);
getOtherControl().setEnabled(true);
break;
}
}
}
} catch (CoreException e) {
Activator.log(e);
}
}
}