Project: bpelunit
/*******************************************************************************
 * Copyright (c) 2000, 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 
 *******************************************************************************/
package net.bpelunit.toolsupport.editors.formwidgets; 
 
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.events.SelectionAdapter; 
import org.eclipse.swt.events.SelectionEvent; 
import org.eclipse.swt.layout.GridData; 
import org.eclipse.swt.layout.GridLayout; 
import org.eclipse.swt.widgets.Button; 
import org.eclipse.swt.widgets.Composite; 
import org.eclipse.swt.widgets.Control; 
import org.eclipse.swt.widgets.Label; 
import org.eclipse.swt.widgets.Layout; 
import org.eclipse.swt.widgets.Text; 
import org.eclipse.ui.forms.IFormColors; 
import org.eclipse.ui.forms.widgets.FormToolkit; 
import org.eclipse.ui.forms.widgets.Hyperlink; 
import org.eclipse.ui.forms.widgets.TableWrapData; 
import org.eclipse.ui.forms.widgets.TableWrapLayout; 
 
/**
 * 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. 
 */
 
public class FormEntry { 
 private Control fLabel; 
 private Text fText; 
 private Button fBrowse;   
 private String fValue= ""//$NON-NLS-1$ 
 private boolean fDirty; 
 boolean fIgnoreModify= false
 private IFormEntryListener fListener; 
 private boolean fSkipValidation; 
 private IEditorValidator fValidator; 
 
 /**
  * The default constructor. Call 'createControl' to make it. 
  *  
  */
 
