/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.model.ui.attribute.editor; import org.eclipse.core.runtime.Assert; 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.FocusListener; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Text; import org.jboss.tools.common.MethodNotImplementedException; import org.jboss.tools.common.model.ui.widgets.BorderedControl; import org.jboss.tools.common.model.ui.widgets.IWidgetSettings; import org.jboss.tools.common.model.ui.widgets.ScrolledComposite; import org.jboss.tools.common.model.ui.widgets.border.Border; public class StringFieldEditor extends ExtendedFieldEditor { 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; private String oldValue; private Text textField; // real text control private Control textControl; // maybe border control with text control inside private int charCapacity = UNLIMITED; private int textLimit = UNLIMITED; private String error; private boolean emptyStringAllowed = true; private int validateStrategy= VALIDATE_ON_KEY_STROKE; public StringFieldEditor() {} public StringFieldEditor(IWidgetSettings settings) { super(settings); } protected void adjustForNumColumns(int numColumns) { GridData gd = (GridData)textField.getLayoutData(); gd.horizontalSpan = numColumns - 1; // We only grab excess space if we have to // If another field editor has more columns then // we assume it is setting the width. gd.grabExcessHorizontalSpace = gd.horizontalSpan == 1; } protected boolean validate() { boolean result = false; if (emptyStringAllowed) result = true; if (textField == null) { result = false; return result; } String txt = textField.getText(); if (txt == null) { result = false; } else { result = (txt.trim().length() > 0) || emptyStringAllowed; } result = result && doValidate(); if (result) clearErrorMessage(); else showErrorMessage(error); return result; } protected boolean doValidate() { return true; } protected void doFillIntoGrid(Composite parent, int numColumns) { getLabelComposite(parent); createTextControl(parent); GridData gd = new GridData(); gd.horizontalSpan = numColumns - 1; if (charCapacity != UNLIMITED) { GC gc = new GC(textField); try { Point extent = gc.textExtent("X");//$NON-NLS-1$ gd.widthHint = charCapacity * extent.x; } finally { gc.dispose(); } } else { gd.horizontalAlignment = GridData.FILL; gd.grabExcessHorizontalSpace = true; } textField.setLayoutData(gd); } protected void doLoad() { throw new MethodNotImplementedException(); } protected void doLoadDefault() { throw new MethodNotImplementedException(); } protected void doStore() { getPreferenceStore().setValue(getPreferenceName(), textField.getText()); } public int getNumberOfControls() { return 2; } public String getStringValue() { if (textField != null) return textField.getText(); else return getPreferenceStore().getString(getPreferenceName()); } protected Text getTextField() { return textField; } protected Control getTextControl() { return textControl; } public Control createTextControl(Composite parent) { ///do not restore this assignment! glory ///textControl = textField; if (textField == null) { int style = getSettings().getStyle("Text.Style"); //$NON-NLS-1$ if (style==SWT.DEFAULT) style = SWT.NONE; /// Color bg = getSettings().getColor("Text.Background"); Color fg = getSettings().getColor("Text.Foreground"); //$NON-NLS-1$ Font font = getSettings().getFont("Text.Font"); //$NON-NLS-1$ Border border = getSettings().getBorder("Text.Border"); //$NON-NLS-1$ boolean readOnly = isAlwaysReadOnly(); if (border != null) { if(readOnly) style |= SWT.READ_ONLY; BorderedControl borderedControl = new BorderedControl(parent, SWT.NONE, border); textField = new Text(borderedControl, style); textControl = borderedControl; } else { int style2 = SWT.BORDER; if(readOnly) style2 |= SWT.READ_ONLY; textField = new Text(parent, style2); textControl = textField; } textField.setFont(font); /// textField.setBackground(bg); textField.setForeground(fg); switch (validateStrategy) { case VALIDATE_ON_KEY_STROKE : textField.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { valueChanged(); } }); textField.addFocusListener(new FocusAdapter() { public void focusGained(FocusEvent e) { refreshValidState(); } public void focusLost(FocusEvent e) { clearErrorMessage(); } }); break; case VALIDATE_ON_FOCUS_LOST : textField.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { clearErrorMessage(); } }); textField.addFocusListener(new FocusAdapter() { public void focusGained(FocusEvent e) { refreshValidState(); } public void focusLost(FocusEvent e) { valueChanged(); clearErrorMessage(); } }); break; default : Assert.isTrue(false, "Unknown validate strategy");//$NON-NLS-1$ } textField.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent event) { textField = null; } }); if(textLimit > 0){//Only set limits above 0 - see SWT spec textField.setTextLimit(textLimit); } addContentAssist(textField); } else { checkParent(textControl, parent); } //SampleContentAssistentProcessor �ontentProcessor = new SampleContentAssistentProcessor(); //ControlContentAssistHelper.createTextContentAssistant(getTextField(), �ontentProcessor); textField.addFocusListener(new FocusListener() { public void focusGained(FocusEvent e) { if(textField == null || textField.isDisposed()) return; ScrolledComposite.scrollToVisible(textField, new Rectangle(0, 0, textField.getBounds().width, textField.getBounds().height)); } public void focusLost(FocusEvent e) { } }); return textControl; } protected void addContentAssist(Text text) {} /** * We cannot controls to provide READ-ONLY property on the fly. * Instead, let us at least create it as READ-ONLY when it has * no chance to get editable, for instance, if object to edit * is from jar. * @return */ protected boolean isAlwaysReadOnly() { return false; } public boolean isEmptyStringAllowed() { return emptyStringAllowed; } public boolean isValid() { return isValid; } protected void refreshValidState() { isValid = validate(); } public void setEmptyStringAllowed(boolean b) { emptyStringAllowed = b; } public void setErrorMessage(String message) { error = message; } public void setFocus() { if (textField != null) { textField.setSelection(0, textField.getText().length()); textField.setFocus(); } } public void setStringValue(String value) { if (textField != null) { if (value == null) value = "";//$NON-NLS-1$ oldValue = textField.getText(); if (!oldValue.equals(value)) { String ov = oldValue; Point p = textField.getSelection(); textField.setText(value); int i = findPosition(ov, value, p.x); textField.setSelection(i); valueChanged(); } } } private int findPosition(String ov, String nv, int p) { if(p == ov.length() || p < 0) return nv.length(); for (int i = 0; i < p; i++) { if(i >= ov.length() || i >= nv.length()) return nv.length(); if(ov.charAt(i) != nv.charAt(i)) return i; } return p; } public void setTextLimit(int limit) { textLimit = limit; if (textField != null) textField.setTextLimit(limit); } public void setValidateStrategy(int value) { Assert.isTrue(value == VALIDATE_ON_FOCUS_LOST || value == VALIDATE_ON_KEY_STROKE); validateStrategy = value; } protected void valueChanged() { setPresentsDefaultValue(false); boolean oldState = isValid; refreshValidState(); if (isValid != oldState) fireStateChanged(IS_VALID, oldState, isValid); if(textField == null) { //disposed return; } String newValue = textField.getText(); if (!newValue.equals(oldValue)) { fireValueChanged(VALUE, oldValue, newValue); if(textField == null) { //disposed while firing return; } oldValue = textField.getText(); } } public void setEnabled(boolean enabled){ super.setEnabled(enabled); setTextControlEnabled(enabled); updateErrorState(); } protected void setTextControlEnabled(boolean enabled) { Control c = getTextControl(); if (c != null && !c.isDisposed()) { Text text = getTextField(); if(text != null && !text.isDisposed()) { text.setEditable(enabled); } else { boolean e = isAlwaysReadOnly(); c.setEnabled(enabled || e); } } } public void cut() { if (textField != null && textField.isFocusControl() && isEnabled()) { textField.cut(); valueChanged(); } } public void copy() { if (textField != null && textField.isFocusControl()) { textField.copy(); } } public void paste() { if (textField != null && textField.isFocusControl() && isEnabled()) { textField.paste(); valueChanged(); } } public void delete() { } }