blob: adc264818988d9d870f1d38687f34ba29d444105 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006 IBM Corporation 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:
* IBM Corporation - initial API and implementation
* Sebastian Davids <sdavids@gmx.de> - bug 132479 - [FieldAssist] Field assist example improvements
*******************************************************************************/
package org.eclipse.ui.examples.fieldassist;
import java.text.MessageFormat;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.bindings.keys.ParseException;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.StatusDialog;
import org.eclipse.jface.fieldassist.ComboContentAdapter;
import org.eclipse.jface.fieldassist.ComboControlCreator;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.fieldassist.DecoratedField;
import org.eclipse.jface.fieldassist.FieldAssistColors;
import org.eclipse.jface.fieldassist.FieldDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.fieldassist.IContentProposal;
import org.eclipse.jface.fieldassist.IContentProposalProvider;
import org.eclipse.jface.fieldassist.IControlContentAdapter;
import org.eclipse.jface.fieldassist.IControlCreator;
import org.eclipse.jface.fieldassist.TextContentAdapter;
import org.eclipse.jface.fieldassist.TextControlCreator;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.examples.fieldassist.preferences.PreferenceConstants;
/**
* Example dialog that shows different field assist capabilities.
*/
public class ExampleDialog extends StatusDialog {
class SpinnerContentAdapter implements IControlContentAdapter {
// We are only implementing this for our internal use, not for
// content assist, so many of the methods are ignored.
public String getControlContents(Control control) {
return new Integer(((Spinner) control).getSelection()).toString();
}
public void setControlContents(Control control, String text,
int cursorPosition) {
// ignore
}
public void insertControlContents(Control control, String text,
int cursorPosition) {
// ignore
}
public int getCursorPosition(Control control) {
// ignore
return 0;
}
public Rectangle getInsertionBounds(Control control) {
return control.getBounds();
}
public void setCursorPosition(Control control, int index) {
// ignore
}
}
abstract class SmartField {
DecoratedField field;
IControlContentAdapter contentAdapter;
FieldDecoration errorDecoration, warningDecoration;
SmartField(DecoratedField field, IControlContentAdapter adapter) {
this.field = field;
this.contentAdapter = adapter;
}
String getContents() {
return contentAdapter.getControlContents(field.getControl());
}
boolean isRequiredField() {
return true;
}
FieldDecoration getErrorDecoration() {
if (errorDecoration == null) {
FieldDecoration standardError = FieldDecorationRegistry
.getDefault().getFieldDecoration(
FieldDecorationRegistry.DEC_ERROR);
if (getErrorMessage() == null) {
errorDecoration = standardError;
} else {
errorDecoration = new FieldDecoration(standardError
.getImage(), getErrorMessage());
}
}
return errorDecoration;
}
FieldDecoration getWarningDecoration() {
if (warningDecoration == null) {
FieldDecoration standardWarning = FieldDecorationRegistry
.getDefault().getFieldDecoration(
FieldDecorationRegistry.DEC_WARNING);
if (getWarningMessage() == null) {
warningDecoration = standardWarning;
} else {
warningDecoration = new FieldDecoration(standardWarning
.getImage(), getWarningMessage());
}
}
return warningDecoration;
}
abstract boolean isValid();
abstract boolean isWarning();
String getErrorMessage() {
return null;
}
String getWarningMessage() {
return null;
}
}
class UserField extends SmartField {
UserField(DecoratedField field, IControlContentAdapter adapter) {
super(field, adapter);
}
boolean isValid() {
String contents = getContents();
for (int i = 0; i < contents.length(); i++) {
if (!Character.isLetter(contents.charAt(i))) {
return false;
}
}
return true;
}
String getErrorMessage() {
return TaskAssistExampleMessages.ExampleDialog_UserError;
}
boolean isWarning() {
return getContents().equals(
TaskAssistExampleMessages.ExampleDialog_WarningName);
}
String getWarningMessage() {
return TaskAssistExampleMessages.ExampleDialog_UserWarning;
}
}
class AgeField extends SmartField {
AgeField(DecoratedField field, IControlContentAdapter adapter) {
super(field, adapter);
}
boolean isValid() {
// We seed the spinner with valid values always.
return true;
}
boolean isWarning() {
Spinner spinner = (Spinner) field.getControl();
return spinner.getSelection() > 65;
}
String getWarningMessage() {
return TaskAssistExampleMessages.ExampleDialog_AgeWarning;
}
}
private String[] validUsers = { "tom", "dick", "harry", "ferdinand", "tim", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
"teresa", "tori", "daniela" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
private String triggerKey;
private String username;
private boolean showErrorDecoration, showErrorMessage, showErrorColor,
showWarningDecoration, showRequiredFieldColor,
showRequiredFieldDecoration, showSecondaryPopup;
private Color defaultTextColor, errorColor;
/**
* Open the exapmle dialog.
* @param parent the parent shell
* @param username the default username
*/
public ExampleDialog(Shell parent, String username) {
super(parent);
setTitle(TaskAssistExampleMessages.ExampleDialog_Title);
this.username = username;
getPreferenceValues();
}
protected Control createDialogArea(Composite parent) {
Composite outer = (Composite) super.createDialogArea(parent);
initializeDialogUnits(outer);
Group main = new Group(outer, SWT.NONE);
main.setLayoutData(new GridData(GridData.FILL_BOTH));
main.setText(TaskAssistExampleMessages.ExampleDialog_SecurityGroup);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
main.setLayout(layout);
Label label = new Label(main, SWT.LEFT);
label.setText(TaskAssistExampleMessages.ExampleDialog_UserName);
IPreferenceStore store = FieldAssistPlugin.getDefault()
.getPreferenceStore();
// Create a field representing a user name
DecoratedField field = new DecoratedField(main, SWT.BORDER,
new TextControlCreator());
final SmartField textField = new UserField(field,
new TextContentAdapter());
if (store.getBoolean(PreferenceConstants.PREF_SHOWCONTENTPROPOSALCUE)) {
field.addFieldDecoration(getCueDecoration(), SWT.TOP | SWT.LEFT,
true);
}
if (showRequiredFieldDecoration && textField.isRequiredField()) {
field.addFieldDecoration(getRequiredFieldDecoration(), SWT.BOTTOM
| SWT.LEFT, false);
}
Text text = (Text) field.getControl();
defaultTextColor = text.getBackground();
text.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent event) {
handleModify(textField);
}
});
text.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent event) {
handleFocusGained(textField);
}
public void focusLost(FocusEvent event) {
handleFocusLost(textField);
}
});
text.setText(username);
installContentProposalAdapter(text, new TextContentAdapter());
field.getLayoutControl().setLayoutData(getDecoratedFieldGridData());
// prime the required field color by calling the focus lost handler.
handleFocusLost(textField);
label = new Label(main, SWT.LEFT);
label.setText(TaskAssistExampleMessages.ExampleDialog_ComboUserName);
// Create a combo field representing a user name
field = new DecoratedField(main, SWT.BORDER | SWT.DROP_DOWN,
new ComboControlCreator());
final SmartField comboField = new UserField(field,
new ComboContentAdapter());
if (store.getBoolean(PreferenceConstants.PREF_SHOWCONTENTPROPOSALCUE)) {
field.addFieldDecoration(getCueDecoration(), SWT.TOP | SWT.LEFT,
true);
}
if (showRequiredFieldDecoration) {
field.addFieldDecoration(getRequiredFieldDecoration(), SWT.BOTTOM
| SWT.LEFT, false);
}
Combo combo = (Combo) field.getControl();
combo.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent event) {
handleModify(comboField);
}
});
combo.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent event) {
handleFocusGained(comboField);
}
public void focusLost(FocusEvent event) {
handleFocusLost(comboField);
}
});
combo.setText(username);
combo.setItems(validUsers);
field.getLayoutControl().setLayoutData(getDecoratedFieldGridData());
installContentProposalAdapter(combo, new ComboContentAdapter());
// prime the required field color by calling the focus lost handler.
handleFocusLost(comboField);
// Create a spinner representing a user age
label = new Label(main, SWT.LEFT);
label.setText(TaskAssistExampleMessages.ExampleDialog_Age);
field = new DecoratedField(main, SWT.BORDER, new IControlCreator() {
public Control createControl(Composite parent, int style) {
return new Spinner(parent, style);
}
});
if (showRequiredFieldDecoration) {
field.addFieldDecoration(getRequiredFieldDecoration(), SWT.BOTTOM
| SWT.LEFT, false);
}
final SmartField spinnerField = new AgeField(field,
new SpinnerContentAdapter());
Spinner spinner = (Spinner) field.getControl();
spinner.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent event) {
handleModify(spinnerField);
}
});
combo.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent event) {
handleFocusGained(spinnerField);
}
public void focusLost(FocusEvent event) {
handleFocusLost(spinnerField);
}
});
spinner.setSelection(40);
field.getLayoutControl().setLayoutData(getDecoratedFieldGridData());
// prime the required field color by calling the focus lost handler.
handleFocusLost(spinnerField);
// This field is not managed by a decorated field
label = new Label(main, SWT.LEFT);
label.setText(TaskAssistExampleMessages.ExampleDialog_Password);
// We need to indent the field by the size of the decoration.
text = new Text(main, SWT.BORDER);
text.setText("******"); //$NON-NLS-1$
text.setLayoutData(getNonDecoratedFieldGridData());
Dialog.applyDialogFont(outer);
return main;
}
private void getPreferenceValues() {
IPreferenceStore store = FieldAssistPlugin.getDefault()
.getPreferenceStore();
showErrorMessage = store
.getBoolean(PreferenceConstants.PREF_SHOWERRORMESSAGE);
showErrorDecoration = store
.getBoolean(PreferenceConstants.PREF_SHOWERRORDECORATION);
showErrorColor = store
.getBoolean(PreferenceConstants.PREF_SHOWERRORCOLOR);
showWarningDecoration = store
.getBoolean(PreferenceConstants.PREF_SHOWWARNINGDECORATION);
showRequiredFieldColor = store
.getBoolean(PreferenceConstants.PREF_SHOWREQUIREDFIELDCOLOR);
showRequiredFieldDecoration = store
.getBoolean(PreferenceConstants.PREF_SHOWREQUIREDFIELDDECORATION);
showSecondaryPopup = store
.getBoolean(PreferenceConstants.PREF_SHOWSECONDARYPOPUP);
triggerKey = store.getString(PreferenceConstants.PREF_CONTENTASSISTKEY);
}
private FieldDecoration getCueDecoration() {
// We use our own decoration which is based on the JFace version.
FieldDecorationRegistry registry = FieldDecorationRegistry.getDefault();
FieldDecoration dec = registry
.getFieldDecoration(FieldAssistPlugin.DEC_CONTENTASSIST);
if (dec == null) {
// Get the standard one. We use its image and our own customized
// text.
FieldDecoration standardDecoration = registry
.getFieldDecoration(FieldDecorationRegistry.DEC_CONTENT_PROPOSAL);
registry.registerFieldDecoration(
FieldAssistPlugin.DEC_CONTENTASSIST, NLS.bind(
TaskAssistExampleMessages.Decorator_ContentAssist,
triggerKey), standardDecoration.getImage());
dec = registry
.getFieldDecoration(FieldAssistPlugin.DEC_CONTENTASSIST);
}
return dec;
}
private FieldDecoration getWarningDecoration() {
return FieldDecorationRegistry.getDefault().getFieldDecoration(
FieldDecorationRegistry.DEC_WARNING);
}
private FieldDecoration getRequiredFieldDecoration() {
return FieldDecorationRegistry.getDefault().getFieldDecoration(
FieldDecorationRegistry.DEC_REQUIRED);
}
private void handleModify(SmartField smartField) {
// Error indicator supercedes all others
if (!smartField.isValid()) {
showError(smartField);
} else {
hideError(smartField);
if (smartField.isWarning()) {
showWarning(smartField);
} else {
hideWarning(smartField);
if (smartField.isRequiredField()) {
smartField.field.addFieldDecoration(
getRequiredFieldDecoration(),
SWT.BOTTOM | SWT.LEFT, false);
}
}
}
}
private void handleFocusGained(SmartField smartField) {
// only set color if error color not already showing
if (showErrorColor && !smartField.isValid())
return;
if (showRequiredFieldColor && smartField.isRequiredField()) {
smartField.field.getControl().setBackground(defaultTextColor);
}
}
private void handleFocusLost(SmartField smartField) {
// only set color if error color not showing
if (showErrorColor && !smartField.isValid())
return;
if (showRequiredFieldColor && smartField.isRequiredField()
&& smartField.getContents().length() == 0) {
smartField.field.getControl().setBackground(
FieldAssistColors
.getRequiredFieldBackgroundColor(smartField.field
.getControl()));
}
}
private void showError(SmartField smartField) {
FieldDecoration dec = smartField.getErrorDecoration();
if (showErrorMessage) {
updateStatus(new Status(IStatus.ERROR,
"org.eclipse.examples.contentassist", 0, dec //$NON-NLS-1$
.getDescription(), null));
}
if (showErrorDecoration) {
smartField.field.addFieldDecoration(dec, SWT.BOTTOM | SWT.LEFT,
false);
}
if (showErrorColor) {
smartField.field.getControl().setBackground(
getErrorColor(smartField.field.getControl()));
}
}
private void hideError(SmartField smartField) {
FieldDecoration dec = smartField.getErrorDecoration();
if (showErrorMessage) {
this.updateStatus(Status.OK_STATUS);
}
if (showErrorDecoration) {
smartField.field.hideDecoration(dec);
}
if (showErrorColor) {
smartField.field.getControl().setBackground(defaultTextColor);
}
}
private void showWarning(SmartField smartField) {
if (showWarningDecoration) {
FieldDecoration dec = smartField.getWarningDecoration();
smartField.field.addFieldDecoration(dec, SWT.BOTTOM | SWT.LEFT,
false);
}
}
private void hideWarning(SmartField smartField) {
if (showWarningDecoration) {
smartField.field.hideDecoration(getWarningDecoration());
}
}
private void installContentProposalAdapter(Control control, IControlContentAdapter contentAdapter) {
IPreferenceStore store = FieldAssistPlugin.getDefault()
.getPreferenceStore();
boolean propagate = store
.getBoolean(PreferenceConstants.PREF_CONTENTASSISTKEY_PROPAGATE);
KeyStroke keyStroke;
char[] autoActivationCharacters = null;
int autoActivationDelay = store
.getInt(PreferenceConstants.PREF_CONTENTASSISTDELAY);
if (triggerKey.equals(PreferenceConstants.PREF_CONTENTASSISTKEYAUTO)) {
// null means automatically assist when character typed
keyStroke = null;
} else if (triggerKey
.equals(PreferenceConstants.PREF_CONTENTASSISTKEYAUTOSUBSET)) {
keyStroke = null;
autoActivationCharacters = new char[] { 't', 'd' };
} else {
try {
keyStroke = KeyStroke.getInstance(triggerKey);
} catch (ParseException e) {
keyStroke = KeyStroke.getInstance(SWT.F10);
}
}
ContentProposalAdapter adapter = new ContentProposalAdapter(control,
contentAdapter, getContentProposalProvider(),
keyStroke, autoActivationCharacters);
adapter.setAutoActivationDelay(autoActivationDelay);
adapter.setPropagateKeys(propagate);
adapter.setFilterStyle(getContentAssistFilterStyle());
adapter.setProposalAcceptanceStyle(getContentAssistAcceptance());
}
private IContentProposalProvider getContentProposalProvider() {
return new IContentProposalProvider() {
public IContentProposal[] getProposals(String contents, int position) {
IContentProposal[] proposals = new IContentProposal[validUsers.length];
for (int i = 0; i < validUsers.length; i++) {
final String user = validUsers[i];
proposals[i] = new IContentProposal() {
public String getContent() {
return user;
}
public String getLabel() {
return user;
}
public String getDescription() {
if (showSecondaryPopup)
return MessageFormat
.format(
TaskAssistExampleMessages.ExampleDialog_ProposalDescription,
new String[] { user });
return null;
}
public int getCursorPosition() {
return user.length();
}
};
}
return proposals;
}
};
}
private int getContentAssistAcceptance() {
IPreferenceStore store = FieldAssistPlugin.getDefault()
.getPreferenceStore();
String acceptanceStyle = store
.getString(PreferenceConstants.PREF_CONTENTASSISTRESULT);
if (acceptanceStyle
.equals(PreferenceConstants.PREF_CONTENTASSISTRESULT_INSERT))
return ContentProposalAdapter.PROPOSAL_INSERT;
if (acceptanceStyle
.equals(PreferenceConstants.PREF_CONTENTASSISTRESULT_REPLACE))
return ContentProposalAdapter.PROPOSAL_REPLACE;
return ContentProposalAdapter.PROPOSAL_IGNORE;
}
private int getContentAssistFilterStyle() {
IPreferenceStore store = FieldAssistPlugin.getDefault()
.getPreferenceStore();
String acceptanceStyle = store
.getString(PreferenceConstants.PREF_CONTENTASSISTFILTER);
if (acceptanceStyle
.equals(PreferenceConstants.PREF_CONTENTASSISTFILTER_CHAR))
return ContentProposalAdapter.FILTER_CHARACTER;
if (acceptanceStyle
.equals(PreferenceConstants.PREF_CONTENTASSISTFILTER_CUMULATIVE))
return ContentProposalAdapter.FILTER_CUMULATIVE;
return ContentProposalAdapter.FILTER_NONE;
}
private GridData getDecoratedFieldGridData() {
return new GridData(IDialogConstants.ENTRY_FIELD_WIDTH, SWT.DEFAULT);
}
private GridData getNonDecoratedFieldGridData() {
GridData data = new GridData();
data.horizontalAlignment = SWT.FILL;
data.horizontalIndent = FieldDecorationRegistry.getDefault()
.getMaximumDecorationWidth();
return data;
}
private Color getErrorColor(Control control) {
if (errorColor == null) {
RGB rgb = FieldAssistColors.computeErrorFieldBackgroundRGB(control);
errorColor = new Color(control.getDisplay(), rgb);
}
return errorColor;
}
public boolean close() {
if (errorColor != null) {
errorColor.dispose();
}
return super.close();
}
}