changeset 4:c87617952847

some JFace modules
author Frank Benoit <benoit@tionex.de>
date Fri, 28 Mar 2008 17:08:33 +0100
parents 6518c18a01f7
children 103ab03b77eb
files dwtx/core/commands/IHandlerAttributes.d dwtx/jface/action/IAction.d dwtx/jface/action/IMenuCreator.d dwtx/jface/dialogs/AnimatorFactory.d dwtx/jface/dialogs/ControlAnimator.d dwtx/jface/dialogs/ErrorSupportProvider.d dwtx/jface/resource/DerivedImageDescriptor.d dwtx/jface/resource/DeviceResourceDescriptor.d dwtx/jface/resource/DeviceResourceException.d dwtx/jface/resource/FileImageDescriptor.d dwtx/jface/resource/ImageDataImageDescriptor.d dwtx/jface/resource/ImageDescriptor.d dwtx/jface/resource/MissingImageDescriptor.d dwtx/jface/resource/URLImageDescriptor.d dwtx/jface/util/Assert.d dwtx/jface/util/Geometry.d dwtx/jface/util/ILogger.d dwtx/jface/util/IOpenEventListener.d dwtx/jface/util/IPropertyChangeListener.d dwtx/jface/util/ISafeRunnableRunner.d dwtx/jface/util/ListenerList.d dwtx/jface/util/OpenStrategy.d dwtx/jface/util/Policy.d dwtx/jface/util/PropertyChangeEvent.d
diffstat 24 files changed, 3806 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/dwtx/core/commands/IHandlerAttributes.d	Wed Mar 26 00:57:19 2008 +0100
+++ b/dwtx/core/commands/IHandlerAttributes.d	Fri Mar 28 17:08:33 2008 +0100
@@ -34,6 +34,6 @@
      * The command should act and behave as if it has no handler.
      * </p>
      */
