/**
* (c) 2011, Alejandro Serrano
* Released under the terms of the EPL.
*/
package net.sf.eclipsefp.haskell.ui.internal.editors.cabal.forms;
import org.eclipse.core.resources.IProject;
import org.eclipse.swt.SWT;
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.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.widgets.FormToolkit;
/**
* copied from PDE UI internals and modified
*
* The helper class for creating entry fields with label and text. Optionally, a
* button can be added after the text. The attached listener reacts to all the
* events. Entring new text makes the entry 'dirty', but only when 'commit' is
* called is 'valueChanged' method called (and only if 'dirty' flag is set).
* This allows delayed commit.
*
* Based on previous work of Leif Frenzel
*/
public class FormEntryText extends FormEntry {
private Text textField;
private String oldValue = null;
private String value = ""; //$NON-NLS-1$
private boolean isIgnoreModify = false;
@Override
public void init( final IProject project, final Composite parent,
final FormToolkit toolkit, final int style ) {
this.textField = toolkit.createText( parent, "", style );
addListeners();
}
@Override
public Control getControl() {
return this.textField;
}
private boolean isMultiline(){
return ( this.textField.getStyle() & SWT.MULTI ) > 0;
}
@Override
public int heightHint() {
// Make more space for multiline editors
return isMultiline() ? 45 : 15;
}
@Override
public void setValue( final String value, final boolean blockNotification ) {
// we don't modify while we're editing
if (this.textField.isFocusControl()){
return;
}
this.isIgnoreModify = blockNotification;
// remove line separators if we're not multiline
this.value = ( value != null ) ? isMultiline()?
value
: value.replace( "\n", " " ).replace( "\r", "" )
: ""; //$NON-NLS-1$
String v=this.value != null ? this.value : "" ;//$NON-NLS-1$
if (!v.equals(this.textField.getText())){
this.textField.setText( v );
}
this.isIgnoreModify = false;
if (oldValue==null && !blockNotification){
oldValue=value;
}
}
@Override
public String getValue() {
return value.trim();
}
@Override
public void setEditable( final boolean editable ) {
this.textField.setEditable( editable );
}
/** Returns true if the text has been modified. */
public boolean isDirty() {
return !value.equals(oldValue);
}
/**
* If dirty, commits the text in the widget to the value and notifies the
* listener. This call clears the 'dirty' flag.
*/
public void commit() {
if( isDirty() ) {
oldValue = value;
}
}
public void cancelEdit() {
value = oldValue;
notifyTextValueChanged();
}
// helping functions
// //////////////////
private void keyReleaseOccured( final KeyEvent evt ) {
if( evt.character == '\r' && ( textField.getStyle() & SWT.MULTI ) == 0 ) {
// commit value
if( isDirty() ) {
commit();
}
} else if( evt.character == '\u001b' ) { // Escape character
//if( !textField.getText().equals( oldValue ) ) {
int pos=this.textField.getCaretPosition();
String v=oldValue != null ? oldValue : "" ;//$NON-NLS-1$
textField.setText( v); // restore old
pos=Math.min( pos, v.length() );
this.textField.setSelection( pos, pos );
//}
cancelEdit();
} else {
value=textField.getText();
notifyTextValueChanged();
}
notifySelectionChanged();
}
private void editOccured( final ModifyEvent evt ) {
if( !isIgnoreModify ) {
notifyTextDirty();
}
}
private void addListeners() {
textField.addKeyListener( new KeyAdapter() {
@Override
public void keyReleased( final KeyEvent evt ) {
keyReleaseOccured( evt );
}
} );
textField.addModifyListener( new ModifyListener() {
@Override
public void modifyText( final ModifyEvent evt ) {
if( !textField.getText().equals( value ) ) {
editOccured( evt );
}
}
} );
textField.addFocusListener( new FocusAdapter() {
@Override
public void focusGained( final FocusEvent evt ) {
notifyFocusGained();
}
@Override
public void focusLost( final FocusEvent evt ) {
if( isDirty() ) {
commit();
}
}
} );
}
}