 public FormEntry(Composite parent, FormToolkit toolkit, String labelText, int style) { 
  createControl(parent, toolkit, labelText, style, nullfalse00); 
 
 
 /**
  * This constructor create all the controls right away. 
  *  
  * @param parent 
  * @param toolkit 
  * @param labelText 
  * @param browseText 
  * @param linkLabel 
  */
 
 public FormEntry(Composite parent, FormToolkit toolkit, String labelText, String browseText, boolean linkLabel) { 
  this(parent, toolkit, labelText, browseText, linkLabel, 0); 
 
 
 public FormEntry(Composite parent, FormToolkit toolkit, String labelText, String browseText, boolean linkLabel, int indent) { 
  createControl(parent, toolkit, labelText, SWT.SINGLE, browseText, linkLabel, indent, 0); 
 
 
 public FormEntry(Composite parent, FormToolkit toolkit, String labelText, int indent, int tcolspan) { 
  createControl(parent, toolkit, labelText, SWT.SINGLE, nullfalse, indent, tcolspan); 
 
 
 /**
  * Create all the controls in the provided parent. 
  *  
  * @param parent 
  * @param toolkit 
  * @param labelText 
  * @param span 
  * @param browseText 
  * @param linkLabel 
  */
 
 private void createControl(Composite parent, FormToolkit toolkit, String labelText, int style, String browseText, boolean linkLabel, int indent, 
   int tcolspan) { 
  if (linkLabel) { 
   Hyperlink link= toolkit.createHyperlink(parent, labelText, SWT.NULL); 
   fLabel= link; 
  else { 
   if (labelText != null) { 
    fLabel= toolkit.createLabel(parent, labelText); 
    fLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE)); 
   
  
  fText= toolkit.createText(parent, "", style); //$NON-NLS-1$ 
  addListeners(); 
  if (browseText != null) { 
   fBrowse= toolkit.createButton(parent, browseText, SWT.PUSH); 
   fBrowse.addSelectionListener(new SelectionAdapter() { 
    @Override 
    public void widgetSelected(SelectionEvent e) { 
     if (fListener != null
      fListener.browseButtonSelected(FormEntry.this); 
    
   }); 
  
  fillIntoGrid(parent, indent, tcolspan); 
 
 
 public void setEditable(boolean editable) { 
  if (fValidator != null
   fValidator.setEnabled(editable); 
  fText.setEditable(editable); 
  if (fLabel instanceof Hyperlink) 
   ((Hyperlink) fLabel).setUnderlined(editable); 
 
  if (fBrowse != null
   fBrowse.setEnabled(editable); 
 
 
 private void fillIntoGrid(Composite parent, int indent, int tcolspan) { 
  Layout layout= parent.getLayout(); 
  int tspan; 
  if (layout instanceof GridLayout) { 
   int span= ((GridLayout) layout).numColumns; 
   if (tcolspan > 0
    tspan= tcolspan; 
   else 
    tspan= fBrowse != null ? span - 2 : span - 1
   GridData gd; 
   if (fLabel != null) { 
    gd= new GridData(GridData.VERTICAL_ALIGN_CENTER); 
    gd.horizontalIndent= indent; 
    fLabel.setLayoutData(gd); 
   
   gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL); 
   gd.horizontalSpan= tspan; 
   gd.grabExcessHorizontalSpace= (tspan == 1); 
   gd.widthHint= 10
   fText.setLayoutData(gd); 
   if (fBrowse != null) { 
    gd= new GridData(GridData.VERTICAL_ALIGN_CENTER); 
    fBrowse.setLayoutData(gd); 
   
  else if (layout instanceof TableWrapLayout) { 
   int span= ((TableWrapLayout) layout).numColumns; 
   if (tcolspan > 0
    tspan= tcolspan; 
   else 
    tspan= fBrowse != null ? span - 2 : span - 1
   TableWrapData td; 
   if (fLabel != null) { 
    td= new TableWrapData(); 
    td.valign= TableWrapData.MIDDLE; 
    td.indent= indent; 
    fLabel.setLayoutData(td); 
   
   td= new TableWrapData(TableWrapData.FILL); 
   td.colspan= tspan; 
   td.grabHorizontal= (tspan == 1); 
   td.valign= TableWrapData.MIDDLE; 
   fText.setLayoutData(td); 
   if (fBrowse != null) { 
    td= new TableWrapData(TableWrapData.FILL); 
    td.valign= TableWrapData.MIDDLE; 
    fBrowse.setLayoutData(td); 
   
  
 
 
 /**
  * Attaches the listener for the entry. 
  *  
  * @param listener 
  */
 
 public void setFormEntryListener(IFormEntryListener listener) { 
  if (fLabel != null && fLabel instanceof Hyperlink) { 
   if (this.fListener != null
    ((Hyperlink) fLabel).removeHyperlinkListener(this.fListener); 
   if (listener != null
    ((Hyperlink) fLabel).addHyperlinkListener(listener); 
  
  this.fListener= listener; 
 
 
 private void addListeners() { 
  fText.addKeyListener(new KeyAdapter() { 
   @Override 
   public void keyReleased(KeyEvent e) { 
    keyReleaseOccured(e); 
   
  }); 
  fText.addModifyListener(new ModifyListener() { 
   public void modifyText(ModifyEvent e) { 
    editOccured(e); 
   
  }); 
  fText.addFocusListener(new FocusAdapter() { 
   @Override 
   public void focusGained(FocusEvent e) { 
    if (fListener != null
     fListener.focusGained(FormEntry.this); 
   
 
   @Override 
   public void focusLost(FocusEvent e) { 
    if (fDirty) 
     commit(); 
   
  }); 
 
 
 /**
  * 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 (fDirty) { 
   fValue= fText.getText(); 
   // if (value.length()==0) 
   // value = null; 
   // notify 
   if (fListener != null
    fListener.textValueChanged(this); 
  
  fDirty= false
 
 
 public void cancelEdit() { 
  fDirty= false
 
 
 private void editOccured(ModifyEvent e) { 
  if (!fSkipValidation) 
   validate(); 
  if (fIgnoreModify) 
   return
  fDirty= true
  if (fListener != null
   fListener.textDirty(this); 
 
 
 /**
  * Returns the text control. 
  *  
  * @return 
  */
 
 public Text getText() { 
  return fText; 
 
 
 public Control getLabel() { 
  return fLabel; 
 
 
 /**
  * Returns the browse button control. 
  *  
  * @return 
  */
 
 public Button getButton() { 
  return fBrowse; 
 
 
 /**
  * Returns the current entry value. If the entry is dirty and was not commited, the value may be 
  * different from the text in the widget. 
  *  
  * @return 
  */
 
 public String getValue() { 
  return fValue.trim(); 
 
 
 /**
  * Returns true if the text has been modified. 
  *  
  * @return 
  */
 
 public boolean isDirty() { 
  return fDirty; 
 
 
 private void keyReleaseOccured(KeyEvent e) { 
  if (e.character == '\r') { 
   // commit value 
   if (fDirty) 
    commit(); 
  else if (e.character == '\u001b') { // Escape character 
   if (!fValue.equals(fText.getText())) 
    fText.setText(fValue != null ? fValue : ""); // restore old //$NON-NLS-1$ 
   fDirty= false
  
  if (fListener != null
   fListener.selectionChanged(FormEntry.this); 
 
 
 /**
  * Sets the value of this entry. 
  *  
  * @param value 
  */
 
 public void setValue(String value) { 
  if (fText != null
   fText.setText(value != null ? value : ""); //$NON-NLS-1$ 
  this.fValue= (value != null) ? value : ""//$NON-NLS-1$ 
 
 
 /**
  * Sets the value of this entry with the possibility to turn the notification off. 
  *  
  * @param value 
  * @param blockNotification 
  */
 
 public void setValue(String value, boolean blockNotification) { 
  fIgnoreModify= blockNotification; 
  setValue(value); 
  fIgnoreModify= false
 
 
 /**
  * Sets the value of this entry with the possibility to turn the notification and validation 
  * off. 
  *  
  * @param value 
  * @param blockNotification 
  */
 
 public void setValue(String value, boolean blockNotification, boolean skipValidation) { 
  fSkipValidation= skipValidation; 
  setValue(value, blockNotification); 
  fSkipValidation= false
 
 
 public void setVisible(boolean visible) { 
  if (fLabel != null
   fLabel.setVisible(visible); 
  if (fText != null
   fText.setVisible(visible); 
  if (fBrowse != null
   fBrowse.setVisible(visible); 
 
 
 public void setValidator(IEditorValidator validator) { 
  fValidator= validator; 
 
 
 public IEditorValidator getValidator() { 
  return fValidator; 
 
 
 public void validate() { 
  if (fValidator != null
   fValidator.validate(true); 
 
 
 public String getProviderValue() { 
  return fText.getText(); 
 
 
 public String getProviderDescription() { 
  if (fLabel == null
   return null
  if (fLabel instanceof Label) 
   return ((Label) fLabel).getText(); 
  else if (fLabel instanceof Hyperlink) 
   return ((Hyperlink) fLabel).getText(); 
  return null
 
}