/** * Copyright (c) 2013-2016 Angelo ZERR. * 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: * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation */ package tern.eclipse.ide.ui.preferences; import org.eclipse.core.runtime.Assert; import org.eclipse.jface.preference.FieldEditor; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.FocusAdapter; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; public class StringComboFieldEditor extends FieldEditor { public static final int VALIDATE_ON_KEY_STROKE = 0; public static final int VALIDATE_ON_FOCUS_LOST = 1; public static int UNLIMITED = -1; private boolean isValid; protected String oldValue; Combo textField; private int widthInChars; private int textLimit; private String errorMessage; private boolean emptyStringAllowed; private int validateStrategy; private String[] items; protected StringComboFieldEditor(String[] items) { this.widthInChars = UNLIMITED; this.textLimit = UNLIMITED; this.emptyStringAllowed = true; this.validateStrategy = 0; this.items = items; } public StringComboFieldEditor(String name, String labelText, int width, int strategy, String[] items, Composite parent) { this.widthInChars = UNLIMITED; this.textLimit = UNLIMITED; this.emptyStringAllowed = true; this.validateStrategy = 0; init(name, labelText); this.widthInChars = width; setValidateStrategy(strategy); this.isValid = false; this.errorMessage = JFaceResources .getString("StringComboFieldEditor.errorMessage"); this.items = items; createControl(parent); } public StringComboFieldEditor(String name, String labelText, int width, String[] items, Composite parent) { this(name, labelText, width, 0, items, parent); } public StringComboFieldEditor(String name, String labelText, String[] items, Composite parent) { this(name, labelText, UNLIMITED, items, parent); } protected void adjustForNumColumns(int numColumns) { GridData gd = (GridData) this.textField.getLayoutData(); gd.horizontalSpan = (numColumns - 1); gd.grabExcessHorizontalSpace = (gd.horizontalSpan == 1); } protected boolean checkState() { boolean result = false; if (this.emptyStringAllowed) { result = true; } if (this.textField == null) { result = false; } String txt = this.textField.getText(); result = (txt.trim().length() > 0) || (this.emptyStringAllowed); result = (result) && (doCheckState()); if (result) clearErrorMessage(); else { showErrorMessage(this.errorMessage); } return result; } protected boolean doCheckState() { return true; } @Override protected void doFillIntoGrid(Composite parent, int numColumns) { getLabelControl(parent); this.textField = getTextControl(parent); GridData gd = new GridData(); gd.horizontalSpan = (numColumns - 1); if (this.widthInChars != UNLIMITED) { GC gc = new GC(this.textField); try { Point extent = gc.textExtent("X"); gd.widthHint = (this.widthInChars * extent.x); } finally { gc.dispose(); } } else { gd.horizontalAlignment = 4; gd.grabExcessHorizontalSpace = true; } this.textField.setLayoutData(gd); } @Override protected void doLoad() { if (this.textField != null) { String value = getPreferenceStore().getString(getPreferenceName()); this.textField.setText(value); this.textField.setToolTipText(value); this.oldValue = value; } } @Override protected void doLoadDefault() { if (this.textField != null) { String value = getPreferenceStore().getDefaultString( getPreferenceName()); this.textField.setText(value); this.textField.setToolTipText(value); } valueChanged(); } @Override protected void doStore() { getPreferenceStore().setValue(getPreferenceName(), this.textField.getText()); } public String getErrorMessage() { return this.errorMessage; } public int getNumberOfControls() { return 2; } public String getStringValue() { if (this.textField != null) { return this.textField.getText(); } return getPreferenceStore().getString(getPreferenceName()); } protected Combo getTextControl() { return this.textField; } public Combo getTextControl(Composite parent) { if (this.textField == null) { this.textField = new Combo(parent, SWT.NONE); this.textField.setItems(items); this.textField.setFont(parent.getFont()); switch (this.validateStrategy) { case 0: this.textField.addKeyListener(new KeyAdapter() { public void keyReleased(KeyEvent e) { StringComboFieldEditor.this.valueChanged(); } }); this.textField.addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent e) { StringComboFieldEditor.this.valueChanged(); } }); break; case 1: this.textField.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { StringComboFieldEditor.this.clearErrorMessage(); } }); this.textField.addFocusListener(new FocusAdapter() { public void focusGained(FocusEvent e) { StringComboFieldEditor.this.refreshValidState(); } public void focusLost(FocusEvent e) { StringComboFieldEditor.this.valueChanged(); StringComboFieldEditor.this.clearErrorMessage(); } }); break; default: Assert.isTrue(false, "Unknown validate strategy"); } this.textField.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent event) { StringComboFieldEditor.this.textField = null; } }); if (this.textLimit > 0) this.textField.setTextLimit(this.textLimit); } else { checkParent(this.textField, parent); } return this.textField; } public boolean isEmptyStringAllowed() { return this.emptyStringAllowed; } @Override public boolean isValid() { return this.isValid; } @Override protected void refreshValidState() { this.isValid = checkState(); } public void setEmptyStringAllowed(boolean b) { this.emptyStringAllowed = b; } public void setErrorMessage(String message) { this.errorMessage = message; } public void setFocus() { if (this.textField != null) this.textField.setFocus(); } public void setStringValue(String value) { if (this.textField != null) { if (value == null) { value = ""; } this.oldValue = this.textField.getText(); if (!(this.oldValue.equals(value))) { this.textField.setText(value); this.textField.setToolTipText(value); valueChanged(); } } } public void setTextLimit(int limit) { this.textLimit = limit; if (this.textField != null) this.textField.setTextLimit(limit); } public void setValidateStrategy(int value) { Assert.isTrue((value == 1) || (value == 0)); this.validateStrategy = value; } public void showErrorMessage() { showErrorMessage(this.errorMessage); } protected void valueChanged() { setPresentsDefaultValue(false); boolean oldState = this.isValid; refreshValidState(); if (this.isValid != oldState) { fireStateChanged("field_editor_is_valid", oldState, this.isValid); } String newValue = this.textField.getText(); if (!(newValue.equals(this.oldValue))) { fireValueChanged("field_editor_value", this.oldValue, newValue); this.oldValue = newValue; } } public void setEnabled(boolean enabled, Composite parent) { super.setEnabled(enabled, parent); getTextControl(parent).setEnabled(enabled); } }