/*******************************************************************************
* Copyright (c) 2008 Pierre-Antoine Grégoire.
* 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:
* Pierre-Antoine Grégoire - initial API and implementation
*******************************************************************************/
package org.org.eclipse.core.utils.platform.dialogs.input;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.jface.resource.JFaceColors;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
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.DirectoryDialog;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public abstract class AbstractInputTrayDialog extends TrayDialog {
public static enum FieldType {
TEXT, TEXT_AREA, MULTIPLE_CHOICE_COMBO, SINGLE_CHOICE_COMBO, FILE_CHOICE, FOLDER_CHOICE
}
private int numColumns = 2;
private String title;
private Text validationMessageLabel;
private IFieldsValidator validator;
@SuppressWarnings("rawtypes")
private Map<IFieldIdentifier, IFieldValueHolder> fieldValueHolders = new ConcurrentHashMap<IFieldIdentifier, IFieldValueHolder>();
public AbstractInputTrayDialog(IShellProvider parentShell) {
super(parentShell);
}
public AbstractInputTrayDialog(Shell shell) {
super(shell);
}
public AbstractInputTrayDialog(Shell shell, int numColumns) {
super(shell);
this.numColumns = numColumns;
}
public AbstractInputTrayDialog(Shell shell, String title) {
super(shell);
this.title = title;
}
public AbstractInputTrayDialog(Shell shell, String title, int numColums) {
super(shell);
this.title = title;
this.numColumns = numColums;
}
@Override
protected Control createDialogArea(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout(1, false);
layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
composite.setLayout(layout);
composite.setLayoutData(new GridData(GridData.FILL_BOTH));
applyDialogFont(composite);
if (title != null) {
Composite titleContainer = new Composite(composite, SWT.NONE);
titleContainer.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
titleContainer.setBackground(JFaceColors.getBannerBackground(this.getShell().getDisplay()));
titleContainer.setLayout(new GridLayout(1, false));
Label nameLabel = new Label(titleContainer, SWT.NONE);
nameLabel.setText(title);
nameLabel.setFont(JFaceResources.getFontRegistry().get(JFaceResources.BANNER_FONT));
nameLabel.setBackground(JFaceColors.getBannerBackground(this.getShell().getDisplay()));
nameLabel.setForeground(JFaceColors.getBannerForeground(this.getShell().getDisplay()));
nameLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
}
Composite fieldsContainer = new Composite(composite, SWT.BORDER);
fieldsContainer.setLayout(new GridLayout(numColumns, false));
fieldsContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
final Composite validationMessageContainer = new Composite(composite, SWT.BORDER);
validationMessageContainer.setLayout(new GridLayout(1, false));
validationMessageContainer.setBackground(JFaceColors.getBannerBackground(this.getShell().getDisplay()));
validationMessageContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
validationMessageLabel = new Text(validationMessageContainer, SWT.MULTI | SWT.READ_ONLY);
validationMessageLabel.setText("");
validationMessageLabel.setForeground(JFaceColors.getErrorText(this.getShell().getDisplay()));
validationMessageLabel.setBackground(JFaceColors.getBannerBackground(this.getShell().getDisplay()));
validationMessageLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
return fieldsContainer;
}
@Override
protected void okPressed() {
boolean validatorIssue = false;
if (validator != null) {
IValidationResult validationResult = validator.validate(fieldValueHolders);
if (validationResult.getMessage() != null) {
validatorIssue = true;
validationMessageLabel.setText(validationResult.getMessage());
getShell().layout(true);
getShell().pack(true);
}
}
if (!validatorIssue) {
super.okPressed();
}
}
protected Text createTextField(Composite composite, IFieldValueHolder<String> valueHolder, final String fieldLabel, boolean enabled) {
Label nameLabel = new Label(composite, SWT.NONE);
nameLabel.setText(fieldLabel + ":");
nameLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, 1));
Text text = new Text(composite, SWT.FLAT | SWT.BORDER);
text.setText(valueHolder.getValue());
text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, numColumns - 1, 1));
text.addModifyListener(new FieldValueModifiedListener(valueHolder));
text.setEnabled(enabled);
fieldValueHolders.put(valueHolder.getFieldId(), valueHolder);
return text;
}
protected Text createTextField(Composite composite, IFieldIdentifier fieldIdentifier, final String fieldLabel, boolean enabled) {
IFieldValueHolder<String> fieldValueHolder = new StringHolder(fieldIdentifier);
return createTextField(composite, fieldValueHolder, fieldLabel, enabled);
}
protected Text createTextField(Composite composite, IFieldValueHolder<String> valueHolder, final String fieldLabel) {
return createTextField(composite, valueHolder, fieldLabel, true);
}
protected Text createTextField(Composite composite, IFieldIdentifier fieldIdentifier, final String fieldLabel) {
return createTextField(composite, fieldIdentifier, fieldLabel, true);
}
protected Text createTextAreaField(Composite composite, IFieldValueHolder<String> valueHolder, final String fieldLabel, boolean enabled, int lines) {
Label nameLabel = new Label(composite, SWT.NONE);
nameLabel.setText(fieldLabel + ":");
nameLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, 1));
Text text = new Text(composite, SWT.FLAT | SWT.BORDER | SWT.MULTI);
GC gc = new GC(text);
FontMetrics fm = gc.getFontMetrics();
gc.dispose();
int height = lines * fm.getHeight();
text.setText(valueHolder.getValue());
GridData gridLayoutData = new GridData(SWT.FILL, SWT.CENTER, true, false, numColumns - 1, 1);
gridLayoutData.heightHint = height;
text.setLayoutData(gridLayoutData);
text.addModifyListener(new FieldValueModifiedListener(valueHolder));
text.setEnabled(enabled);
fieldValueHolders.put(valueHolder.getFieldId(), valueHolder);
return text;
}
protected Text createTextAreaField(Composite composite, IFieldIdentifier fieldIdentifier, final String fieldLabel, boolean enabled, int lines) {
IFieldValueHolder<String> fieldValueHolder = new StringHolder(fieldIdentifier);
return createTextAreaField(composite, fieldValueHolder, fieldLabel, enabled, lines);
}
protected Text createTextAreaField(Composite composite, IFieldValueHolder<String> valueHolder, final String fieldLabel, int lines) {
return createTextAreaField(composite, valueHolder, fieldLabel, true, lines);
}
protected Text createTextAreaField(Composite composite, IFieldIdentifier fieldIdentifier, final String fieldLabel, int lines) {
return createTextAreaField(composite, fieldIdentifier, fieldLabel, true, lines);
}
protected List createMultipleChoiceComboField(Composite composite, IFieldValueHolder<String[]> valueHolder, final String fieldLabel, String[] comboContents) {
Label nameLabel = new Label(composite, SWT.NONE);
nameLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, 1));
nameLabel.setText(fieldLabel + ":");
List list = new List(composite, SWT.MULTI | SWT.BORDER);
list.setItems(comboContents);
list.addSelectionListener(new ListValuesSelectionListener(valueHolder));
GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false, numColumns - 1, 1);
gridData.heightHint = 80;
list.setLayoutData(gridData);
fieldValueHolders.put(valueHolder.getFieldId(), valueHolder);
return list;
}
protected Combo createSingleChoiceComboField(Composite composite, IFieldValueHolder<String> valueHolder, final String fieldLabel, String[] comboContents) {
Label nameLabel = new Label(composite, SWT.NONE);
nameLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, 1));
nameLabel.setText(fieldLabel + ":");
Combo combo = new Combo(composite, SWT.SINGLE);
combo.setItems(comboContents);
combo.addModifyListener(new FieldValueModifiedListener(valueHolder));
combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, numColumns - 1, 1));
fieldValueHolders.put(valueHolder.getFieldId(), valueHolder);
return combo;
}
protected Text createFolderChoiceField(final Composite composite, IFieldValueHolder<String> valueHolder, final String fieldLabel, boolean enabled) {
Label nameLabel = new Label(composite, SWT.NONE);
nameLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, 1));
nameLabel.setText(fieldLabel + ":");
int textFlags = SWT.FLAT | SWT.BORDER;
if (!enabled) {
textFlags |= SWT.READ_ONLY;
}
final Text text = new Text(composite, textFlags);
text.addModifyListener(new FieldValueModifiedListener(valueHolder));
text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, numColumns - 2, 1));
text.setText(valueHolder.getValue());
Button button = new Button(composite, SWT.FLAT);
button.setText("Browse...");
button.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
widgetDefaultSelected(e);
}
public void widgetDefaultSelected(SelectionEvent e) {
DirectoryDialog directoryDialog = new DirectoryDialog(composite.getShell());
String file = directoryDialog.open();
if (file != null) {
text.setText(file);
}
}
});
fieldValueHolders.put(valueHolder.getFieldId(), valueHolder);
return text;
}
protected Combo createSingleChoiceComboField(Composite composite, IFieldValueHolder<String> valueHolder, final String fieldLabel, String[] comboValues, Map<String, String> valuesMapping) {
Label nameLabel = new Label(composite, SWT.NONE);
nameLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, 1));
nameLabel.setText(fieldLabel + ":");
Combo combo = new Combo(composite, SWT.SINGLE);
combo.setItems(comboValues);
combo.addModifyListener(new FieldValueModifiedListener(valueHolder, valuesMapping));
combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, numColumns - 1, 1));
fieldValueHolders.put(valueHolder.getFieldId(), valueHolder);
return combo;
}
protected Text createFileChoiceField(Composite composite, IFieldValueHolder<String> valueHolder, String fieldLabel, boolean enabled, String[] filterExtensions) {
Label nameLabel = new Label(composite, SWT.NONE);
nameLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, 1));
nameLabel.setText(fieldLabel + ":");
int textFlags = SWT.FLAT | SWT.BORDER;
if (!enabled) {
textFlags |= SWT.READ_ONLY;
}
final Text text = new Text(composite, textFlags);
text.setText(valueHolder.getValue());
text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, numColumns - 2, 1));
text.addModifyListener(new FieldValueModifiedListener(valueHolder));
Button button = new Button(composite, SWT.FLAT);
button.setText("Browse...");
button.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false, 1, 1));
button.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
button.addMouseListener(new MouseListener() {
public void mouseUp(MouseEvent e) {
FileDialog fileDialog = new FileDialog(getShell());
fileDialog.setFilterExtensions(new String[] { "*.xml" });
String file = fileDialog.open();
if (file != null) {
text.setText(file);
}
getShell().layout(true);
getShell().pack(true);
}
public void mouseDown(MouseEvent e) {
}
public void mouseDoubleClick(MouseEvent e) {
}
});
button.addKeyListener(new KeyListener() {
public void keyReleased(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
if (e.character == ' ' || e.character == SWT.KEYPAD_CR) {
FileDialog fileDialog = new FileDialog(getShell());
fileDialog.setFilterExtensions(new String[] { "*.xml" });
String file = fileDialog.open();
if (file != null) {
text.setText(file);
}
getShell().layout(true);
getShell().pack(true);
}
}
});
fieldValueHolders.put(valueHolder.getFieldId(), valueHolder);
text.setEnabled(enabled);
return text;
}
public int getNumColumns() {
return numColumns;
}
public String getValidationMessage() {
return validationMessageLabel.getText();
}
public void setValidationMessage(String validationMessage) {
if (validationMessageLabel != null) {
validationMessageLabel.setText(validationMessage);
}
}
public IFieldsValidator getValidator() {
return validator;
}
public void setValidator(IFieldsValidator validator) {
this.validator = validator;
}
@SuppressWarnings("rawtypes")
public IFieldValueHolder getFieldValueHolder(IFieldIdentifier fieldIdentifier) {
return fieldValueHolders.get(fieldIdentifier);
}
public Object getFieldValueHolderValue(IFieldIdentifier fieldIdentifier) {
if (fieldValueHolders.get(fieldIdentifier) == null) {
throw new IllegalStateException("Field has not yet been created, open dialog first");
}
return fieldValueHolders.get(fieldIdentifier).getValue();
}
}