Project: dawn-isenciaui
package com.isencia.passerelle.workbench.model.editor.ui.cell;
 
import java.text.MessageFormat; 
 
import org.eclipse.jface.viewers.TextCellEditor; 
import org.eclipse.swt.SWT; 
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.SelectionAdapter; 
import org.eclipse.swt.events.SelectionEvent; 
import org.eclipse.swt.graphics.Point; 
import org.eclipse.swt.graphics.Rectangle; 
import org.eclipse.swt.layout.GridData; 
import org.eclipse.swt.widgets.Button; 
import org.eclipse.swt.widgets.Composite; 
import org.eclipse.swt.widgets.Control; 
import org.eclipse.swt.widgets.Layout; 
 
public abstract class DialogBrowserEditor extends TextCellEditor { 
 
 private Button button; 
 
 /**
  * Listens for 'focusLost' events and  fires the 'apply' event as long 
  * as the focus wasn't lost because the dialog was opened. 
  */
 
 private FocusListener buttonFocusListener; 
 
  
 public DialogBrowserEditor(Composite aComposite) { 
  super(aComposite); 
 
 
    /* (non-Javadoc)
     * Method declared on CellEditor. 
     */
 
    protected Control createControl(final Composite parent) { 
      
     final Composite editor = new Composite(parent, getStyle()); 
        editor.setFont(parent.getFont()); 
        editor.setBackground(parent.getBackground()); 
        editor.setLayout(new DialogCellLayout()); 
 
        super.createControl(editor); 
        text.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, truetrue)); 
         
        button = createButton(editor); 
        button.setFont(editor.getFont()); 
         
        button.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, falsefalse)); 
 
        button.addKeyListener(new KeyAdapter() { 
         /* (non-Javadoc)
          * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent) 
          */
 
         public void keyReleased(KeyEvent e) { 
          if (e.character == '\u001b') { // Escape 
           fireCancelEditor(); 
          
         
        }); 
 
        button.addFocusListener(getButtonFocusListener()); 
 
        button.addSelectionListener(new SelectionAdapter() { 
         /* (non-Javadoc)
          * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) 
          */
 
         public void widgetSelected(SelectionEvent event) { 
          // Remove the button's focus listener since it's guaranteed 
          // to lose focus when the dialog opens 
          button.removeFocusListener(getButtonFocusListener()); 
 
          Object newValue = openDialogBox(editor, doGetValue()); 
 
          // Re-add the listener once the dialog closes 
          button.addFocusListener(getButtonFocusListener()); 
 
          if (newValue != null) { 
           boolean newValidState = isCorrect(newValue); 
           if (newValidState) { 
            markDirty(); 
            doSetValue(newValue); 
           else { 
            // try to insert the current value into the error message. 
            setErrorMessage(MessageFormat.format(getErrorMessage(), 
              new Object[] { newValue.toString() })); 
           
           fireApplyEditorValue(); 
          
         
        }); 
 
        setValueValid(true); 
         
        return editor; 
    } 
 
    /**
     * Creates the button for this cell editor under the given parent control. 
     * <p> 
     * The default implementation of this framework method creates the button  
     * display on the right hand side of the dialog cell editor. Subclasses 
     * may extend or reimplement. 
     * </p> 
     * 
     * @param parent the parent control 
     * @return the new button control 
     */
 
    protected Button createButton(Composite parent) { 
        Button result = new Button(parent, SWT.DOWN); 
        result.setText("..."); //$NON-NLS-1$ 
        return result; 
    } 
 
    /**
     * Return a listener for button focus. 
     * @return FocusListener 
     */
 
    private FocusListener getButtonFocusListener() { 
     if (buttonFocusListener == null) { 
      buttonFocusListener = new FocusListener() { 
 
    /* (non-Javadoc)
     * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent) 
     */
 
    public void focusGained(FocusEvent e) { 
     // Do nothing 
    
 
    /* (non-Javadoc)
     * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent) 
     */
 
    public void focusLost(FocusEvent e) { 
     DialogBrowserEditor.this.focusLost(); 
    
      }; 
     
      
     return buttonFocusListener; 
 
     
    /**
     * Opens a dialog box under the given parent control and returns the 
     * dialog's value when it closes, or <code>null</code> if the dialog 
     * was canceled or no selection was made in the dialog. 
     * <p> 
     * This framework method must be implemented by concrete subclasses. 
     * It is called when the user has pressed the button and the dialog 
     * box must pop up. 
     * </p> 
     * 
     * @param cellEditorWindow the parent control cell editor's window 
     *   so that a subclass can adjust the dialog box accordingly 
     * @return the selected value, or <code>null</code> if the dialog was  
     *   canceled or no selection was made in the dialog 
     */
 
    protected abstract Object openDialogBox(Control cellEditorWindow, final Object value); 
     
     
  
 protected void focusLost() { 
  if (text.isFocusControl() || button.isFocusControl()) return
  if (isActivated()) { 
   fireApplyEditorValue(); 
   deactivate(); 
  
 
 
    /**
     * Internal class for laying out the dialog. 
     */
 
    private class DialogCellLayout extends Layout { 
        public void layout(Composite editor, boolean force) { 
            Rectangle bounds = editor.getClientArea(); 
            Point size = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, force); 
            if (text != null) { 
             text.setBounds(00, bounds.width - size.x, bounds.height); 
   
            button.setBounds(bounds.width - size.x, 0, size.x, bounds.height); 
        } 
 
        public Point computeSize(Composite editor, int wHint, int hHint, 
                boolean force) { 
            if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT) { 
    return new Point(wHint, hHint); 
   
            Point contentsSize = text.computeSize(SWT.DEFAULT, SWT.DEFAULT, 
                    force); 
            Point buttonSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, 
                    force); 
            // Just return the button width to ensure the button is not clipped 
            // if the label is long. 
            // The label will just use whatever extra width there is 
            Point result = new Point(buttonSize.x, Math.max(contentsSize.y, 
                    buttonSize.y)); 
            return result; 
        } 
    } 
 
}