-    public static final String ATTRIBUTE_HANDLED = "handled"; //$NON-NLS-1$
+    public static const String ATTRIBUTE_HANDLED = "handled"; //$NON-NLS-1$
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/action/IAction.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,522 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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 dwtx.jface.action.IAction;
+
+import dwtx.jface.action.IMenuCreator;
+
+import dwt.events.HelpListener;
+import dwt.widgets.Event;
+import dwtx.core.commands.IHandlerAttributes;
+import dwtx.jface.resource.ImageDescriptor;
+import dwtx.jface.util.IPropertyChangeListener;
+
+import dwt.dwthelper.utils;
+
+/**
+ * An action represents the non-UI side of a command which can be triggered
+ * by the end user. Actions are typically associated with buttons, menu items,
+ * and items in tool bars. The controls for a command are built by some container,
+ * which furnished the context where these controls appear and configures
+ * them with data from properties declared by the action. When the end user
+ * triggers the command via its control, the action's <code>run</code>
+ * method is invoked to do the real work.
+ * <p>
+ * Actions support a predefined set of properties (and possibly others as well).
+ * Clients of an action may register property change listeners so that they get
+ * notified whenever the value of a property changes.
+ * </p>
+ * <p>
+ * Clients should subclass the abstract base class <code>Action</code> to define
+ * concrete actions rather than implementing <code>IAction</code> from scratch.
+ * </p>
+ * <p>
+ * This interface exists only to define the API for actions.
+ * It is not intended to be implemented by clients.
+ * </p>
+ *
+ * @see Action
+ */
+public interface IAction {
+
+    /**
+     * Action style constant (value <code>0</code>) indicating action style
+     * is not specified yet. By default, the action will assume a push button
+     * style. If <code>setChecked</code> is called, then the style will change
+     * to a check box, or if <code>setMenuCreator</code> is called, then the
+     * style will change to a drop down menu.
+     *
+     * @since 2.1
+     */
+    public static int AS_UNSPECIFIED = 0x00;
+
+    /**
+     * Action style constant (value <code>1</code>) indicating action is
+     * a simple push button.
+     */
+    public static int AS_PUSH_BUTTON = 0x01;
+
+    /**
+     * Action style constant (value <code>2</code>) indicating action is
+     * a check box (or a toggle button).
+     */
+    public static int AS_CHECK_BOX = 0x02;
+
+    /**
+     * Action style constant (value <code>4</code>) indicating action is
+     * a drop down menu.
+     */
+    public static int AS_DROP_DOWN_MENU = 0x04;
+
+    /**
+     * Action style constant (value <code>8</code>) indicating action is
+     * a radio button.
+     *
+     * @since 2.1
+     */
+    public static int AS_RADIO_BUTTON = 0x08;
+
+    /**
+     * Property name of an action's text (value <code>"text"</code>).
+     */
+    public static const String TEXT = "text"; //$NON-NLS-1$
+
+    /**
+     * Property name of an action's enabled state
+     * (value <code>"enabled"</code>).
+     */
+    public static const String ENABLED = "enabled"; //$NON-NLS-1$
+
+    /**
+     * Property name of an action's image (value <code>"image"</code>).
+     */
+    public static const String IMAGE = "image"; //$NON-NLS-1$
+
+    /**
+     * Property name of an action's tooltip text (value <code>"toolTipText"</code>).
+     */
+    public static const String TOOL_TIP_TEXT = "toolTipText"; //$NON-NLS-1$
+
+    /**
+     * Property name of an action's description (value <code>"description"</code>).
+     * Typically the description is shown as a (longer) help text in the status line.
+     */
+    public static const String DESCRIPTION = "description"; //$NON-NLS-1$
+
+    /**
+     * Property name of an action's checked status (value
+     * <code>"checked"</code>). Applicable when the style is
+     * <code>AS_CHECK_BOX</code> or <code>AS_RADIO_BUTTON</code>.
+     */
+    public static const String CHECKED = "checked"; //$NON-NLS-1$
+
+    /**
+     * Property name of an action's success/fail result
+     * (value <code>"result"</code>). The values are
+     * <code>bool.TRUE</code> if running the action succeeded and
+     * <code>bool.FALSE</code> if running the action failed or did not
+     * complete.
+     * <p>
+     * Not all actions report whether they succeed or fail. This property
+     * is provided for use by actions that may be invoked by clients that can
+     * take advantage of this information when present (for example, actions
+     * used in cheat sheets). Clients should always assume that running the
+     * action succeeded in the absence of notification to the contrary.
+     * </p>
+     *
+     * @since 3.0
+     */
+    public static const String RESULT = "result"; //$NON-NLS-1$
+
+    /**
+     * Property name of an action's handler. Some actions delegate some or all
+     * of their behaviour or state to another object. In this case, if the
+     * object to which behaviour has been delegated changes, then a property
+     * change event should be sent with this name.
+     *
+     * This is used to support backward compatibility of actions within the
+     * commands framework.
+     *
+     * @since 3.1
+     */
+    public static const String HANDLED = IHandlerAttributes.ATTRIBUTE_HANDLED;
+
+    /**
+     * Adds a property change listener to this action.
+     * Has no effect if an identical listener is already registered.
+     *
+     * @param listener a property change listener
+     */
+    public void addPropertyChangeListener(IPropertyChangeListener listener);
+
+    /**
+     * Returns the accelerator keycode for this action.
+     * The result is the bit-wise OR of zero or more modifier masks
+     * and a key, as explained in <code>MenuItem.getAccelerator</code>.
+     *
+     * @return the accelerator keycode
+     * @see dwt.widgets.MenuItem#getAccelerator()
+     */
+    public int getAccelerator();
+
+    /**
+     * Returns the action definition id of this action.
+     *
+     * @return the action definition id of this action, or
+     * <code>null</code> if none
+     * @since 2.0
+     */
+    public String getActionDefinitionId();
+
+    /**
+     * Returns the action's description if it has one.
+     * Otherwise it returns <code>getToolTipText()</code>.
+     *
+     * @return a description for the action; may be <code>null</code>
+     */
+    public String getDescription();
+
+    /**
+     * Returns the disabled image for this action as an image descriptor.
+     * <p>
+     * This method is associated with the <code>IMAGE</code> property;
+     * property change events are reported when its value changes.
+     * </p>
+     *
+     * @return the image, or <code>null</code> if this action has no image
+     * @see #IMAGE
+     */
+    public ImageDescriptor getDisabledImageDescriptor();
+
+    /**
+     * Returns a help listener for this action.
+     *
+     * @return a help listener for this action
+     */
+    public HelpListener getHelpListener();
+
+    /**
+     * Returns the hover image for this action as an image descriptor.
+     * <p>
+     * Hover images will be used on platforms that support changing the image
+     * when the user hovers over the item. This method is associated with
+     * the <code>IMAGE</code> property;
+     * property change events are reported when its value changes.
+     * </p>
+     *
+     * @return the image, or <code>null</code> if this action has no image
+     * @see #IMAGE
+     */
+    public ImageDescriptor getHoverImageDescriptor();
+
+    /**
+     * Returns a unique identifier for this action, or <code>null</code> if it has
+     * none.
+     *
+     * @return the action id, or <code>null</code> if none
+     */
+    public String getId();
+
+    /**
+     * Returns the image for this action as an image descriptor.
+     * <p>
+     * This method is associated with the <code>IMAGE</code> property;
+     * property change events are reported when its value changes.
+     * </p>
+     *
+     * @return the image, or <code>null</code> if this action has no image
+     * @see #IMAGE
+     */
+    public ImageDescriptor getImageDescriptor();
+
+    /**
+     * Returns the menu creator for this action.
+     *
+     * @return the menu creator, or <code>null</code> if none
+     */
+    public IMenuCreator getMenuCreator();
+
+    /**
+     * Return this action's style.
+     *
+     * @return one of <code>AS_PUSH_BUTTON</code>, <code>AS_CHECK_BOX</code>,
+     * <code>AS_RADIO_BUTTON</code> and <code>AS_DROP_DOWN_MENU</code>.
+     */
+    public int getStyle();
+
+    /**
+     * Returns the text for this action.
+     * <p>
+     * This method is associated with the <code>TEXT</code> property;
+     * property change events are reported when its value changes.
+     * </p>
+     *
+     * @return the text, or <code>null</code> if none
+     * @see #TEXT
+     */
+    public String getText();
+
+    /**
+     * Returns the tool tip text for this action.
+     * <p>
+     * This method is associated with the <code>TOOL_TIP_TEXT</code> property;
+     * property change events are reported when its value changes.
+     * </p>
+     *
+     * @return the tool tip text, or <code>null</code> if none
+     * @see #TOOL_TIP_TEXT
+     */
+    public String getToolTipText();
+
+    /**
+     * Returns the checked status of this action. Applicable only if the style is
+     * <code>AS_CHECK_BOX</code> or <code>AS_RADIO_BUTTON</code>.
+     * <p>
+     * This method is associated with the <code>CHECKED</code> property;
+     * property change events are reported when its value changes.
+     * </p>
+     *
+     * @return the checked status
+     * @see #CHECKED
+     */
+    public bool isChecked();
+
+    /**
+     * Returns whether this action is enabled.
+     * <p>
+     * This method is associated with the <code>ENABLED</code> property;
+     * property change events are reported when its value changes.
+     * </p>
+     *
+     * @return <code>true</code> if enabled, and
+     *   <code>false</code> if disabled
+     * @see #ENABLED
+     */
+    public bool isEnabled();
+
+    /**
+     * Returns whether this action is handled. In the default case, this is
+     * always <code>true</code>. However, if the action delegates some of its
+     * behaviour to some other object, then this method should answer whether
+     * such an object is currently available.
+     *
+     * @return <code>true</code> if all of the action's behaviour is
+     *         available; <code>false</code> otherwise.
+     * @since 3.1
+     */
+    public bool isHandled();
+
+    /**
+     * Removes the given listener from this action.
+     * Has no effect if an identical listener is not registered.
+     *
+     * @param listener a property change listener
+     */
+    public void removePropertyChangeListener(IPropertyChangeListener listener);
+
+    /**
+     * Runs this action.
+     * Each action implementation must define the steps needed to carry out this action.
+     * The default implementation of this method in <code>Action</code>
+     * does nothing.
+     */
+    public void run();
+
+    /**
+     * Runs this action, passing the triggering DWT event.
+     * As of 2.0, <code>ActionContributionItem</code> calls this method
+     * instead of <code>run()</code>.
+     * The default implementation of this method in <code>Action</code>
+     * simply calls <code>run()</code> for backwards compatibility.
+     *
+     * @param event the DWT event which triggered this action being run
+     * @since 2.0
+     */
+    public void runWithEvent(Event event);
+
+    /**
+     * Sets the action definition id of this action.
+     *
+     * @param id the action definition id
+     * @since 2.0
+     */
+    public void setActionDefinitionId(String id);
+
+    /**
+     * Sets the checked status of this action. Applicable for the styles
+     * <code>AS_CHECK_BOX</code> or <code>AS_RADIO_BUTTON</code>.
+     * <p>
+     * Fires a property change event for the <code>CHECKED</code> property
+     * if the checked status actually changes as a consequence.
+     * </p>
+     *
+     * @param checked the new checked status
+     * @see #CHECKED
+     */
+    public void setChecked(bool checked);
+
+    /**
+     * Sets this action's description.
+     * Typically the description is shown as a (longer) help text in the status line.
+     * <p>
+     * Fires a property change event for the <code>DESCRIPTION</code> property
+     * if the description actually changes as a consequence.
+     * </p>
+     *
+     * @param text the description, or <code>null</code> to clear the description
+     * @see #DESCRIPTION
+     */
+    public void setDescription(String text);
+
+    /**
+     * Sets the disabled image for this action, as an image descriptor.
+     * <p>
+     * Disabled images will be used on platforms that support changing the image
+     * when the item is disabled.Fires a property change event for
+     * the <code>IMAGE</code> property
+     * if the image actually changes as a consequence.
+     * </p>
+     *
+     * @param newImage the image, or <code>null</code> if this
+     *   action should not have an image
+     * @see #IMAGE
+     */
+    public void setDisabledImageDescriptor(ImageDescriptor newImage);
+
+    /**
+     * Sets the enabled state of this action.
+     * <p>
+     * When an action is in the enabled state, the control associated with
+     * it is active; triggering it will end up inkoking this action's
+     * <code>run</code> method.
+     * </p>
+     * <p>
+     * Fires a property change event for the <code>ENABLED</code> property
+     * if the enabled state actually changes as a consequence.
+     * </p>
+     *
+     * @param enabled <code>true</code> to enable, and
+     *   <code>false</code> to disable
+     * @see #ENABLED
+     */
+    public void setEnabled(bool enabled);
+
+    /**
+     * Sets a help listener for this action.
+     *
+     * @param listener a help listener for this action
+     */
+    public void setHelpListener(HelpListener listener);
+
+    /**
+     * Sets the hover image for this action, as an image descriptor.
+     * <p>
+     * Hover images will be used on platforms that support changing the image
+     * when the user hovers over the item.Fires a property change event for
+     * the <code>IMAGE</code> property
+     * if the image actually changes as a consequence.
+     * </p>
+     *
+     * @param newImage the image, or <code>null</code> if this
+     *   action should not have an image
+     * @see #IMAGE
+     */
+    public void setHoverImageDescriptor(ImageDescriptor newImage);
+
+    /**
+     * Sets the unique identifier for this action. This is used to identify actions
+     * when added to a contribution manager.
+     * It should be set when the action is created.  It should not be modified once
+     * the action is part of an action contribution item.
+     *
+     * @param id the action id
+     *
+     * @see ActionContributionItem
+     * @see IContributionItem#getId
+     */
+    public void setId(String id);
+
+    /**
+     * Sets the image for this action, as an image descriptor.
+     * <p>
+     * Fires a property change event for the <code>IMAGE</code> property
+     * if the image actually changes as a consequence.
+     * </p>
+     *
+     * @param newImage the image, or <code>null</code> if this
+     *   action should not have an image
+     * @see #IMAGE
+     */
+    public void setImageDescriptor(ImageDescriptor newImage);
+
+    /**
+     * Sets the menu creator for this action. Applicable for style
+     * <code>AS_DROP_DOWN_MENU</code>.
+     *
+     * @param creator the menu creator, or <code>null</code> if none
+     */
+    public void setMenuCreator(IMenuCreator creator);
+
+    /**
+     * Sets the text for this action.
+     * <p>
+     * An accelerator specification may follow the actual text, separated from it by
+     * an '@' or a '\t' character.  An accelerator specification consists of zero or more
+     * modifier tokens followed by a key code token.  The tokens are separated by a '+' character.
+     * </p>
+     * <p>
+     * Fires a property change event for the <code>TEXT</code> property
+     * if the text actually changes as a consequence.
+     * </p>
+     *
+     * @param text the text, or <code>null</code> if none
+     * @see #TEXT
+     * @see Action#findModifier
+     * @see Action#findKeyCode
+     */
+    public void setText(String text);
+
+    /**
+     * Sets the tool tip text for this action.
+     * <p>
+     * Fires a property change event for the <code>TOOL_TIP_TEXT</code> property
+     * if the tool tip text actually changes as a consequence.
+     * </p>
+     *
+     * @param text the tool tip text, or <code>null</code> if none
+     * @see #TOOL_TIP_TEXT
+     */
+    public void setToolTipText(String text);
+
+    /**
+     * <p>
+     * Sets the accelerator keycode that this action maps to. This is a bitwise OR
+     * of zero or more DWT key modifier masks (i.e. DWT.CTRL or DWT.ALT) and a
+     * character code. For example, for Ctrl+Z, use <code>DWT.CTRL | 'Z'</code>.
+     * Use 0 for no accelerator.
+     * </p>
+     * <p>
+     * This method should no longer be used for actions in the Eclipse workbench.
+     * <code>IWorkbenchCommandSupport</code> and
+     * <code>IWorkbenchContextSupport</code> provide all the functionality
+     * required for key bindings. If you set an accelerator using this method, then
+     * it will not work in the workbench if it conflicts any existing key binding,
+     * or if there is a different key binding defined for this action's definition
+     * id. The definition id should be used instead -- referring to the command in
+     * the workbench from which the key binding should be retrieved.
+     * </p>
+     *
+     * @param keycode
+     *            the keycode to be accepted.
+     */
+    public void setAccelerator(int keycode);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/action/IMenuCreator.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.action.IMenuCreator;
+
+import dwt.widgets.Control;
+import dwt.widgets.Menu;
+
+/**
+ * Interface for something that creates and disposes of DWT menus.  Note that
+ * it is the responsibility of the implementor to dispose of DWT menus it
+ * creates.
+ */
+public interface IMenuCreator {
+    /**
+     * Disposes the menu returned by <code>getMenu</code>. Does nothing
+     * if there is no menu.  This method will be executed only when the
+     * parent of the menu is disposed.
+     */
+    public void dispose();
+
+    /**
+     * Returns the DWT menu, created as a pop up menu parented by the
+     * given control.  In most cases, this menu can be created once, cached and reused
+     * when the pop-up/drop-down action occurs.  If the menu must be dynamically
+     * created (i.e., each time it is popped up or dropped down), the old menu
+     * should be disposed of before replacing it with the new menu.
+     *
+     * @param parent the parent control
+     * @return the menu, or <code>null</code> if the menu could not
+     *  be created
+     */
+    public Menu getMenu(Control parent);
+
+    /**
+     * Returns an DWT menu created as a drop down menu parented by the
+     * given menu.  In most cases, this menu can be created once, cached and reused
+     * when the pop-up/drop-down action occurs.  If the menu must be dynamically
+     * created (i.e., each time it is popped up or dropped down), the old menu
+     * should be disposed of before replacing it with the new menu.
+     *
+     * @param parent the parent menu
+     * @return the menu, or <code>null</code> if the menu could not
+     *  be created
+     */
+    public Menu getMenu(Menu parent);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/dialogs/AnimatorFactory.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ ******************************************************************************/
+
+module dwtx.jface.dialogs.AnimatorFactory;
+
+import dwtx.jface.dialogs.ControlAnimator;
+
+import dwt.widgets.Control;
+
+
+/**
+ * Factory for control animators used by JFace to animate the display of an DWT
+ * Control. Through the use of the method
+ * {@link dwtx.jface.util.Policy#setAnimatorFactory(AnimatorFactory)}
+ * a new type of animator factory can be plugged into JFace.
+ *
+ * @since 3.2
+ * @deprecated as of 3.3, this class is no longer used.
+ */
+public class AnimatorFactory {
+    /**
+     * Creates a new ControlAnimator for use by JFace in animating
+     * the display of an DWT Control. <p>
+     * Subclasses should override this method.
+     *
+     * @param control the DWT Control to de displayed
+     * @return the ControlAnimator.
+     * @since 3.2
+     */
+    public ControlAnimator createAnimator(Control control) {
+        return new ControlAnimator(control);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/dialogs/ControlAnimator.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ ******************************************************************************/
+
+module dwtx.jface.dialogs.ControlAnimator;
+
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Control;
+
+/**
+ * ControlAnimator provides a simple implementation to display or hide a control
+ * at the bottom of the parent composite. Other animations will be written as
+ * subclasses of this class. <p>
+ * Instances of this class can be created using an AnimatorFactory.
+ *
+ * @since 3.2
+ */
+
+
+public class ControlAnimator {
+    /** the control that will be displayed or hidden */
+    protected Control control;
+
+    /**
+     * Constructs a new ControlAnimator instance and passes along the
+     * control that will be displayed or hidden.
+     *
+     * @param control the control that will be displayed or hidden.
+     */
+    public this(Control control) {
+        this.control = control;
+    }
+
+    /**
+     * Displays or hides a control at the bottom of the parent composite
+     * and makes use of the control's DWT visible flag.<p>
+     * Subclasses should override this method.</p>
+     *
+     * @param visible <code>true</code> if the control should be shown,
+     *        and <code>false</code> otherwise.
+     */
+    public void setVisible(bool visible){
+        // Using the DWT visible flag to determine if the control has
+        // already been displayed or hidden. Return if already displayed
+        // and visible is true, or if already hidden and visible is false.
+        if (!(control.isVisible() ^ visible))
+            return;
+        control.setVisible(visible);
+        Rectangle parentBounds = control.getParent().getBounds();
+        int bottom = parentBounds.height;
+        int endY = visible ? bottom - control.getBounds().height
+                : bottom;
+        Point loc = control.getLocation();
+        control.setLocation(loc.x,endY);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/dialogs/ErrorSupportProvider.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 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 dwtx.jface.dialogs.ErrorSupportProvider;
+
+
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwtx.core.runtime.IStatus;
+
+/**
+ * A ErrorSupportProvider defines the area to be shown in an error dialog for extra support information.
+ * @since 3.3
+ *
+ */
+public abstract class ErrorSupportProvider {
+
+
+        /**
+         * Create an area for adding support components as a child of parent.
+         * @param parent The parent {@link Composite}
+         * @param status The {@link IStatus} that is being displayed.
+         * @return Control
+         */
+        public abstract Control createSupportArea(Composite parent, IStatus status);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/resource/DerivedImageDescriptor.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.resource.DerivedImageDescriptor;
+
+import dwtx.jface.resource.ImageDescriptor;
+import dwtx.jface.resource.DeviceResourceException;
+
+import dwt.DWT;
+import dwt.DWTException;
+import dwt.graphics.Device;
+import dwt.graphics.Image;
+import dwt.graphics.ImageData;
+import dwt.widgets.Display;
+
+import dwt.dwthelper.utils;
+
+/**
+ * An image descriptor which creates images based on another ImageDescriptor, but with
+ * additional DWT flags. Note that this is only intended for compatibility.
+ *
+ * @since 3.1
+ */
+final class DerivedImageDescriptor : ImageDescriptor {
+
+    private ImageDescriptor original;
+    private int flags;
+
+    /**
+     * Create a new image descriptor
+     * @param original the original one
+     * @param swtFlags flags to be used when image is created {@link Image#Image(Device, Image, int)}
+     * @see DWT#IMAGE_COPY
+     * @see DWT#IMAGE_DISABLE
+     * @see DWT#IMAGE_GRAY
+     */
+    public this(ImageDescriptor original, int swtFlags) {
+        this.original = original;
+        flags = swtFlags;
+    }
+
+    public Object createResource(Device device) {
+        try {
+            return internalCreateImage(device);
+        } catch (DWTException e) {
+            throw new DeviceResourceException(this, e);
+        }
+    }
+
+    public Image createImage(Device device) {
+        return internalCreateImage(device);
+    }
+
+    public override hash_t toHash() {
+        return original.toHash() + flags;
+    }
+
+    public override int opEquals(Object arg0) {
+        if ( auto desc = cast(DerivedImageDescriptor)arg0 ) {
+            return desc.original is original && flags is desc.flags;
+        }
+
+        return false;
+    }
+
+    /**
+     * Creates a new Image on the given device. Note that we defined a new
+     * method rather than overloading createImage since this needs to be
+     * called by getImageData(), and we want to be absolutely certain not
+     * to cause infinite recursion if the base class gets refactored.
+     *
+     * @param device device to create the image on
+     * @return a newly allocated Image. Must be disposed by calling image.dispose().
+     */
+    private final Image internalCreateImage(Device device) {
+        Image originalImage = original.createImage(device);
+        Image result = new Image(device, originalImage, flags);
+        original.destroyResource(originalImage);
+        return result;
+    }
+
+    public ImageData getImageData() {
+        Image image = internalCreateImage(Display.getCurrent());
+        ImageData result = image.getImageData();
+        image.dispose();
+        return result;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/resource/DeviceResourceDescriptor.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.resource.DeviceResourceDescriptor;
+
+import dwt.graphics.Device;
+
+/**
+ * Instances of this class can allocate and dispose DWT resources. Each
+ * instance describes a particular resource (such as a Color, Font, or Image)
+ * and can create and destroy that resource on demand. DeviceResourceDescriptors
+ * are managed by a ResourceRegistry.
+ *
+ * @see dwtx.jface.resource.ResourceManager
+ *
+ * @since 3.1
+ */
+public abstract class DeviceResourceDescriptor {
+    /**
+     * Creates the resource described by this descriptor
+     *
+     * @since 3.1
+     *
+     * @param device the Device on which to allocate the resource
+     * @return the newly allocated resource (not null)
+     * @throws DeviceResourceException if unable to allocate the resource
+     */
+    public abstract Object createResource(Device device);
+
+    /**
+     * Undoes everything that was done by a previous call to create(...), given
+     * the object that was returned by create(...).
+     *
+     * @since 3.1
+     *
+     * @param previouslyCreatedObject an object that was returned by an equal
+     * descriptor in a previous call to createResource(...).
+     */
+    public abstract void destroyResource(Object previouslyCreatedObject);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/resource/DeviceResourceException.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.resource.DeviceResourceException;
+
+import dwtx.jface.resource.DeviceResourceDescriptor;
+
+import dwt.dwthelper.utils;
+
+/**
+ * Thrown when allocation of an DWT device resource fails
+ *
+ * @since 3.1
+ */
+public class DeviceResourceException : RuntimeException {
+
+    private Exception cause;
+
+    /**
+     * All serializable objects should have a stable serialVersionUID
+     */
+    private static const long serialVersionUID = 11454598756198L;
+
+    /**
+     * Creates a DeviceResourceException indicating an error attempting to
+     * create a resource and an embedded low-level exception describing the cause
+     *
+     * @param missingResource
+     * @param cause cause of the exception (or null if none)
+     */
+    public this(DeviceResourceDescriptor missingResource, Exception cause) {
+        super("Unable to create resource " ~ missingResource.toString()); //$NON-NLS-1$
+        // don't pass the cause to super, to allow compilation against JCL Foundation (bug 80059)
+        this.cause = cause;
+    }
+
+    /**
+     * Creates a DeviceResourceException indicating an error attempting to
+     * create a resource
+     *
+     * @param missingResource
+     */
+    public this(DeviceResourceDescriptor missingResource) {
+        this(missingResource, null);
+    }
+
+    /**
+     * Returns the cause of this throwable or <code>null</code> if the
+     * cause is nonexistent or unknown.
+     *
+     * @return the cause or <code>null</code>
+     * @since 3.1
+     */
+    public Exception getCause() {
+        return cause;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/resource/FileImageDescriptor.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.resource.FileImageDescriptor;
+
+import dwtx.jface.resource.ImageDescriptor;
+
+// import java.io.BufferedInputStream;
+// import java.io.FileInputStream;
+// import java.io.FileNotFoundException;
+// import java.io.IOException;
+// import java.io.InputStream;
+
+import dwt.DWT;
+import dwt.DWTException;
+import dwt.graphics.ImageData;
+
+import dwt.dwthelper.utils;
+import dwt.dwthelper.InputStream;
+import dwt.dwthelper.FileInputStream;
+import dwt.dwthelper.BufferedInputStream;
+
+/**
+ * An image descriptor that loads its image information
+ * from a file.
+ */
+class FileImageDescriptor : ImageDescriptor {
+
+    /**
+     * The class whose resource directory contain the file,
+     * or <code>null</code> if none.
+     */
+    private ClassInfo location;
+
+    /**
+     * The name of the file.
+     */
+    private String name;
+
+    /**
+     * Creates a new file image descriptor.
+     * The file has the given file name and is located
+     * in the given class's resource directory. If the given
+     * class is <code>null</code>, the file name must be absolute.
+     * <p>
+     * Note that the file is not accessed until its
+     * <code>getImageDate</code> method is called.
+     * </p>
+     *
+     * @param clazz class for resource directory, or
+     *   <code>null</code>
+     * @param filename the name of the file
+     */
+    this(ClassInfo clazz, String filename) {
+        this.location = clazz;
+        this.name = filename;
+    }
+
+    /* (non-Javadoc)
+     * Method declared on Object.
+     */
+    public bool equals(Object o) {
+        if (!( cast(FileImageDescriptor)o )) {
+            return false;
+        }
+        FileImageDescriptor other = cast(FileImageDescriptor) o;
+        if (location !is null) {
+            if ( location.name != other.location.name ) {
+                return false;
+            }
+        } else {
+            if (other.location !is null) {
+                return false;
+            }
+        }
+        return name == other.name;
+    }
+
+    /* (non-Javadoc)
+     * Method declared on ImageDesciptor.
+     * Returns null if the image data cannot be read.
+     */
+    public ImageData getImageData() {
+        InputStream in_ = getStream();
+        ImageData result = null;
+        if (in_ !is null) {
+            try {
+                result = new ImageData(in_);
+            } catch (DWTException e) {
+                if (e.code !is DWT.ERROR_INVALID_IMAGE) {
+                    throw e;
+                // fall through otherwise
+                }
+            } finally {
+                in_.close();
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Returns a stream on the image contents.  Returns
+     * null if a stream could not be opened.
+     *
+     * @return the buffered stream on the file or <code>null</code>
+     * if the file cannot be found
+     */
+    private InputStream getStream() {
+        InputStream is_ = null;
+
+        if (location !is null) {
+            is_ = ClassInfoGetResourceAsStream( location, name);
+
+        } else {
+            try {
+                is_ = new FileInputStream(name);
+            } catch (/+FileNotFoundException+/ IOException e) {
+                return null;
+            }
+        }
+        if (is_ is null) {
+            return null;
+        } else {
+            return new BufferedInputStream(is_);
+        }
+    }
+
+    /* (non-Javadoc)
+     * Method declared on Object.
+     */
+    public override hash_t toHash() {
+        int code = dwt.dwthelper.utils.toHash(name);
+        if (location !is null) {
+            code += location.toHash();
+        }
+        return code;
+    }
+
+    /* (non-Javadoc)
+     * Method declared on Object.
+     */
+    /**
+     * The <code>FileImageDescriptor</code> implementation of this <code>Object</code> method
+     * returns a string representation of this object which is suitable only for debugging.
+     */
+    public override String toString() {
+        return "FileImageDescriptor(location=" ~ location.toString() ~ ", name=" ~ name ~ ")";//$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/resource/ImageDataImageDescriptor.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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 dwtx.jface.resource.ImageDataImageDescriptor;
+
+import dwt.graphics.Device;
+import dwt.graphics.Image;
+import dwt.graphics.ImageData;
+
+import dwtx.jface.resource.ImageDescriptor;
+
+import dwt.dwthelper.utils;
+
+/**
+ * @since 3.1
+ */
+class ImageDataImageDescriptor : ImageDescriptor {
+
+    private ImageData data;
+
+    /**
+     * Original image being described, or null if this image is described
+     * completely using its ImageData
+     */
+    private Image originalImage = null;
+
+    /**
+     * Creates an image descriptor, given an image and the device it was created on.
+     *
+     * @param originalImage
+     */
+    this(Image originalImage) {
+        this(originalImage.getImageData());
+        this.originalImage = originalImage;
+    }
+
+    /**
+     * Creates an image descriptor, given some image data.
+     *
+     * @param data describing the image
+     */
+
+    this(ImageData data) {
+        this.data = data;
+    }
+
+    /* (non-Javadoc)
+     * @see dwtx.jface.resource.DeviceResourceDescriptor#create(dwt.graphics.Device)
+     */
+    public Object createResource(Device device) {
+
+        // If this descriptor is an existing font, then we can return the original font
+        // if this is the same device.
+        if (originalImage !is null) {
+            // If we're allocating on the same device as the original font, return the original.
+            if (originalImage.getDevice() is device) {
+                return originalImage;
+            }
+        }
+
+        return super.createResource(device);
+    }
+
+    /* (non-Javadoc)
+     * @see dwtx.jface.resource.DeviceResourceDescriptor#destroy(java.lang.Object)
+     */
+    public void destroyResource(Object previouslyCreatedObject) {
+        if (previouslyCreatedObject is originalImage) {
+            return;
+        }
+
+        super.destroyResource(previouslyCreatedObject);
+    }
+
+    /* (non-Javadoc)
+     * @see dwtx.jface.resource.ImageDescriptor#getImageData()
+     */
+    public ImageData getImageData() {
+        return data;
+    }
+
+    /* (non-Javadoc)
+     * @see Object#hashCode
+     */
+    public override hash_t toHash() {
+         if (originalImage !is null) {
+             return System.identityHashCode(originalImage);
+         }
+         return data.toHash();
+    }
+
+    /* (non-Javadoc)
+     * @see Object#equals
+     */
+    public override int opEquals(Object obj) {
+        if (!(cast(ImageDataImageDescriptor)obj )) {
+            return false;
+        }
+
+        ImageDataImageDescriptor imgWrap = cast(ImageDataImageDescriptor) obj;
+
+        //Intentionally using is instead of equals() as Image.hashCode() changes
+        //when the image is disposed and so leaks may occur with equals()
+
+        if (originalImage !is null) {
+            return imgWrap.originalImage is originalImage;
+        }
+
+        return (imgWrap.originalImage is null && data.opEquals(imgWrap.data));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/resource/ImageDescriptor.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,344 @@
+/*******************************************************************************
+ * 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.resource.ImageDescriptor;
+
+import dwtx.jface.resource.DeviceResourceDescriptor;
+import dwtx.jface.resource.FileImageDescriptor;
+import dwtx.jface.resource.URLImageDescriptor;
+import dwtx.jface.resource.ImageDataImageDescriptor;
+import dwtx.jface.resource.DerivedImageDescriptor;
+import dwtx.jface.resource.DeviceResourceException;
+import dwtx.jface.resource.MissingImageDescriptor;
+
+import tango.net.Uri;
+
+import dwt.DWTException;
+import dwt.graphics.Device;
+import dwt.graphics.Image;
+import dwt.graphics.ImageData;
+import dwt.graphics.PaletteData;
+import dwt.graphics.RGB;
+import dwt.widgets.Display;
+
+import dwt.dwthelper.utils;
+
+/**
+ * An image descriptor is an object that knows how to create
+ * an DWT image.  It does not hold onto images or cache them,
+ * but rather just creates them on demand.  An image descriptor
+ * is intended to be a lightweight representation of an image
+ * that can be manipulated even when no DWT display exists.
+ * <p>
+ * This package defines a concrete image descriptor implementation
+ * which reads an image from a file (<code>FileImageDescriptor</code>).
+ * It also provides abstract framework classes (this one and
+ * <code>CompositeImageDescriptor</code>) which may be subclassed to define
+ * news kinds of image descriptors.
+ * </p>
+ * <p>
+ * Using this abstract class involves defining a concrete subclass
+ * and providing an implementation for the <code>getImageData</code>
+ * method.
+ * </p>
+ * <p>
+ * There are two ways to get an Image from an ImageDescriptor. The method
+ * createImage will always return a new Image which must be disposed by
+ * the caller. Alternatively, createResource() returns a shared
+ * Image. When the caller is done with an image obtained from createResource,
+ * they must call destroyResource() rather than disposing the Image directly.
+ * The result of createResource() can be safely cast to an Image.
+ * </p>
+ *
+ * @see dwt.graphics.Image
+ */
+public abstract class ImageDescriptor : DeviceResourceDescriptor {
+
+    /**
+     * A small red square used to warn that an image cannot be created.
+     * <p>
+     */
+    protected static const ImageData DEFAULT_IMAGE_DATA;
+
+    static this(){
+        DEFAULT_IMAGE_DATA = new ImageData(6, 6, 1, new PaletteData( [ new RGB(255, 0, 0)  ] ));
+    }
+
+    /**
+     * Constructs an image descriptor.
+     */
+    protected this() {
+        // do nothing
+    }
+
+    /**
+     * Creates and returns a new image descriptor from a file.
+     * Convenience method for
+     * <code>new FileImageDescriptor(location,filename)</code>.
+     *
+     * @param location the class whose resource directory contain the file
+     * @param filename the file name
+     * @return a new image descriptor
+     */
+    public static ImageDescriptor createFromFile(ClassInfo location, String filename) {
+        return new FileImageDescriptor(location, filename);
+    }
+
+    /**
+     * Creates and returns a new image descriptor given ImageData
+     * describing the image.
+     *
+     * @since 3.1
+     *
+     * @param data contents of the image
+     * @return newly created image descriptor
+     */
+    public static ImageDescriptor createFromImageData(ImageData data) {
+        return new ImageDataImageDescriptor(data);
+    }
+
+    /**
+     * Creates and returns a new image descriptor for the given image. Note
+     * that disposing the original Image will cause the descriptor to become invalid.
+     *
+     * @since 3.1
+     *
+     * @param img image to create
+     * @return a newly created image descriptor
+     */
+    public static ImageDescriptor createFromImage(Image img) {
+        return new ImageDataImageDescriptor(img);
+    }
+
+    /**
+     * Creates an ImageDescriptor based on the given original descriptor, but with additional
+     * DWT flags.
+     *
+     * <p>
+     * Note that this sort of ImageDescriptor is slower and consumes more resources than
+     * a regular image descriptor. It will also never generate results that look as nice as
+     * a hand-drawn image. Clients are encouraged to supply their own disabled/grayed/etc. images
+     * rather than using a default image and transforming it.
+     * </p>
+     *
+     * @param originalImage image to transform
+     * @param swtFlags any flag that can be passed to the flags argument of Image#Image(Device, Image, int)
+     * @return an ImageDescriptor that creates new images by transforming the given image descriptor
+     *
+     * @see Image#Image(Device, Image, int)
+     * @since 3.1
+     *
+     */
+    public static ImageDescriptor createWithFlags(ImageDescriptor originalImage, int swtFlags) {
+        return new DerivedImageDescriptor(originalImage, swtFlags);
+    }
+
+    /**
+     * Creates and returns a new image descriptor for the given image. This
+     * method takes the Device that created the Image as an argument, allowing
+     * the original Image to be reused if the descriptor is asked for another
+     * Image on the same device. Note that disposing the original Image will
+     * cause the descriptor to become invalid.
+     *
+     * @deprecated use {@link ImageDescriptor#createFromImage(Image)}
+     * @since 3.1
+     *
+     * @param img image to create
+     * @param theDevice the device that was used to create the Image
+     * @return a newly created image descriptor
+     */
+    public static ImageDescriptor createFromImage(Image img, Device theDevice) {
+        return new ImageDataImageDescriptor(img);
+    }
+
+    /**
+     * Creates and returns a new image descriptor from a URL.
+     *
+     * @param url The URL of the image file.
+     * @return a new image descriptor
+     */
+    public static ImageDescriptor createFromURL(Uri url) {
+        if (url is null) {
+            return getMissingImageDescriptor();
+        }
+        return new URLImageDescriptor(url);
+    }
+
+    /* (non-Javadoc)
+     * @see dwtx.jface.resource.DeviceResourceDescriptor#createResource(dwt.graphics.Device)
+     */
+    public Object createResource(Device device) {
+        Image result = createImage(false, device);
+        if (result is null) {
+            throw new DeviceResourceException(this);
+        }
+        return result;
+    }
+
+    /* (non-Javadoc)
+     * @see dwtx.jface.resource.DeviceResourceDescriptor#destroyResource(Object)
+     */
+    public void destroyResource(Object previouslyCreatedObject) {
+        (cast(Image)previouslyCreatedObject).dispose();
+    }
+
+    /**
+     * Creates and returns a new DWT image for this image descriptor. Note that
+     * each call returns a new DWT image object. The returned image must be
+     * explicitly disposed using the image's dispose call. The image will not be
+     * automatically garbage collected. A default image is returned in the event
+     * of an error.
+     *
+     * <p>
+     * Note: this method differs from createResource(Device) in that the returned image
+     * must be disposed directly, whereas an image obtained from createResource(...)
+     * must be disposed by calling destroyResource(...). It is not possible to
+     * mix-and-match. If you obtained the Image from this method, you must not dispose
+     * it by calling destroyResource. Clients are encouraged to use
+     * create/destroyResource and downcast the result to Image rather than using
+     * createImage.
+     * </p>
+     *
+     * <p>
+     * Note: it is still possible for this method to return <code>null</code>
+     * in extreme cases, for example if DWT runs out of image handles.
+     * </p>
+     *
+     * @return a new image or <code>null</code> if the image could not be
+     *         created
+     */
+    public Image createImage() {
+        return createImage(true);
+    }
+
+    /**
+     * Creates and returns a new DWT image for this image descriptor. The
+     * returned image must be explicitly disposed using the image's dispose
+     * call. The image will not be automatically garbage collected. In the event
+     * of an error, a default image is returned if
+     * <code>returnMissingImageOnError</code> is true, otherwise
+     * <code>null</code> is returned.
+     * <p>
+     * Note: Even if <code>returnMissingImageOnError</code> is true, it is
+     * still possible for this method to return <code>null</code> in extreme
+     * cases, for example if DWT runs out of image handles.
+     * </p>
+     *
+     * @param returnMissingImageOnError
+     *            flag that determines if a default image is returned on error
+     * @return a new image or <code>null</code> if the image could not be
+     *         created
+     */
+    public Image createImage(bool returnMissingImageOnError) {
+        return createImage(returnMissingImageOnError, Display.getCurrent());
+    }
+
+    /**
+     * Creates and returns a new DWT image for this image descriptor. The
+     * returned image must be explicitly disposed using the image's dispose
+     * call. The image will not be automatically garbage collected. A default
+     * image is returned in the event of an error.
+     * <p>
+     * Note: it is still possible for this method to return <code>null</code>
+     * in extreme cases, for example if DWT runs out of image handles.
+     * </p>
+     *
+     * @param device
+     *            the device on which to create the image
+     * @return a new image or <code>null</code> if the image could not be
+     *         created
+     * @since 2.0
+     */
+    public Image createImage(Device device) {
+        return createImage(true, device);
+    }
+
+    /**
+     * Creates and returns a new DWT image for this image descriptor. The
+     * returned image must be explicitly disposed using the image's dispose
+     * call. The image will not be automatically garbage collected. In the even
+     * of an error, a default image is returned if
+     * <code>returnMissingImageOnError</code> is true, otherwise
+     * <code>null</code> is returned.
+     * <p>
+     * Note: Even if <code>returnMissingImageOnError</code> is true, it is
+     * still possible for this method to return <code>null</code> in extreme
+     * cases, for example if DWT runs out of image handles.
+     * </p>
+     *
+     * @param returnMissingImageOnError
+     *            flag that determines if a default image is returned on error
+     * @param device
+     *            the device on which to create the image
+     * @return a new image or <code>null</code> if the image could not be
+     *         created
+     * @since 2.0
+     */
+    public Image createImage(bool returnMissingImageOnError, Device device) {
+
+        ImageData data = getImageData();
+        if (data is null) {
+            if (!returnMissingImageOnError) {
+                return null;
+            }
+            data = DEFAULT_IMAGE_DATA;
+        }
+
+        /*
+         * Try to create the supplied image. If there is an DWT Exception try and create
+         * the default image if that was requested. Return null if this fails.
+         */
+
+        try {
+            if (data.transparentPixel >= 0) {
+                ImageData maskData = data.getTransparencyMask();
+                return new Image(device, data, maskData);
+            }
+            return new Image(device, data);
+        } catch (DWTException exception) {
+            if (returnMissingImageOnError) {
+                try {
+                    return new Image(device, DEFAULT_IMAGE_DATA);
+                } catch (DWTException nextException) {
+                    return null;
+                }
+            }
+            return null;
+        }
+    }
+
+    /**
+     * Creates and returns a new DWT <code>ImageData</code> object
+     * for this image descriptor.
+     * Note that each call returns a new DWT image data object.
+     * <p>
+     * This framework method is declared public so that it is
+     * possible to request an image descriptor's image data without
+     * creating an DWT image object.
+     * </p>
+     * <p>
+     * Returns <code>null</code> if the image data could not be created.
+     * </p>
+     *
+     * @return a new image data or <code>null</code>
+     */
+    public abstract ImageData getImageData();
+
+    /**
+     * Returns the shared image descriptor for a missing image.
+     *
+     * @return the missing image descriptor
+     */
+    public static ImageDescriptor getMissingImageDescriptor() {
+        return MissingImageDescriptor.getInstance();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/resource/MissingImageDescriptor.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.resource.MissingImageDescriptor;
+
+import dwtx.jface.resource.ImageDescriptor;
+
+import dwt.graphics.ImageData;
+
+/**
+ * The image descriptor for a missing image.
+ * <p>
+ * Use <code>MissingImageDescriptor.getInstance</code> to
+ * access the singleton instance maintained in an
+ * internal state variable.
+ * </p>
+ */
+class MissingImageDescriptor : ImageDescriptor {
+    private static MissingImageDescriptor instance;
+
+    /**
+     * Constructs a new missing image descriptor.
+     */
+    private this() {
+        super();
+    }
+
+    /* (non-Javadoc)
+     * Method declared on ImageDesciptor.
+     */
+    public ImageData getImageData() {
+        return DEFAULT_IMAGE_DATA;
+    }
+
+    /**
+     * Returns the shared missing image descriptor instance.
+     *
+     * @return the image descriptor for a missing image
+     */
+    static MissingImageDescriptor getInstance() {
+        if (instance is null) {
+            instance = new MissingImageDescriptor();
+        }
+        return instance;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/resource/URLImageDescriptor.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.resource.URLImageDescriptor;
+
+import dwtx.jface.resource.ImageDescriptor;
+
+// import java.io.BufferedInputStream;
+// import java.io.IOException;
+// import java.io.InputStream;
+import tango.net.Uri;
+
+import dwt.DWT;
+import dwt.DWTException;
+import dwt.graphics.ImageData;
+
+import dwt.dwthelper.utils;
+import dwt.dwthelper.BufferedInputStream;
+import dwt.dwthelper.InputStream;
+
+/**
+ * An ImageDescriptor that gets its information from a URL.
+ * This class is not public API.  Use ImageDescriptor#createFromURL
+ * to create a descriptor that uses a URL.
+ */
+class URLImageDescriptor : ImageDescriptor {
+    private Uri url;
+
+    /**
+     * Creates a new URLImageDescriptor.
+     * @param url The URL to load the image from.  Must be non-null.
+     */
+    this(Uri url) {
+        this.url = url;
+    }
+
+    /* (non-Javadoc)
+     * Method declared on Object.
+     */
+    public bool equals(Object o) {
+        if (!(cast(URLImageDescriptor)o )) {
+            return false;
+        }
+        return (cast(URLImageDescriptor) o).url.opEquals(this.url) !is 0;
+    }
+
+    /* (non-Javadoc)
+     * Method declared on ImageDesciptor.
+     * Returns null if the image data cannot be read.
+     */
+    public ImageData getImageData() {
+        ImageData result = null;
+        InputStream in_ = getStream();
+        if (in_ !is null) {
+            scope(exit)
+                in_.close();
+            try {
+                result = new ImageData(in_);
+            } catch (DWTException e) {
+                if (e.code !is DWT.ERROR_INVALID_IMAGE) {
+                    throw e;
+                // fall through otherwise
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Returns a stream on the image contents.  Returns
+     * null if a stream could not be opened.
+     * @return the stream for loading the data
+     */
+    protected InputStream getStream() {
+        implMissing( __FILE__, __LINE__ );
+        return null;
+        //FIXME
+        /+
+        try {
+            return new BufferedInputStream(url.openStream());
+        } catch (IOException e) {
+            return null;
+        }
+        +/
+    }
+
+    /* (non-Javadoc)
+     * Method declared on Object.
+     */
+    public override hash_t toHash() {
+        return url.toHash();
+    }
+
+    /* (non-Javadoc)
+     * Method declared on Object.
+     */
+    /**
+     * The <code>URLImageDescriptor</code> implementation of this <code>Object</code> method
+     * returns a string representation of this object which is suitable only for debugging.
+     */
+    public override String toString() {
+        return "URLImageDescriptor(" ~ url.toString ~ ")"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/util/Assert.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.util.Assert;
+
+import dwt.dwthelper.utils;
+
+/**
+ * <code>Assert</code> is useful for for embedding runtime sanity checks
+ * in code. The static predicate methods all test a condition and throw some
+ * type of unchecked exception if the condition does not hold.
+ * <p>
+ * Assertion failure exceptions, like most runtime exceptions, are
+ * thrown when something is misbehaving. Assertion failures are invariably
+ * unspecified behavior; consequently, clients should never rely on
+ * these being thrown (or not thrown). <b>If you find yourself in the
+ * position where you need to catch an assertion failure, you have most
+ * certainly written your program incorrectly.</b>
+ * </p>
+ * <p>
+ * Note that an <code>assert</code> statement is slated to be added to the
+ * Java language in JDK 1.4, rending this class obsolete.
+ *
+ * @deprecated As of 3.3, replaced by {@link dwtx.core.runtime.Assert}
+ * </p>
+ */
+public final class Assert {
+
+    /**
+     * <code>AssertionFailedException</code> is a runtime exception thrown
+     * by some of the methods in <code>Assert</code>.
+     * <p>
+     * This class is not declared public to prevent some misuses; programs that catch
+     * or otherwise depend on assertion failures are susceptible to unexpected
+     * breakage when assertions in the code are added or removed.
+     * </p>
+     */
+    private static class AssertionFailedException : RuntimeException {
+
+        /**
+         * Generated serial version UID for this class.
+         * @since 3.1
+         */
+        private static final long serialVersionUID = 3257852073508024376L;
+
+        /**
+         * Constructs a new exception.
+         */
+        public this() {
+        }
+
+        /**
+         * Constructs a new exception with the given message.
+         * @param detail the detail message
+         */
+        public this(String detail) {
+            super(detail);
+        }
+    }
+
+    /* This class is not intended to be instantiated. */
+    private this() {
+    }
+
+    /**
+     * Asserts that an argument is legal. If the given bool is
+     * not <code>true</code>, an <code>IllegalArgumentException</code>
+     * is thrown.
+     *
+     * @param expression the outcome of the check
+     * @return <code>true</code> if the check passes (does not return
+     *    if the check fails)
+     * @exception IllegalArgumentException if the legality test failed
+     */
+    public static bool isLegal(bool expression) {
+        // succeed as quickly as possible
+        if (expression) {
+            return true;
+        }
+        return isLegal(expression, "");//$NON-NLS-1$
+    }
+
+    /**
+     * Asserts that an argument is legal. If the given bool is
+     * not <code>true</code>, an <code>IllegalArgumentException</code>
+     * is thrown.
+     * The given message is included in that exception, to aid debugging.
+     *
+     * @param expression the outcome of the check
+     * @param message the message to include in the exception
+     * @return <code>true</code> if the check passes (does not return
+     *    if the check fails)
+     * @exception IllegalArgumentException if the legality test failed
+     */
+    public static bool isLegal(bool expression, String message) {
+        if (!expression) {
+            throw new IllegalArgumentException("assertion failed; " ~ message); //$NON-NLS-1$
+        }
+        return expression;
+    }
+
+    /**
+     * Asserts that the given object is not <code>null</code>. If this
+     * is not the case, some kind of unchecked exception is thrown.
+     * <p>
+     * As a general rule, parameters passed to API methods must not be
+     * <code>null</code> unless <b>explicitly</b> allowed in the method's
+     * specification. Similarly, results returned from API methods are never
+     * <code>null</code> unless <b>explicitly</b> allowed in the method's
+     * specification. Implementations are encouraged to make regular use of
+     * <code>Assert.isNotNull</code> to ensure that <code>null</code>
+     * parameters are detected as early as possible.
+     * </p>
+     *
+     * @param object the value to test
+     * @exception AssertionFailedException an unspecified unchecked exception if the object
+     *   is <code>null</code>
+     */
+    public static void isNotNull(Object object) {
+        // succeed as quickly as possible
+        if (object !is null) {
+            return;
+        }
+        isNotNull(object, "");//$NON-NLS-1$
+    }
+
+    /**
+     * Asserts that the given object is not <code>null</code>. If this
+     * is not the case, some kind of unchecked exception is thrown.
+     * The given message is included in that exception, to aid debugging.
+     * <p>
+     * As a general rule, parameters passed to API methods must not be
+     * <code>null</code> unless <b>explicitly</b> allowed in the method's
+     * specification. Similarly, results returned from API methods are never
+     * <code>null</code> unless <b>explicitly</b> allowed in the method's
+     * specification. Implementations are encouraged to make regular use of
+     * <code>Assert.isNotNull</code> to ensure that <code>null</code>
+     * parameters are detected as early as possible.
+     * </p>
+     *
+     * @param object the value to test
+     * @param message the message to include in the exception
+     * @exception AssertionFailedException an unspecified unchecked exception if the object
+     *   is <code>null</code>
+     */
+    public static void isNotNull(Object object, String message) {
+        if (object is null) {
+            throw new AssertionFailedException("null argument;" ~ message);//$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Asserts that the given bool is <code>true</code>. If this
+     * is not the case, some kind of unchecked exception is thrown.
+     *
+     * @param expression the outcome of the check
+     * @return <code>true</code> if the check passes (does not return
+     *    if the check fails)
+     */
+    public static bool isTrue(bool expression) {
+        // succeed as quickly as possible
+        if (expression) {
+            return true;
+        }
+        return isTrue(expression, "");//$NON-NLS-1$
+    }
+
+    /**
+     * Asserts that the given bool is <code>true</code>. If this
+     * is not the case, some kind of unchecked exception is thrown.
+     * The given message is included in that exception, to aid debugging.
+     *
+     * @param expression the outcome of the check
+     * @param message the message to include in the exception
+     * @return <code>true</code> if the check passes (does not return
+     *    if the check fails)
+     */
+    public static bool isTrue(bool expression, String message) {
+        if (!expression) {
+            throw new AssertionFailedException("Assertion failed: " ~ message);//$NON-NLS-1$
+        }
+        return expression;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/util/Geometry.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,812 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.util.Geometry;
+
+import dwt.DWT;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Control;
+
+import dwt.dwthelper.utils;
+import dwt.dwthelper.Integer;
+
+/**
+ * Contains static methods for performing simple geometric operations
+ * on the DWT geometry classes.
+ *
+ * @since 3.0
+ */
+public class Geometry {
+
+    /**
+     * Prevent this class from being instantiated.
+     *
+     * @since 3.0
+     */
+    private this() {
+        //This is not instantiated
+    }
+
+    /**
+     * Returns the square of the distance between two points.
+     * <p>This is preferred over the real distance when searching
+     * for the closest point, since it avoids square roots.</p>
+     *
+     * @param p1 first endpoint
+     * @param p2 second endpoint
+     * @return the square of the distance between the two points
+     *
+     * @since 3.0
+     */
+    public static int distanceSquared(Point p1, Point p2) {
+        int term1 = p1.x - p2.x;
+        int term2 = p1.y - p2.y;
+        return term1 * term1 + term2 * term2;
+    }
+
+    /**
+     * Returns the magnitude of the given 2d vector (represented as a Point)
+     *
+     * @param p point representing the 2d vector whose magnitude is being computed
+     * @return the magnitude of the given 2d vector
+     * @since 3.0
+     */
+    public static double magnitude(Point p) {
+        return Math.sqrt( cast(real) magnitudeSquared(p));
+    }
+
+    /**
+     * Returns the square of the magnitude of the given 2-space vector (represented
+     * using a point)
+     *
+     * @param p the point whose magnitude is being computed
+     * @return the square of the magnitude of the given vector
+     * @since 3.0
+     */
+    public static int magnitudeSquared(Point p) {
+        return p.x * p.x + p.y * p.y;
+    }
+
+    /**
+     * Returns the dot product of the given vectors (expressed as Points)
+     *
+     * @param p1 the first vector
+     * @param p2 the second vector
+     * @return the dot product of the two vectors
+     * @since 3.0
+     */
+    public static int dotProduct(Point p1, Point p2) {
+        return p1.x * p2.x + p1.y * p2.y;
+    }
+
+    /**
+     * Returns a new point whose coordinates are the minimum of the coordinates of the
+     * given points
+     *
+     * @param p1 a Point
+     * @param p2 a Point
+     * @return a new point whose coordinates are the minimum of the coordinates of the
+     * given points
+     * @since 3.0
+     */
+    public static Point min(Point p1, Point p2) {
+        return new Point(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y));
+    }
+
+    /**
+     * Returns a new point whose coordinates are the maximum of the coordinates
+     * of the given points
+     * @param p1 a Point
+     * @param p2 a Point
+     * @return point a new point whose coordinates are the maximum of the coordinates
+     * @since 3.0
+     */
+    public static Point max(Point p1, Point p2) {
+        return new Point(Math.max(p1.x, p2.x), Math.max(p1.y, p2.y));
+    }
+
+    /**
+     * Returns a vector in the given direction with the given
+     * magnitude. Directions are given using DWT direction constants, and
+     * the resulting vector is in the screen's coordinate system. That is,
+     * the vector (0, 1) is down and the vector (1, 0) is right.
+     *
+     * @param distance magnitude of the vector
+     * @param direction one of DWT.TOP, DWT.BOTTOM, DWT.LEFT, or DWT.RIGHT
+     * @return a point representing a vector in the given direction with the given magnitude
+     * @since 3.0
+     */
+    public static Point getDirectionVector(int distance, int direction) {
+        switch (direction) {
+        case DWT.TOP:
+            return new Point(0, -distance);
+        case DWT.BOTTOM:
+            return new Point(0, distance);
+        case DWT.LEFT:
+            return new Point(-distance, 0);
+        case DWT.RIGHT:
+            return new Point(distance, 0);
+        }
+
+        return new Point(0, 0);
+    }
+
+    /**
+     * Returns the point in the center of the given rectangle.
+     *
+     * @param rect rectangle being computed
+     * @return a Point at the center of the given rectangle.
+     * @since 3.0
+     */
+    public static Point centerPoint(Rectangle rect) {
+        return new Point(rect.x + rect.width / 2, rect.y + rect.height / 2);
+    }
+
+    /**
+     * Returns a copy of the given point
+     *
+     * @param toCopy point to copy
+     * @return a copy of the given point
+     */
+    public static Point copy(Point toCopy) {
+        return new Point(toCopy.x, toCopy.y);
+    }
+
+    /**
+     * Sets result equal to toCopy
+     *
+     * @param result object that will be modified
+     * @param toCopy object that will be copied
+     * @since 3.1
+     */
+    public static void set(Point result, Point toCopy) {
+        result.x = toCopy.x;
+        result.y = toCopy.y;
+    }
+
+    /**
+     * Sets result equal to toCopy
+     *
+     * @param result object that will be modified
+     * @param toCopy object that will be copied
+     * @since 3.1
+     */
+    public static void set(Rectangle result, Rectangle toCopy) {
+        result.x = toCopy.x;
+        result.y = toCopy.y;
+        result.width = toCopy.width;
+        result.height = toCopy.height;
+    }
+
+    /**
+     * <p>Returns a new difference Rectangle whose x, y, width, and height are equal to the difference of the corresponding
+     * attributes from the given rectangles</p>
+     *
+     * <p></p>
+     * <b>Example: Compute the margins for a given Composite, and apply those same margins to a new GridLayout</b>
+     *
+     * <code><pre>
+     *      // Compute the client area, in the coordinate system of the input composite's parent
+     *      Rectangle clientArea = Display.getCurrent().map(inputComposite,
+     *          inputComposite.getParent(), inputComposite.getClientArea());
+     *
+     *      // Compute the margins for a given Composite by subtracting the client area from the composite's bounds
+     *      Rectangle margins = Geometry.subtract(inputComposite.getBounds(), clientArea);
+     *
+     *      // Now apply these margins to a new GridLayout
+     *      GridLayout layout = GridLayoutFactory.fillDefaults().margins(margins).create();
+     * </pre></code>
+     *
+     * @param rect1 first rectangle
+     * @param rect2 rectangle to subtract
+     * @return the difference between the two rectangles (computed as rect1 - rect2)
+     * @since 3.3
+     */
+    public static Rectangle subtract(Rectangle rect1, Rectangle rect2) {
+        return new Rectangle(rect1.x - rect2.x, rect1.y - rect2.y, rect1.width - rect2.width, rect1.height - rect2.height);
+    }
+
+    /**
+     * <p>Returns a new Rectangle whose x, y, width, and height is the sum of the x, y, width, and height values of
+     * both rectangles respectively.</p>
+     *
+     * @param rect1 first rectangle to add
+     * @param rect2 second rectangle to add
+     * @return a new rectangle whose x, y, height, and width attributes are the sum of the corresponding attributes from
+     *         the arguments.
+     * @since 3.3
+     */
+    public static Rectangle add(Rectangle rect1, Rectangle rect2) {
+        return new Rectangle(rect1.x + rect2.x, rect1.y + rect2.y,
+                rect1.width + rect2.width, rect1.height + rect2.height);
+    }
+
+    /**
+     * Adds two points as 2d vectors. Returns a new point whose coordinates are
+     * the sum of the original two points.
+     *
+     * @param point1 the first point (not null)
+     * @param point2 the second point (not null)
+     * @return a new point whose coordinates are the sum of the given points
+     * @since 3.0
+     */
+    public static Point add(Point point1, Point point2) {
+        return new Point(point1.x + point2.x, point1.y + point2.y);
+    }
+
+    /**
+     * Divides both coordinates of the given point by the given scalar.
+     *
+     * @since 3.1
+     *
+     * @param toDivide point to divide
+     * @param scalar denominator
+     * @return a new Point whose coordinates are equal to the original point divided by the scalar
+     */
+    public static Point divide(Point toDivide, int scalar) {
+        return new Point(toDivide.x / scalar, toDivide.y / scalar);
+    }
+
+
+    /**
+     * Performs vector subtraction on two points. Returns a new point equal to
+     * (point1 - point2).
+     *
+     * @param point1 initial point
+     * @param point2 vector to subtract
+     * @return the difference (point1 - point2)
+     * @since 3.0
+     */
+    public static Point subtract(Point point1, Point point2) {
+        return new Point(point1.x - point2.x, point1.y - point2.y);
+    }
+
+    /**
+     * Swaps the X and Y coordinates of the given point.
+     *
+     * @param toFlip modifies this point
+     * @since 3.1
+     */
+    public static void flipXY(Point toFlip) {
+        int temp = toFlip.x;
+        toFlip.x = toFlip.y;
+        toFlip.y = temp;
+    }
+
+    /**
+     * Swaps the X and Y coordinates of the given rectangle, along with the height and width.
+     *
+     * @param toFlip modifies this rectangle
+     * @since 3.1
+     */
+    public static void flipXY(Rectangle toFlip) {
+        int temp = toFlip.x;
+        toFlip.x = toFlip.y;
+        toFlip.y = temp;
+
+        temp = toFlip.width;
+        toFlip.width = toFlip.height;
+        toFlip.height = temp;
+    }
+
+    /**
+     * Returns the height or width of the given rectangle.
+     *
+     * @param toMeasure rectangle to measure
+     * @param width returns the width if true, and the height if false
+     * @return the width or height of the given rectangle
+     * @since 3.0
+     */
+    public static int getDimension(Rectangle toMeasure, bool width) {
+        if (width) {
+            return toMeasure.width;
+        }
+        return toMeasure.height;
+    }
+
+    /**
+     * Returns the x or y coordinates of the given point.
+     *
+     * @param toMeasure point being measured
+     * @param width if true, returns x. Otherwise, returns y.
+     * @return the x or y coordinate
+     * @since 3.1
+     */
+    public static int getCoordinate(Point toMeasure, bool width) {
+        return width ? toMeasure.x : toMeasure.y;
+    }
+
+    /**
+     * Returns the x or y coordinates of the given rectangle.
+     *
+     * @param toMeasure rectangle being measured
+     * @param width if true, returns x. Otherwise, returns y.
+     * @return the x or y coordinate
+     * @since 3.1
+     */
+    public static int getCoordinate(Rectangle toMeasure, bool width) {
+        return width ? toMeasure.x : toMeasure.y;
+    }
+
+    /**
+     * Sets one dimension of the given rectangle. Modifies the given rectangle.
+     *
+     * @param toSet rectangle to modify
+     * @param width if true, the width is modified. If false, the height is modified.
+     * @param newCoordinate new value of the width or height
+     * @since 3.1
+     */
+    public static void setDimension(Rectangle toSet, bool width, int newCoordinate) {
+        if (width) {
+            toSet.width = newCoordinate;
+        } else {
+            toSet.height = newCoordinate;
+        }
+    }
+
+    /**
+     * Sets one coordinate of the given rectangle. Modifies the given rectangle.
+     *
+     * @param toSet rectangle to modify
+     * @param width if true, the x coordinate is modified. If false, the y coordinate is modified.
+     * @param newCoordinate new value of the x or y coordinates
+     * @since 3.1
+     */
+    public static void setCoordinate(Rectangle toSet, bool width, int newCoordinate) {
+        if (width) {
+            toSet.x = newCoordinate;
+        } else {
+            toSet.y = newCoordinate;
+        }
+    }
+
+    /**
+     * Sets one coordinate of the given point. Modifies the given point.
+     *
+     * @param toSet point to modify
+     * @param width if true, the x coordinate is modified. If false, the y coordinate is modified.
+     * @param newCoordinate new value of the x or y coordinates
+     * @since 3.1
+     */
+    public static void setCoordinate(Point toSet, bool width, int newCoordinate) {
+        if (width) {
+            toSet.x = newCoordinate;
+        } else {
+            toSet.y = newCoordinate;
+        }
+    }
+
+    /**
+     * Returns the distance of the given point from a particular side of the given rectangle.
+     * Returns negative values for points outside the rectangle.
+     *
+     * @param rectangle a bounding rectangle
+     * @param testPoint a point to test
+     * @param edgeOfInterest side of the rectangle to test against
+     * @return the distance of the given point from the given edge of the rectangle
+     * @since 3.0
+     */
+    public static int getDistanceFromEdge(Rectangle rectangle, Point testPoint,
+            int edgeOfInterest) {
+        switch (edgeOfInterest) {
+        case DWT.TOP:
+            return testPoint.y - rectangle.y;
+        case DWT.BOTTOM:
+            return rectangle.y + rectangle.height - testPoint.y;
+        case DWT.LEFT:
+            return testPoint.x - rectangle.x;
+        case DWT.RIGHT:
+            return rectangle.x + rectangle.width - testPoint.x;
+        }
+
+        return 0;
+    }
+
+    /**
+     * Extrudes the given edge inward by the given distance. That is, if one side of the rectangle
+     * was sliced off with a given thickness, this returns the rectangle that forms the slice. Note
+     * that the returned rectangle will be inside the given rectangle if size > 0.
+     *
+     * @param toExtrude the rectangle to extrude. The resulting rectangle will share three sides
+     * with this rectangle.
+     * @param size distance to extrude. A negative size will extrude outwards (that is, the resulting
+     * rectangle will overlap the original iff this is positive).
+     * @param orientation the side to extrude.  One of DWT.LEFT, DWT.RIGHT, DWT.TOP, or DWT.BOTTOM. The
+     * resulting rectangle will always share this side with the original rectangle.
+     * @return a rectangle formed by extruding the given side of the rectangle by the given distance.
+     * @since 3.0
+     */
+    public static Rectangle getExtrudedEdge(Rectangle toExtrude, int size,
+            int orientation) {
+        Rectangle bounds = new Rectangle(toExtrude.x, toExtrude.y,
+                toExtrude.width, toExtrude.height);
+
+        if (!isHorizontal(orientation)) {
+            bounds.width = size;
+        } else {
+            bounds.height = size;
+        }
+
+        switch (orientation) {
+        case DWT.RIGHT:
+            bounds.x = toExtrude.x + toExtrude.width - bounds.width;
+            break;
+        case DWT.BOTTOM:
+            bounds.y = toExtrude.y + toExtrude.height - bounds.height;
+            break;
+        }
+
+        normalize(bounds);
+
+        return bounds;
+    }
+
+    /**
+     * Returns the opposite of the given direction. That is, returns DWT.LEFT if
+     * given DWT.RIGHT and visa-versa.
+     *
+     * @param swtDirectionConstant one of DWT.LEFT, DWT.RIGHT, DWT.TOP, or DWT.BOTTOM
+     * @return one of DWT.LEFT, DWT.RIGHT, DWT.TOP, or DWT.BOTTOM
+     * @since 3.0
+     */
+    public static int getOppositeSide(int swtDirectionConstant) {
+        switch (swtDirectionConstant) {
+        case DWT.TOP:
+            return DWT.BOTTOM;
+        case DWT.BOTTOM:
+            return DWT.TOP;
+        case DWT.LEFT:
+            return DWT.RIGHT;
+        case DWT.RIGHT:
+            return DWT.LEFT;
+        }
+
+        return swtDirectionConstant;
+    }
+
+    /**
+     * Converts the given bool into an DWT orientation constant.
+     *
+     * @param horizontal if true, returns DWT.HORIZONTAL. If false, returns DWT.VERTICAL
+     * @return DWT.HORIZONTAL or DWT.VERTICAL.
+     * @since 3.0
+     */
+    public static int getSwtHorizontalOrVerticalConstant(bool horizontal) {
+        if (horizontal) {
+            return DWT.HORIZONTAL;
+        }
+        return DWT.VERTICAL;
+    }
+
+    /**
+     * Returns true iff the given DWT side constant corresponds to a horizontal side
+     * of a rectangle. That is, returns true for the top and bottom but false for the
+     * left and right.
+     *
+     * @param swtSideConstant one of DWT.TOP, DWT.BOTTOM, DWT.LEFT, or DWT.RIGHT
+     * @return true iff the given side is horizontal.
+     * @since 3.0
+     */
+    public static bool isHorizontal(int swtSideConstant) {
+        return !(swtSideConstant is DWT.LEFT || swtSideConstant is DWT.RIGHT);
+    }
+
+    /**
+     * Moves the given rectangle by the given delta.
+     *
+     * @param rect rectangle to move (will be modified)
+     * @param delta direction vector to move the rectangle by
+     * @since 3.0
+     */
+    public static void moveRectangle(Rectangle rect, Point delta) {
+        rect.x += delta.x;
+        rect.y += delta.y;
+    }
+
+    /**
+     * Moves each edge of the given rectangle outward by the given amount. Negative values
+     * cause the rectangle to contract. Does not allow the rectangle's width or height to be
+     * reduced below zero.
+     *
+     * @param rect normalized rectangle to modify
+     * @param differenceRect difference rectangle to be added to rect
+     * @since 3.3
+     */
+    public static void expand(Rectangle rect, Rectangle differenceRect) {
+        rect.x += differenceRect.x;
+        rect.y += differenceRect.y;
+        rect.height = Math.max(0, rect.height + differenceRect.height);
+        rect.width = Math.max(0, rect.width + differenceRect.width);
+    }
+
+    /**
+     * <p>Returns a rectangle which, when added to another rectangle, will expand each side
+     * by the given number of units.</p>
+     *
+     * <p>This is commonly used to store margin sizes. For example:</p>
+     *
+     * <code><pre>
+     *     // Expands the left, right, top, and bottom
+     *     // of the given control by 10, 5, 1, and 15 units respectively
+     *
+     *     Rectangle margins = Geometry.createDifferenceRect(10,5,1,15);
+     *     Rectangle bounds = someControl.getBounds();
+     *     someControl.setBounds(Geometry.add(bounds, margins));
+     * </pre></code>
+     *
+     * @param left distance to expand the left side (negative values move the edge inward)
+     * @param right distance to expand the right side (negative values move the edge inward)
+     * @param top distance to expand the top (negative values move the edge inward)
+     * @param bottom distance to expand the bottom (negative values move the edge inward)
+     *
+     * @return a difference rectangle that, when added to another rectangle, will cause each
+     * side to expand by the given number of units
+     * @since 3.3
+     */
+    public static Rectangle createDiffRectangle(int left, int right, int top, int bottom) {
+        return new Rectangle(-left, -top, left + right, top + bottom);
+    }
+
+    /**
+     * Moves each edge of the given rectangle outward by the given amount. Negative values
+     * cause the rectangle to contract. Does not allow the rectangle's width or height to be
+     * reduced below zero.
+     *
+     * @param rect normalized rectangle to modify
+     * @param left distance to move the left edge outward (negative values move the edge inward)
+     * @param right distance to move the right edge outward (negative values move the edge inward)
+     * @param top distance to move the top edge outward (negative values move the edge inward)
+     * @param bottom distance to move the bottom edge outward (negative values move the edge inward)
+     * @since 3.1
+     */
+    public static void expand(Rectangle rect, int left, int right, int top, int bottom) {
+        rect.x -= left;
+        rect.width = Math.max(0, rect.width + left + right);
+        rect.y -= top;
+        rect.height = Math.max(0, rect.height + top + bottom);
+    }
+
+    /**
+     * Normalizes the given rectangle. That is, any rectangle with
+     * negative width or height becomes a rectangle with positive
+     * width or height that extends to the upper-left of the original
+     * rectangle.
+     *
+     * @param rect rectangle to modify
+     * @since 3.0
+     */
+    public static void normalize(Rectangle rect) {
+        if (rect.width < 0) {
+            rect.width = -rect.width;
+            rect.x -= rect.width;
+        }
+
+        if (rect.height < 0) {
+            rect.height = -rect.height;
+            rect.y -= rect.height;
+        }
+    }
+
+    /**
+     * Converts the given rectangle from display coordinates to the local coordinate system
+     * of the given object into display coordinates.
+     *
+     * @param coordinateSystem local coordinate system being converted to
+     * @param toConvert rectangle to convert
+     * @return a rectangle in control coordinates
+     * @since 3.0
+     */
+    public static Rectangle toControl(Control coordinateSystem,
+            Rectangle toConvert) {
+        return(coordinateSystem.getDisplay().map
+                (null,coordinateSystem,toConvert));
+    }
+
+    /**
+     * Converts the given rectangle from the local coordinate system of the given object
+     * into display coordinates.
+     *
+     * @param coordinateSystem local coordinate system being converted from
+     * @param toConvert rectangle to convert
+     * @return a rectangle in display coordinates
+     * @since 3.0
+     */
+    public static Rectangle toDisplay(Control coordinateSystem,
+            Rectangle toConvert) {
+        return(coordinateSystem.getDisplay().map
+                (coordinateSystem,null,toConvert));
+
+    }
+
+    /**
+     * Determines where the given point lies with respect to the given rectangle.
+     * Returns a combination of DWT.LEFT, DWT.RIGHT, DWT.TOP, and DWT.BOTTOM, combined
+     * with bitwise or (for example, returns DWT.TOP | DWT.LEFT if the point is to the
+     * upper-left of the rectangle). Returns 0 if the point lies within the rectangle.
+     * Positions are in screen coordinates (ie: a point is to the upper-left of the
+     * rectangle if its x and y coordinates are smaller than any point in the rectangle)
+     *
+     * @param boundary normalized boundary rectangle
+     * @param toTest point whose relative position to the rectangle is being computed
+     * @return one of DWT.LEFT | DWT.TOP, DWT.TOP, DWT.RIGHT | DWT.TOP, DWT.LEFT, 0,
+     * DWT.RIGHT, DWT.LEFT | DWT.BOTTOM, DWT.BOTTOM, DWT.RIGHT | DWT.BOTTOM
+     * @since 3.0
+     */
+    public static int getRelativePosition(Rectangle boundary, Point toTest) {
+        int result = 0;
+
+        if (toTest.x < boundary.x) {
+            result |= DWT.LEFT;
+        } else if (toTest.x >= boundary.x + boundary.width) {
+            result |= DWT.RIGHT;
+        }
+
+        if (toTest.y < boundary.y) {
+            result |= DWT.TOP;
+        } else if (toTest.y >= boundary.y + boundary.height) {
+            result |= DWT.BOTTOM;
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns the distance from the point to the nearest edge of the given
+     * rectangle. Returns negative values if the point lies outside the rectangle.
+     *
+     * @param boundary rectangle to test
+     * @param toTest point to test
+     * @return the distance between the given point and the nearest edge of the rectangle.
+     * Returns positive values for points inside the rectangle and negative values for points
+     * outside the rectangle.
+     * @since 3.1
+     */
+    public static int getDistanceFrom(Rectangle boundary, Point toTest) {
+        int side = getClosestSide(boundary, toTest);
+        return getDistanceFromEdge(boundary, toTest, side);
+    }
+
+    /**
+     * Returns the edge of the given rectangle is closest to the given
+     * point.
+     *
+     * @param boundary rectangle to test
+     * @param toTest point to compare
+     * @return one of DWT.LEFT, DWT.RIGHT, DWT.TOP, or DWT.BOTTOM
+     *
+     * @since 3.0
+     */
+    public static int getClosestSide(Rectangle boundary, Point toTest) {
+        int[] sides = [ DWT.LEFT, DWT.RIGHT, DWT.TOP, DWT.BOTTOM ];
+
+        int closestSide = DWT.LEFT;
+        int closestDistance = Integer.MAX_VALUE;
+
+        for (int idx = 0; idx < sides.length; idx++) {
+            int side = sides[idx];
+
+            int distance = getDistanceFromEdge(boundary, toTest, side);
+
+            if (distance < closestDistance) {
+                closestDistance = distance;
+                closestSide = side;
+            }
+        }
+
+        return closestSide;
+    }
+
+    /**
+     * Returns a copy of the given rectangle
+     *
+     * @param toCopy rectangle to copy
+     * @return a copy of the given rectangle
+     * @since 3.0
+     */
+    public static Rectangle copy(Rectangle toCopy) {
+        return new Rectangle(toCopy.x, toCopy.y, toCopy.width, toCopy.height);
+    }
+
+    /**
+     * Returns the size of the rectangle, as a Point
+     *
+     * @param rectangle rectangle whose size is being computed
+     * @return the size of the given rectangle
+     * @since 3.0
+     */
+    public static Point getSize(Rectangle rectangle) {
+        return new Point(rectangle.width, rectangle.height);
+    }
+
+    /**
+     * Sets the size of the given rectangle to the given size
+     *
+     * @param rectangle rectangle to modify
+     * @param newSize new size of the rectangle
+     * @since 3.0
+     */
+    public static void setSize(Rectangle rectangle, Point newSize) {
+        rectangle.width = newSize.x;
+        rectangle.height = newSize.y;
+    }
+
+    /**
+     * Sets the x,y position of the given rectangle. For a normalized
+     * rectangle (a rectangle with positive width and height), this will
+     * be the upper-left corner of the rectangle.
+     *
+     * @param rectangle rectangle to modify
+     * @param newSize new size of the rectangle
+     *
+     * @since 3.0
+     */
+    public static void setLocation(Rectangle rectangle, Point newSize) {
+        rectangle.width = newSize.x;
+        rectangle.height = newSize.y;
+    }
+
+    /**
+     * Returns the x,y position of the given rectangle. For normalized rectangles
+     * (rectangles with positive width and height), this is the upper-left
+     * corner of the rectangle.
+     *
+     * @param toQuery rectangle to query
+     * @return a Point containing the x,y position of the rectangle
+     *
+     * @since 3.0
+     */
+    public static Point getLocation(Rectangle toQuery) {
+        return new Point(toQuery.x, toQuery.y);
+    }
+
+    /**
+     * Returns a new rectangle with the given position and dimensions, expressed
+     * as points.
+     *
+     * @param position the (x,y) position of the rectangle
+     * @param size the size of the new rectangle, where (x,y) -> (width, height)
+     * @return a new Rectangle with the given position and size
+     *
+     * @since 3.0
+     */
+    public static Rectangle createRectangle(Point position, Point size) {
+        return new Rectangle(position.x, position.y, size.x, size.y);
+    }
+
+    /**
+     * Repositions the 'inner' rectangle to lie completely within the bounds of the 'outer'
+     * rectangle if possible. One use for this is to ensure that, when setting a control's bounds,
+     * that they will always lie within its parent's client area (to avoid clipping).
+     *
+     * @param inner The 'inner' rectangle to be repositioned (should be smaller than the 'outer' rectangle)
+     * @param outer The 'outer' rectangle
+     */
+    public static void moveInside(Rectangle inner, Rectangle outer) {
+        // adjust X
+        if (inner.x < outer.x) {
+            inner.x = outer.x;
+        }
+        if ((inner.x + inner.width) > (outer.x + outer.width)) {
+            inner.x -= (inner.x + inner.width) - (outer.x + outer.width);
+        }
+
+        // Adjust Y
+        if (inner.y < outer.y) {
+            inner.y = outer.y;
+        }
+        if ((inner.y + inner.height) > (outer.y + outer.height)) {
+            inner.y -= (inner.y + inner.height) - (outer.y + outer.height);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/util/ILogger.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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:
+ *     Chris Gross (schtoo@schtoo.com) - initial API and implementation
+ *       (bug 49497 [RCP] JFace dependency on dwtx.core.runtime enlarges standalone JFace applications)
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+module dwtx.jface.util.ILogger;
+
+import dwtx.core.runtime.IStatus;
+
+/**
+ * A mechanism to log errors throughout JFace.
+ * <p>
+ * Clients may provide their own implementation to change
+ * how errors are logged from within JFace.
+ * </p>
+ *
+ * @see dwtx.jface.util.Policy#getLog()
+ * @see dwtx.jface.util.Policy#setLog(ILogger)
+ * @since 3.1
+ */
+public interface ILogger {
+
+    /**
+     * Logs the given status.
+     *
+     * @param status the status to log
+     */
+    public void log(IStatus status);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/util/IOpenEventListener.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.util.IOpenEventListener;
+
+import dwt.events.SelectionEvent;
+
+/**
+ * Listener for open events which are generated on selection
+ * of default selection depending on the user preferences.
+ *
+ * <p>
+ * Usage:
+ * <pre>
+ *  OpenStrategy handler = new OpenStrategy(control);
+ *  handler.addOpenListener(new IOpenEventListener() {
+ *      public void handleOpen(SelectionEvent e) {
+ *          ... // code to handle the open event.
+ *      }
+ *  });
+ * </pre>
+ * </p>
+ *
+ * @see OpenStrategy
+ */
+public interface IOpenEventListener {
+    /**
+     * Called when a selection or default selection occurs
+     * depending on the user preference.
+     * @param e the selection event
+     */
+    public void handleOpen(SelectionEvent e);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/util/IPropertyChangeListener.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.util.IPropertyChangeListener;
+
+import dwtx.jface.util.PropertyChangeEvent;
+
+import dwt.dwthelper.utils;
+
+/**
+ * Listener for property changes.
+ * <p>
+ * Usage:
+ * <pre>
+ * IPropertyChangeListener listener =
+ *   new IPropertyChangeListener() {
+ *      public void propertyChange(PropertyChangeEvent event) {
+ *         ... // code to deal with occurrence of property change
+ *      }
+ *   };
+ * emitter.addPropertyChangeListener(listener);
+ * ...
+ * emitter.removePropertyChangeListener(listener);
+ * </pre>
+ * </p>
+ */
+public interface IPropertyChangeListener : EventListener {
+    /**
+     * Notification that a property has changed.
+     * <p>
+     * This method gets called when the observed object fires a property
+     * change event.
+     * </p>
+     *
+     * @param event the property change event object describing which property
+     * changed and how
+     */
+    public void propertyChange(PropertyChangeEvent event);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/util/ISafeRunnableRunner.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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:
+ *     Chris Gross (schtoo@schtoo.com) - initial API and implementation
+ *       (bug 49497 [RCP] JFace dependency on dwtx.core.runtime enlarges standalone JFace applications)
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+module dwtx.jface.util.ISafeRunnableRunner;
+
+import dwtx.core.runtime.ISafeRunnable;
+
+/**
+ * Runs a safe runnables.
+ * <p>
+ * Clients may provide their own implementation to change
+ * how safe runnables are run from within JFace.
+ * </p>
+ *
+ * @see SafeRunnable#getRunner()
+ * @see SafeRunnable#setRunner(ISafeRunnableRunner)
+ * @see SafeRunnable#run(ISafeRunnable)
+ * @since 3.1
+ */
+public interface ISafeRunnableRunner {
+
+    /**
+     * Runs the runnable.  All <code>ISafeRunnableRunners</code> must catch any exception
+     * thrown by the <code>ISafeRunnable</code> and pass the exception to
+     * <code>ISafeRunnable.handleException()</code>.
+     * @param code the code executed as a save runnable
+     *
+     * @see SafeRunnable#run(ISafeRunnable)
+     */
+    public abstract void run(ISafeRunnable code);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/util/ListenerList.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.util.ListenerList;
+
+static import dwtx.core.runtime.ListenerList;
+
+import dwt.dwthelper.utils;
+
+/**
+ * This class is used to maintain a list of listeners, and is used in the
+ * implementations of several classes within JFace which allow you to register
+ * listeners of various kinds. It is a fairly lightweight object, occupying
+ * minimal space when no listeners are registered.
+ * <p>
+ * Note that the <code>add</code> method checks for and eliminates duplicates
+ * based on identity (not equality). Likewise, the <code>remove</code> method
+ * compares based on identity.
+ * </p>
+ * <p>
+ * Use the <code>getListeners</code> method when notifying listeners. Note
+ * that no garbage is created if no listeners are registered. The recommended
+ * code sequence for notifying all registered listeners of say,
+ * <code>FooListener.eventHappened</code>, is:
+ *
+ * <pre>
+ * Object[] listeners = myListenerList.getListeners();
+ * for (int i = 0; i &lt; listeners.length; ++i) {
+ *  ((FooListener) listeners[i]).eventHappened(event);
+ * }
+ * </pre>
+ *
+ * </p>
+ *
+ * @deprecated Please use {@link dwtx.core.runtime.ListenerList} instead.
+ *             Please note that the {@link #ListenerList(int)} and
+ *             {@link dwtx.core.runtime.ListenerList#ListenerList(int)}
+ *             constructors have different semantics. Please read the javadoc
+ *             carefully. Also note that the equivalent of
+ *             {@link #ListenerList()} is actually
+ *             {@link dwtx.core.runtime.ListenerList#ListenerList(int)}
+ *             with {@link dwtx.core.runtime.ListenerList#IDENTITY} as
+ *             the argument.
+ */
+public class ListenerList : dwtx.core.runtime.ListenerList.ListenerList {
+
+    /**
+     * Creates a listener list with an initial capacity of 1.
+     */
+    public this() {
+        super(IDENTITY);
+    }
+
+    /**
+     * Creates a listener list with the given initial capacity.
+     *
+     * @param capacity
+     *            the number of listeners which this list can initially accept
+     *            without growing its internal representation; must be at least
+     *            1
+     */
+    public this(int capacity) {
+        // the runtime ListenerList does not support capacity
+        this();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/util/OpenStrategy.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,495 @@
+/*******************************************************************************
+ * 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.util.OpenStrategy;
+
+import dwtx.jface.util.IOpenEventListener;
+
+import dwt.DWT;
+import dwt.custom.TableTree;
+import dwt.custom.TableTreeItem;
+import dwt.events.SelectionEvent;
+import dwt.events.SelectionListener;
+import dwt.graphics.Point;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Event;
+import dwt.widgets.Listener;
+import dwt.widgets.Table;
+import dwt.widgets.TableItem;
+import dwt.widgets.Tree;
+import dwt.widgets.TreeItem;
+import dwt.widgets.Widget;
+import dwtx.core.runtime.ListenerList;
+
+import dwt.dwthelper.utils;
+import dwt.dwthelper.Runnable;
+
+/**
+ * Implementation of single-click and double-click strategies.
+ * <p>
+ * Usage:
+ * <pre>
+ *  OpenStrategy handler = new OpenStrategy(control);
+ *  handler.addOpenListener(new IOpenEventListener() {
+ *      public void handleOpen(SelectionEvent e) {
+ *          ... // code to handle the open event.
+ *      }
+ *  });
+ * </pre>
+ * </p>
+ */
+public class OpenStrategy {
+    /**
+     * Default behavior. Double click to open the item.
+     */
+    public static const int DOUBLE_CLICK = 0;
+
+    /**
+     * Single click will open the item.
+     */
+    public static const int SINGLE_CLICK = 1;
+
+    /**
+     * Hover will select the item.
+     */
+    public static const int SELECT_ON_HOVER = 1 << 1;
+
+    /**
+     * Open item when using arrow keys
+     */
+    public static const int ARROW_KEYS_OPEN = 1 << 2;
+
+    /** A single click will generate
+     * an open event but key arrows will not do anything.
+     *
+     * @deprecated
+     */
+    public static const int NO_TIMER = SINGLE_CLICK;
+
+    /** A single click will generate an open
+     * event and key arrows will generate an open event after a
+     * small time.
+     *
+     * @deprecated
+     */
+    public static const int FILE_EXPLORER = SINGLE_CLICK | ARROW_KEYS_OPEN;
+
+    /** Pointing to an item will change the selection
+     * and a single click will gererate an open event
+     *
+     * @deprecated
+     */
+    public static const int ACTIVE_DESKTOP = SINGLE_CLICK | SELECT_ON_HOVER;
+
+    // Time used in FILE_EXPLORER and ACTIVE_DESKTOP
+    private static const int TIME = 500;
+
+    /* SINGLE_CLICK or DOUBLE_CLICK;
+     * In case of SINGLE_CLICK, the bits SELECT_ON_HOVER and ARROW_KEYS_OPEN
+     * my be set as well. */
+    private static int CURRENT_METHOD = DOUBLE_CLICK;
+
+    private Listener eventHandler;
+
+    private ListenerList openEventListeners;
+
+    private ListenerList selectionEventListeners;
+
+    private ListenerList postSelectionEventListeners;
+
+    /**
+     * @param control the control the strategy is applied to
+     */
+    public this(Control control) {
+        openEventListeners = new ListenerList();
+        selectionEventListeners = new ListenerList();
+        postSelectionEventListeners = new ListenerList();
+        initializeHandler(control.getDisplay());
+        addListener(control);
+    }
+
+    /**
+     * Adds an IOpenEventListener to the collection of openEventListeners
+     * @param listener the listener to add
+     */
+    public void addOpenListener(IOpenEventListener listener) {
+        openEventListeners.add(cast(Object)listener);
+    }
+
+    /**
+     * Removes an IOpenEventListener to the collection of openEventListeners
+     * @param listener the listener to remove
+     */
+    public void removeOpenListener(IOpenEventListener listener) {
+        openEventListeners.remove(cast(Object)listener);
+    }
+
+    /**
+     * Adds an SelectionListener to the collection of selectionEventListeners
+     * @param listener the listener to add
+     */
+    public void addSelectionListener(SelectionListener listener) {
+        selectionEventListeners.add(cast(Object)listener);
+    }
+
+    /**
+     * Removes an SelectionListener to the collection of selectionEventListeners
+     * @param listener the listener to remove
+     */
+    public void removeSelectionListener(SelectionListener listener) {
+        selectionEventListeners.remove(cast(Object)listener);
+    }
+
+    /**
+     * Adds an SelectionListener to the collection of selectionEventListeners
+     * @param listener the listener to add
+     */
+    public void addPostSelectionListener(SelectionListener listener) {
+        postSelectionEventListeners.add(cast(Object)listener);
+    }
+
+    /**
+     * Removes an SelectionListener to the collection of selectionEventListeners
+     * @param listener the listener to remove
+     */
+    public void removePostSelectionListener(SelectionListener listener) {
+        postSelectionEventListeners.remove(cast(Object)listener);
+    }
+
+    /**
+     * This method is internal to the framework; it should not be implemented outside
+     * the framework.
+     * @return the current used single/double-click method
+     *
+     */
+    public static int getOpenMethod() {
+        return CURRENT_METHOD;
+    }
+
+    /**
+     * Set the current used single/double-click method.
+     *
+     * This method is internal to the framework; it should not be implemented outside
+     * the framework.
+     * @param method the method to be used
+     * @see OpenStrategy#DOUBLE_CLICK
+     * @see OpenStrategy#SINGLE_CLICK
+     * @see OpenStrategy#SELECT_ON_HOVER
+     * @see OpenStrategy#ARROW_KEYS_OPEN
+     */
+    public static void setOpenMethod(int method) {
+        if (method is DOUBLE_CLICK) {
+            CURRENT_METHOD = method;
+            return;
+        }
+        if ((method & SINGLE_CLICK) is 0) {
+            throw new IllegalArgumentException("Invalid open mode"); //$NON-NLS-1$
+        }
+        if ((method & (SINGLE_CLICK | SELECT_ON_HOVER | ARROW_KEYS_OPEN)) is 0) {
+            throw new IllegalArgumentException("Invalid open mode"); //$NON-NLS-1$
+        }
+        CURRENT_METHOD = method;
+    }
+
+    /**
+     * @return true if editors should be activated when opened.
+     */
+    public static bool activateOnOpen() {
+        return getOpenMethod() is DOUBLE_CLICK;
+    }
+
+    /*
+     * Adds all needed listener to the control in order to implement
+     * single-click/double-click strategies.
+     */
+    private void addListener(Control c) {
+        c.addListener(DWT.MouseEnter, eventHandler);
+        c.addListener(DWT.MouseExit, eventHandler);
+        c.addListener(DWT.MouseMove, eventHandler);
+        c.addListener(DWT.MouseDown, eventHandler);
+        c.addListener(DWT.MouseUp, eventHandler);
+        c.addListener(DWT.KeyDown, eventHandler);
+        c.addListener(DWT.Selection, eventHandler);
+        c.addListener(DWT.DefaultSelection, eventHandler);
+        c.addListener(DWT.Collapse, eventHandler);
+        c.addListener(DWT.Expand, eventHandler);
+    }
+
+    /*
+     * Fire the selection event to all selectionEventListeners
+     */
+    private void fireSelectionEvent(SelectionEvent e) {
+        if (e.item !is null && e.item.isDisposed()) {
+            return;
+        }
+        Object l[] = selectionEventListeners.getListeners();
+        for (int i = 0; i < l.length; i++) {
+            (cast(SelectionListener) l[i]).widgetSelected(e);
+        }
+    }
+
+    /*
+     * Fire the default selection event to all selectionEventListeners
+     */
+    private void fireDefaultSelectionEvent(SelectionEvent e) {
+        Object l[] = selectionEventListeners.getListeners();
+        for (int i = 0; i < l.length; i++) {
+            (cast(SelectionListener) l[i]).widgetDefaultSelected(e);
+        }
+    }
+
+    /*
+     * Fire the post selection event to all postSelectionEventListeners
+     */
+    private void firePostSelectionEvent(SelectionEvent e) {
+        if (e.item !is null && e.item.isDisposed()) {
+            return;
+        }
+        Object l[] = postSelectionEventListeners.getListeners();
+        for (int i = 0; i < l.length; i++) {
+            (cast(SelectionListener) l[i]).widgetSelected(e);
+        }
+    }
+
+    /*
+     * Fire the open event to all openEventListeners
+     */
+    private void fireOpenEvent(SelectionEvent e) {
+        if (e.item !is null && e.item.isDisposed()) {
+            return;
+        }
+        Object l[] = openEventListeners.getListeners();
+        for (int i = 0; i < l.length; i++) {
+            (cast(IOpenEventListener) l[i]).handleOpen(e);
+        }
+    }
+
+    //Initialize event handler.
+    private void initializeHandler( Display display_) {
+        eventHandler = new class() Listener {
+            Display display;
+            bool timerStarted = false;
+
+            Event mouseUpEvent = null;
+
+            Event mouseMoveEvent = null;
+
+            SelectionEvent selectionPendent = null;
+
+            bool enterKeyDown = false;
+
+            SelectionEvent defaultSelectionPendent = null;
+
+            bool arrowKeyDown = false;
+
+            int[] count;
+
+            long startTime;
+
+            bool collapseOccurred = false;
+
+            bool expandOccurred = false;
+
+            this(){
+                display = display_;
+                startTime = System.currentTimeMillis();
+                count = new int[1];
+            }
+
+            public void handleEvent( Event e) {
+                if (e.type is DWT.DefaultSelection) {
+                    SelectionEvent event = new SelectionEvent(e);
+                    fireDefaultSelectionEvent(event);
+                    if (CURRENT_METHOD is DOUBLE_CLICK) {
+                        fireOpenEvent(event);
+                    } else {
+                        if (enterKeyDown) {
+                            fireOpenEvent(event);
+                            enterKeyDown = false;
+                            defaultSelectionPendent = null;
+                        } else {
+                            defaultSelectionPendent = event;
+                        }
+                    }
+                    return;
+                }
+
+                switch (e.type) {
+                case DWT.MouseEnter:
+                case DWT.MouseExit:
+                    mouseUpEvent = null;
+                    mouseMoveEvent = null;
+                    selectionPendent = null;
+                    break;
+                case DWT.MouseMove:
+                    if ((CURRENT_METHOD & SELECT_ON_HOVER) is 0) {
+                        return;
+                    }
+                    if (e.stateMask !is 0) {
+                        return;
+                    }
+                    if (e.widget.getDisplay().getFocusControl() !is e.widget) {
+                        return;
+                    }
+                    mouseMoveEvent = e;
+                    Runnable runnable = new class() Runnable {
+                        public void run() {
+                            long time = System.currentTimeMillis();
+                            int diff = cast(int) (time - startTime);
+                            if (diff <= TIME) {
+                                display.timerExec(diff * 2 / 3, this );
+                            } else {
+                                timerStarted = false;
+                                setSelection(mouseMoveEvent);
+                            }
+                        }
+                    };
+                    startTime = System.currentTimeMillis();
+                    if (!timerStarted) {
+                        timerStarted = true;
+                        display.timerExec(TIME * 2 / 3, runnable );
+                    }
+                    break;
+                case DWT.MouseDown:
+                    mouseUpEvent = null;
+                    arrowKeyDown = false;
+                    break;
+                case DWT.Expand:
+                    expandOccurred = true;
+                    break;
+                case DWT.Collapse:
+                    collapseOccurred = true;
+                    break;
+                case DWT.MouseUp:
+                    mouseMoveEvent = null;
+                    if ((e.button !is 1) || ((e.stateMask & ~DWT.BUTTON1) !is 0)) {
+                        return;
+                    }
+                    if (selectionPendent !is null
+                            && !(collapseOccurred || expandOccurred)) {
+                        mouseSelectItem(selectionPendent);
+                    } else {
+                        mouseUpEvent = e;
+                        collapseOccurred = false;
+                        expandOccurred = false;
+                    }
+                    break;
+                case DWT.KeyDown:
+                    mouseMoveEvent = null;
+                    mouseUpEvent = null;
+                    arrowKeyDown = ((e.keyCode is DWT.ARROW_UP) || (e.keyCode is DWT.ARROW_DOWN))
+                            && e.stateMask is 0;
+                    if (e.character is DWT.CR) {
+                        if (defaultSelectionPendent !is null) {
+                            fireOpenEvent(new SelectionEvent(e));
+                            enterKeyDown = false;
+                            defaultSelectionPendent = null;
+                        } else {
+                            enterKeyDown = true;
+                        }
+                    }
+                    break;
+                case DWT.Selection:
+                    SelectionEvent event = new SelectionEvent(e);
+                    fireSelectionEvent(event);
+                    mouseMoveEvent = null;
+                    if (mouseUpEvent !is null) {
+                        mouseSelectItem(event);
+                    } else {
+                        selectionPendent = event;
+                    }
+                    count[0]++;
+                    // In the case of arrowUp/arrowDown when in the arrowKeysOpen mode, we
+                    // want to delay any selection until the last arrowDown/Up occurs.  This
+                    // handles the case where the user presses arrowDown/Up successively.
+                    // We only want to open an editor for the last selected item.
+                    display.asyncExec(new class() Runnable {
+                        int id;
+                        Event e2;
+                        this(){ id = count[0]; e2 = e; }
+                        public void run() {
+                            if (arrowKeyDown) {
+                                display.timerExec(TIME, new class() Runnable {
+                                    int id2;
+                                    Event e3;
+                                    this(){ id2 = id; e3 = e2; }
+                                    public void run() {
+                                        if (id2 is count[0]) {
+                                            firePostSelectionEvent(new SelectionEvent(e3));
+                                            if ((CURRENT_METHOD & ARROW_KEYS_OPEN) !is 0) {
+                                                fireOpenEvent(new SelectionEvent(e3));
+                                            }
+                                        }
+                                    }
+                                });
+                            } else {
+                                firePostSelectionEvent(new SelectionEvent(e2));
+                            }
+                        }
+                    });
+                    break;
+                }
+            }
+
+            void mouseSelectItem(SelectionEvent e) {
+                if ((CURRENT_METHOD & SINGLE_CLICK) !is 0) {
+                    fireOpenEvent(e);
+                }
+                mouseUpEvent = null;
+                selectionPendent = null;
+            }
+
+            void setSelection(Event e) {
+                if (e is null) {
+                    return;
+                }
+                Widget w = e.widget;
+                if (w.isDisposed()) {
+                    return;
+                }
+
+                SelectionEvent selEvent = new SelectionEvent(e);
+
+                /*ISSUE: May have to create a interface with method:
+                 setSelection(Point p) so that user's custom widgets
+                 can use this class. If we keep this option. */
+                if ( auto tree = cast(Tree)w) {
+                    TreeItem item = tree.getItem(new Point(e.x, e.y));
+                    if (item !is null) {
+                        tree.setSelection([ item ]);
+                    }
+                    selEvent.item = item;
+                } else if ( auto table = cast(Table)w) {
+                    TableItem item = table.getItem(new Point(e.x, e.y));
+                    if (item !is null) {
+                        table.setSelection([ item ]);
+                    }
+                    selEvent.item = item;
+                } else if ( auto table = cast(TableTree)w) {
+                    TableTreeItem item = table.getItem(new Point(e.x, e.y));
+                    if (item !is null) {
+                        table.setSelection([ item ]);
+                    }
+                    selEvent.item = item;
+                } else {
+                    return;
+                }
+                if (selEvent.item is null) {
+                    return;
+                }
+                fireSelectionEvent(selEvent);
+                firePostSelectionEvent(selEvent);
+            }
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/util/Policy.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ *     Chris Gross (schtoo@schtoo.com) - support for ILogger added
+ *       (bug 49497 [RCP] JFace dependency on dwtx.core.runtime enlarges standalone JFace applications)
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.util.Policy;
+
+static import dwtx.core.runtime.Assert;
+import dwtx.core.runtime.IStatus;
+import dwtx.jface.dialogs.AnimatorFactory;
+import dwtx.jface.dialogs.ErrorSupportProvider;
+
+import dwtx.jface.util.ILogger;
+
+import dwt.dwthelper.utils;
+import tango.io.Stdout;
+
+/**
+ * The Policy class handles settings for behaviour, debug flags and logging
+ * within JFace.
+ *
+ * @since 3.0
+ */
+public class Policy {
+
+    /**
+     * Constant for the the default setting for debug options.
+     */
+    public static const bool DEFAULT = false;
+
+    /**
+     * The unique identifier of the JFace plug-in.
+     */
+    public static const String JFACE = "dwtx.jface";//$NON-NLS-1$
+
+    private static ILogger log;
+
+    private static Comparator viewerComparator;
+
+    private static AnimatorFactory animatorFactory;
+
+    /**
+     * A flag to indicate whether unparented dialogs should be checked.
+     */
+    public static bool DEBUG_DIALOG_NO_PARENT = DEFAULT;
+
+    /**
+     * A flag to indicate whether actions are being traced.
+     */
+    public static bool TRACE_ACTIONS = DEFAULT;
+
+    /**
+     * A flag to indicate whether toolbars are being traced.
+     */
+
+    public static bool TRACE_TOOLBAR = DEFAULT;
+
+    private static ErrorSupportProvider errorSupportProvider;
+
+    /**
+     * Returns the dummy log to use if none has been set
+     */
+    private static ILogger getDummyLog() {
+        return new class ILogger {
+            public void log(IStatus status) {
+                Stderr.formatln(status.getMessage());
+                if (status.getException() !is null) {
+                    auto e = status.getException();
+                    Stderr( "Exception in {}({}): {}", e.file, e.line, e.msg );
+                    foreach( msg; e.info ){
+                        Stderr( "    trc: {}", msg );
+                    }
+//                     status.getException().printStackTrace();
+                }
+            }
+        };
+    }
+
+    /**
+     * Sets the logger used by JFace to log errors.
+     *
+     * @param logger
+     *            the logger to use, or <code>null</code> to use the default
+     *            logger
+     * @since 3.1
+     */
+    public static void setLog(ILogger logger) {
+        log = logger;
+    }
+
+    /**
+     * Returns the logger used by JFace to log errors.
+     * <p>
+     * The default logger prints the status to <code>System.err</code>.
+     * </p>
+     *
+     * @return the logger
+     * @since 3.1
+     */
+    public static ILogger getLog() {
+        if (log is null) {
+            log = getDummyLog();
+        }
+        return log;
+    }
+
+    /**
+     * Return the default comparator used by JFace to sort strings.
+     *
+     * @return a default comparator used by JFace to sort strings
+     */
+    private static Comparator getDefaultComparator() {
+        return new class() Comparator {
+            /**
+             * Compares string s1 to string s2.
+             *
+             * @param s1
+             *            string 1
+             * @param s2
+             *            string 2
+             * @return Returns an integer value. Value is less than zero if
+             *         source is less than target, value is zero if source and
+             *         target are equal, value is greater than zero if source is
+             *         greater than target.
+             * @exception ClassCastException
+             *                the arguments cannot be cast to Strings.
+             */
+            public int compare(Object s1, Object s2) {
+                auto a = (cast(ArrayWrapperString) s1).array;
+                auto b = (cast(ArrayWrapperString) s2).array;
+                return a < b;
+            }
+        };
+    }
+
+    /**
+     * Return the comparator used by JFace to sort strings.
+     *
+     * @return the comparator used by JFace to sort strings
+     * @since 3.2
+     */
+    public static Comparator getComparator() {
+        if (viewerComparator is null) {
+            viewerComparator = getDefaultComparator();
+        }
+        return viewerComparator;
+    }
+
+    /**
+     * Sets the comparator used by JFace to sort strings.
+     *
+     * @param comparator
+     *            comparator used by JFace to sort strings
+     * @since 3.2
+     */
+    public static void setComparator(Comparator comparator) {
+        dwtx.core.runtime.Assert.Assert.isTrue(viewerComparator is null);
+        viewerComparator = comparator;
+    }
+
+    /**
+     * Sets the animator factory used by JFace to create control animator
+     * instances.
+     *
+     * @param factory
+     *            the AnimatorFactory to use.
+     * @since 3.2
+     * @deprecated this is no longer in use as of 3.3
+     */
+    public static void setAnimatorFactory(AnimatorFactory factory) {
+        animatorFactory = factory;
+    }
+
+    /**
+     * Returns the animator factory used by JFace to create control animator
+     * instances.
+     *
+     * @return the animator factory used to create control animator instances.
+     * @since 3.2
+     * @deprecated this is no longer in use as of 3.3
+     */
+    public static AnimatorFactory getAnimatorFactory() {
+        if (animatorFactory is null)
+            animatorFactory = new AnimatorFactory();
+        return animatorFactory;
+    }
+
+    /**
+     * Set the error support provider for error dialogs.
+     *
+     * @param provider
+     * @since 3.3
+     */
+    public static void setErrorSupportProvider(ErrorSupportProvider provider) {
+        errorSupportProvider = provider;
+    }
+
+    /**
+     * Return the ErrorSupportProvider for the receiver.
+     *
+     * @return ErrorSupportProvider or <code>null</code> if this has not been set
+     * @since 3.3
+     */
+    public static ErrorSupportProvider getErrorSupportProvider() {
+        return errorSupportProvider;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/util/PropertyChangeEvent.d	Fri Mar 28 17:08:33 2008 +0100
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.util.PropertyChangeEvent;
+
+import dwtx.core.runtime.Assert;
+
+import dwt.dwthelper.utils;
+
+/**
+ * An event object describing a change to a named property.
+ * <p>
+ * This concrete class was designed to be instantiated, but may
+ * also be subclassed if required.
+ * </p>
+ * <p>
+ * The JFace frameworks contain classes that report property
+ * change events for internal state changes that may be of interest
+ * to external parties. A special listener interface
+ * (<code>IPropertyChangeListener</code>) is defined for this purpose,
+ * and a typical class allow listeners to be registered via
+ * an <code>addPropertyChangeListener</code> method.
+ * </p>
+ *
+ * @see IPropertyChangeListener
+ */
+public class PropertyChangeEvent : EventObject {
+
+    /**
+     * Generated serial version UID for this class.
+     * @since 3.1
+     */
+    private static final long serialVersionUID = 3256726173533811256L;
+
+    /**
+     * The name of the changed property.
+     */
+    private String propertyName;
+
+    /**
+     * The old value of the changed property, or <code>null</code> if
+     * not known or not relevant.
+     */
+    private Object oldValue;
+
+    /**
+     * The new value of the changed property, or <code>null</code> if
+     * not known or not relevant.
+     */
+    private Object newValue;
+
+    /**
+     * Creates a new property change event.
+     *
+     * @param source the object whose property has changed
+     * @param property the property that has changed (must not be <code>null</code>)
+     * @param oldValue the old value of the property, or <code>null</code> if none
+     * @param newValue the new value of the property, or <code>null</code> if none
+     */
+    public this(Object source, String property, Object oldValue,
+            Object newValue) {
+        super(source);
+        Assert.isTrue( property.length > 0 );
+        this.propertyName = property;
+        this.oldValue = oldValue;
+        this.newValue = newValue;
+    }
+
+    /**
+     * Returns the new value of the property.
+     *
+     * @return the new value, or <code>null</code> if not known
+     *  or not relevant (for instance if the property was removed).
+     */
+    public Object getNewValue() {
+        return newValue;
+    }
+
+    /**
+     * Returns the old value of the property.
+     *
+     * @return the old value, or <code>null</code> if not known
+     *  or not relevant (for instance if the property was just
+     *  added and there was no old value).
+     */
+    public Object getOldValue() {
+        return oldValue;
+    }
+
+    /**
+     * Returns the name of the property that changed.
+     * <p>
+     * Warning: there is no guarantee that the property name returned
+     * is a constant string.  Callers must compare property names using
+     * equals, not is.
+     * </p>
+     *
+     * @return the name of the property that changed
+     */
+    public String getProperty() {
+        return propertyName;
+    }
+}