/*******************************************************************************
* 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.launch;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
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.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.linuxtools.docker.ui.Activator;
import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory;
import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunNetworkModel;
import org.eclipse.linuxtools.internal.docker.ui.wizards.WizardMessages;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
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;
public class RunImageNetworkTab extends AbstractLaunchConfigurationTab
implements PropertyChangeListener {
private static final String TAB_NAME = "RunNetworkTab.name"; //$NON-NLS-1$
private static final int INDENT = 30;
private static final int COLUMNS = 3;
private final DataBindingContext dbc = new DataBindingContext();
private final ImageRunNetworkModel model;
private Control containerControl; // control selecting container
private Control otherControl; // control selecting other selection
public RunImageNetworkTab(ImageRunNetworkModel model) {
this.model = model;
}
@Override
public void createControl(Composite parent) {
final Composite container = new Composite(parent, SWT.NONE);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).span(1, 1)
.grab(true, false).applyTo(container);
GridLayoutFactory.fillDefaults().numColumns(COLUMNS).margins(6, 6)
.applyTo(container);
if (model == null) {
setErrorMessage(LaunchMessages.getString("NoConnectionError.msg"));
} else {
setErrorMessage(null);
createNetworkSettingsSection(container);
}
setControl(container);
}
private void createNetworkSettingsSection(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$
bindButton(containerButton, ImageRunNetworkModel.CONTAINER_MODE);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.applyTo(containerButton);
// Container list
final Combo containerList = new Combo(subContainer,
SWT.DROP_DOWN | SWT.READ_ONLY);
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.bindList(WidgetProperties.items().observe(containerList),
BeanProperties
.list(ImageRunNetworkModel.class,
ImageRunNetworkModel.CONTAINER_NAMES)
.observe(model));
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));
}
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
*/
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);
}
};
}
@Override
public Image getImage() {
return SWTImagesFactory.get(SWTImagesFactory.IMG_NETWORK_TAB);
}
@Override
public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
}
@Override
public void initializeFrom(ILaunchConfiguration configuration) {
if (model == null)
return;
try {
String networkModeString = configuration.getAttribute(
IRunDockerImageLaunchConfigurationConstants.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;
}
}
// update the underlying launch config working copy on model
// changes.
model.addPropertyChangeListener(
new LaunchConfigurationChangeListener());
} catch (CoreException e) {
Activator.logErrorMessage(
LaunchMessages.getString(
"RunDockerImageLaunchConfiguration.load.failure"), //$NON-NLS-1$
e);
}
}
@Override
public void performApply(ILaunchConfigurationWorkingCopy configuration) {
if (model == null)
return;
configuration.setAttribute(
IRunDockerImageLaunchConfigurationConstants.NETWORK_MODE,
model.getNetworkModeString());
}
@Override
public boolean isValid(ILaunchConfiguration launchConfig) {
try {
if (model == null)
return false;
if (model.getNetworkMode()
.equals(ImageRunNetworkModel.CONTAINER_MODE)
&& ((Combo) getContainerControl()).getText().isEmpty()) {
setWarningMessage(WizardMessages
.getString("WarningNoContainerSelected.msg")); // $NON-NLS-1
return false;
} else if (model.getNetworkMode()
.equals(ImageRunNetworkModel.OTHER_MODE)
&& ((Text) getOtherControl()).getText().isEmpty()) {
setWarningMessage(
WizardMessages.getString("WarningOtherFieldEmpty.msg")); // $NON-NLS-1
return false;
}
} catch (Exception e) {
Activator.log(e);
return false;
}
setWarningMessage(null);
return true;
}
@Override
public String getName() {
return LaunchMessages.getString(TAB_NAME);
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
// TODO Auto-generated method stub
}
private class LaunchConfigurationChangeListener
implements PropertyChangeListener {
@Override
public void propertyChange(final PropertyChangeEvent evt) {
updateLaunchConfigurationDialog();
}
}
}