blob: adffce5bd2d4198389346c5606b97a127c00187f [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.AutoCompleteField;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
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.TextContentAdapter;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
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.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 abstract class FieldAssistTestDialog 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 {
// Cast to different types by each subclass
Object decImpl;
Control control;
IControlContentAdapter contentAdapter;
FieldDecoration errorDecoration, warningDecoration;
SmartField(Object decImpl, Control control,
IControlContentAdapter adapter) {
this.decImpl = decImpl;
this.contentAdapter = adapter;
this.control = control;
}
boolean isRequiredField() {
return true;
}
boolean hasContentAssist() {
return false;
}
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;
}
String getContents() {
return contentAdapter.getControlContents(control);
}
abstract boolean isValid();
abstract boolean isWarning();
String getErrorMessage() {
return null;
}
String getWarningMessage() {
return null;
}
}
class UserField extends SmartField {
UserField(Object decImpl, Control control,
IControlContentAdapter adapter) {
super(decImpl, control, 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;
}
boolean hasContentAssist() {
return true;
}
}
class AgeField extends SmartField {
AgeField(Object decImpl, Control control, IControlContentAdapter adapter) {
super(decImpl, control, adapter);
}
boolean isValid() {
// We seed the spinner with valid values always.
return true;
}
boolean isWarning() {
Spinner spinner = (Spinner) control;
return spinner.getSelection() > 65;
}
String getWarningMessage() {
return TaskAssistExampleMessages.ExampleDialog_AgeWarning;
}
}
String[] validUsers = { "tom", "dick", "harry", "ferdinand", "tim",
"teresa", "tori", "daniela", "aaron", "kevin", "tod", "mike",
"kim", "eric", "paul" };
String triggerKey;
String username;
boolean showErrorDecoration, showErrorMessage, showErrorColor,
showWarningDecoration, showRequiredFieldColor,
showRequiredFieldDecoration, showRequiredFieldLabelIndicator,
showSecondaryPopup, showContentAssist;
int marginWidth;
Color defaultTextColor, errorColor;
/**
* Open the exapmle dialog.
*
* @param parent
* the parent shell
* @param username
* the default username
*/
public FieldAssistTestDialog(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);
createSecurityGroup(outer);
// Create a simple field to show how field assist can be used for
// autocomplete.
Group autoComplete = new Group(outer, SWT.NONE);
autoComplete.setLayoutData(new GridData(GridData.FILL_BOTH));
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);
autoComplete.setLayout(layout);
autoComplete
.setText(TaskAssistExampleMessages.ExampleDialog_AutoCompleteGroup);
Label label = new Label(autoComplete, SWT.LEFT);
label.setText(TaskAssistExampleMessages.ExampleDialog_UserName);
// Create an auto-complete field representing a user name
Text text = new Text(autoComplete, SWT.BORDER);
text.setLayoutData(getFieldGridData());
new AutoCompleteField(text, new TextContentAdapter(), validUsers);
Dialog.applyDialogFont(outer);
return outer;
}
abstract void createSecurityGroup(Composite parent);
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);
showRequiredFieldLabelIndicator = store
.getBoolean(PreferenceConstants.PREF_SHOWREQUIREDFIELDLABELINDICATOR);
showSecondaryPopup = store
.getBoolean(PreferenceConstants.PREF_SHOWSECONDARYPOPUP);
showContentAssist = store
.getBoolean(PreferenceConstants.PREF_SHOWCONTENTPROPOSALCUE);
triggerKey = store.getString(PreferenceConstants.PREF_CONTENTASSISTKEY);
marginWidth = store
.getInt(PreferenceConstants.PREF_DECORATOR_MARGINWIDTH);
}
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;
}
FieldDecoration getWarningDecoration() {
return FieldDecorationRegistry.getDefault().getFieldDecoration(
FieldDecorationRegistry.DEC_WARNING);
}
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 (showContentAssist && smartField.hasContentAssist()) {
showContentAssistDecoration(smartField, true);
} else {
showContentAssistDecoration(smartField, false);
showRequiredFieldDecoration(smartField,
showRequiredFieldDecoration);
}
}
}
}
GridData getFieldGridData() {
int margin = FieldDecorationRegistry.getDefault()
.getMaximumDecorationWidth();
GridData data = new GridData();
data.horizontalAlignment = SWT.FILL;
data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH + margin;
data.horizontalIndent = margin;
data.grabExcessHorizontalSpace = true;
return data;
}
abstract void showRequiredFieldDecoration(SmartField smartField,
boolean show);
abstract void showContentAssistDecoration(SmartField smartField,
boolean show);
void handleFocusGained(SmartField smartField) {
// only set color if error color not already showing
if (showErrorColor && !smartField.isValid())
return;
if (showRequiredFieldColor && smartField.isRequiredField()) {
smartField.control.setBackground(defaultTextColor);
}
}
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.control.setBackground(FieldAssistColors
.getRequiredFieldBackgroundColor(smartField.control));
}
}
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) {
showErrorDecoration(smartField, true);
}
if (showErrorColor) {
smartField.control.setBackground(getErrorColor(smartField.control));
}
}
abstract void showErrorDecoration(SmartField smartField, boolean show);
void hideError(SmartField smartField) {
if (showErrorMessage) {
this.updateStatus(Status.OK_STATUS);
}
if (showErrorDecoration) {
showErrorDecoration(smartField, false);
}
if (showErrorColor) {
smartField.control.setBackground(defaultTextColor);
}
}
void showWarning(SmartField smartField) {
if (showWarningDecoration) {
showWarningDecoration(smartField, true);
}
}
void hideWarning(SmartField smartField) {
if (showWarningDecoration) {
showWarningDecoration(smartField, false);
}
}
abstract void showWarningDecoration(SmartField smartField, boolean show);
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) {
public void closeProposalPopup() {
closeProposalPopup();
}
};
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 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();
}
void addRequiredFieldIndicator(Label label) {
String text = label.getText();
// This concatenation could be done by a field assist helper.
text = text.concat("*");
label.setText(text);
}
FieldDecoration getRequiredFieldDecoration() {
return FieldDecorationRegistry.getDefault().getFieldDecoration(
FieldDecorationRegistry.DEC_REQUIRED);
}
int getDecorationLocationBits() {
IPreferenceStore store = FieldAssistPlugin.getDefault()
.getPreferenceStore();
int bits = 0;
String vert = store
.getString(PreferenceConstants.PREF_DECORATOR_VERTICALLOCATION);
if (vert
.equals(PreferenceConstants.PREF_DECORATOR_VERTICALLOCATION_BOTTOM)) {
bits = SWT.BOTTOM;
} else if (vert
.equals(PreferenceConstants.PREF_DECORATOR_VERTICALLOCATION_CENTER)) {
bits = SWT.CENTER;
} else {
bits = SWT.TOP;
}
String horz = store
.getString(PreferenceConstants.PREF_DECORATOR_HORIZONTALLOCATION);
if (horz
.equals(PreferenceConstants.PREF_DECORATOR_HORIZONTALLOCATION_RIGHT)) {
bits |= SWT.RIGHT;
} else {
bits |= SWT.LEFT;
}
return bits;
}
}