Mercurial > projects > dwt2
diff org.eclipse.jface/src/org/eclipse/jface/viewers/DialogCellEditor.d @ 12:bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 14 Mar 2009 18:23:29 +0100 |
parents | |
children | 6f068362a363 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/org.eclipse.jface/src/org/eclipse/jface/viewers/DialogCellEditor.d Sat Mar 14 18:23:29 2009 +0100 @@ -0,0 +1,394 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 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 + * Port to the D programming language: + * Frank Benoit <benoit@tionex.de> + *******************************************************************************/ +module org.eclipse.jface.viewers.DialogCellEditor; + +import org.eclipse.jface.viewers.CellEditor; + +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.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +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.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.jface.resource.JFaceResources; + +import java.lang.all; +import java.util.Set; +import tango.text.convert.Format; + +/** + * An abstract cell editor that uses a dialog. + * Dialog cell editors usually have a label control on the left and a button on + * the right. Pressing the button opens a dialog window (for example, a color dialog + * or a file dialog) to change the cell editor's value. + * The cell editor's value is the value of the dialog. + * <p> + * Subclasses may override the following methods: + * <ul> + * <li><code>createButton</code>: creates the cell editor's button control</li> + * <li><code>createContents</code>: creates the cell editor's 'display value' control</li> + * <li><code>updateContents</code>: updates the cell editor's 'display value' control + * after its value has changed</li> + * <li><code>openDialogBox</code>: opens the dialog box when the end user presses + * the button</li> + * </ul> + * </p> + */ +public abstract class DialogCellEditor : CellEditor { + + /** + * Image registry key for three dot image (value <code>"cell_editor_dots_button_image"</code>). + */ + public static const String CELL_EDITOR_IMG_DOTS_BUTTON = "cell_editor_dots_button_image";//$NON-NLS-1$ + + /** + * The editor control. + */ + private Composite editor; + + /** + * The current contents. + */ + private Control contents; + + /** + * The label that gets reused by <code>updateLabel</code>. + */ + private Label defaultLabel; + + /** + * The button. + */ + 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; + + /** + * The value of this cell editor; initially <code>null</code>. + */ + private Object value = null; + + static this() { + ImageRegistry reg = JFaceResources.getImageRegistry(); + reg.put(CELL_EDITOR_IMG_DOTS_BUTTON, ImageDescriptor.createFromFile( + getImportData!("org.eclipse.jface.images.dots_button.gif")));//$NON-NLS-1$ + } + + /** + * Internal class for laying out the dialog. + */ + private class DialogCellLayout : Layout { + public override void layout(Composite editor, bool force) { + Rectangle bounds = editor.getClientArea(); + Point size = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, force); + if (contents !is null) { + contents.setBounds(0, 0, bounds.width - size.x, bounds.height); + } + button.setBounds(bounds.width - size.x, 0, size.x, bounds.height); + } + + public override Point computeSize(Composite editor, int wHint, int hHint, + bool force) { + if (wHint !is SWT.DEFAULT && hHint !is SWT.DEFAULT) { + return new Point(wHint, hHint); + } + Point contentsSize = contents.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; + } + } + + /** + * Default DialogCellEditor style + */ + private static const int defaultStyle = SWT.NONE; + + /** + * Creates a new dialog cell editor with no control + * @since 2.1 + */ + public this() { + setStyle(defaultStyle); + } + + /** + * Creates a new dialog cell editor parented under the given control. + * The cell editor value is <code>null</code> initially, and has no + * validator. + * + * @param parent the parent control + */ + protected this(Composite parent) { + this(parent, defaultStyle); + } + + /** + * Creates a new dialog cell editor parented under the given control. + * The cell editor value is <code>null</code> initially, and has no + * validator. + * + * @param parent the parent control + * @param style the style bits + * @since 2.1 + */ + protected this(Composite parent, int style) { + super(parent, style); + } + + /** + * 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; + } + + /** + * Creates the controls used to show the value of this cell editor. + * <p> + * The default implementation of this framework method creates + * a label widget, using the same font and background color as the parent control. + * </p> + * <p> + * Subclasses may reimplement. If you reimplement this method, you + * should also reimplement <code>updateContents</code>. + * </p> + * + * @param cell the control for this cell editor + * @return the underlying control + */ + protected Control createContents(Composite cell) { + defaultLabel = new Label(cell, SWT.LEFT); + defaultLabel.setFont(cell.getFont()); + defaultLabel.setBackground(cell.getBackground()); + return defaultLabel; + } + + /* (non-Javadoc) + * Method declared on CellEditor. + */ + protected override Control createControl(Composite parent) { + + Font font = parent.getFont(); + Color bg = parent.getBackground(); + + editor = new Composite(parent, getStyle()); + editor.setFont(font); + editor.setBackground(bg); + editor.setLayout(new DialogCellLayout()); + + contents = createContents(editor); + updateContents(value); + + button = createButton(editor); + button.setFont(font); + + button.addKeyListener(new class KeyAdapter { + /* (non-Javadoc) + * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent) + */ + public void keyReleased(KeyEvent e) { + if (e.character is '\u001b') { // Escape + fireCancelEditor(); + } + } + }); + + button.addFocusListener(getButtonFocusListener()); + + button.addSelectionListener(new class 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); + + // Re-add the listener once the dialog closes + button.addFocusListener(getButtonFocusListener()); + + if (newValue !is null) { + bool newValidState = isCorrect(newValue); + if (newValidState) { + markDirty(); + doSetValue(newValue); + } else { + // try to insert the current value into the error message. + setErrorMessage(Format(getErrorMessage(), + newValue.toString() )); + } + fireApplyEditorValue(); + } + } + }); + + setValueValid(true); + + return editor; + } + + /* (non-Javadoc) + * + * Override in order to remove the button's focus listener if the celleditor + * is deactivating. + * + * @see org.eclipse.jface.viewers.CellEditor#deactivate() + */ + public override void deactivate() { + if (button !is null && !button.isDisposed()) { + button.removeFocusListener(getButtonFocusListener()); + } + + super.deactivate(); + } + + /* (non-Javadoc) + * Method declared on CellEditor. + */ + protected override Object doGetValue() { + return value; + } + + /* (non-Javadoc) + * Method declared on CellEditor. + * The focus is set to the cell editor's button. + */ + protected override void doSetFocus() { + button.setFocus(); + + // add a FocusListener to the button + button.addFocusListener(getButtonFocusListener()); + } + + /** + * Return a listener for button focus. + * @return FocusListener + */ + private FocusListener getButtonFocusListener() { + if (buttonFocusListener is null) { + buttonFocusListener = new class 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) { + this.outer.focusLost(); + } + }; + } + + return buttonFocusListener; + } + + /* (non-Javadoc) + * Method declared on CellEditor. + */ + protected override void doSetValue(Object value) { + this.value = value; + updateContents(value); + } + + /** + * Returns the default label widget created by <code>createContents</code>. + * + * @return the default label widget + */ + protected Label getDefaultLabel() { + return defaultLabel; + } + + /** + * 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); + + /** + * Updates the controls showing the value of this cell editor. + * <p> + * The default implementation of this framework method just converts + * the passed object to a string using <code>toString</code> and + * sets this as the text of the label widget. + * </p> + * <p> + * Subclasses may reimplement. If you reimplement this method, you + * should also reimplement <code>createContents</code>. + * </p> + * + * @param value the new value of this cell editor + */ + protected void updateContents(Object value) { + if (defaultLabel is null) { + return; + } + + String text = "";//$NON-NLS-1$ + if (value !is null) { + text = value.toString(); + } + defaultLabel.setText(text); + } +}