summaryrefslogtreecommitdiffstats
path: root/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse
diff options
context:
space:
mode:
authorFelipe Heidrich <fheidric>2007-01-26 23:22:25 +0000
committerFelipe Heidrich <fheidric>2007-01-26 23:22:25 +0000
commit9e9b7c1991c514a5ce2c57186a01ce1662a5d135 (patch)
tree179f650722e43e9fd1203f4f731a66100cb23892 /bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse
parent0eb9e7eb3f7485c8e21fed125fc140c8cd0774a2 (diff)
downloadeclipse.platform.swt-9e9b7c1991c514a5ce2c57186a01ce1662a5d135.tar.gz
eclipse.platform.swt-9e9b7c1991c514a5ce2c57186a01ce1662a5d135.tar.xz
eclipse.platform.swt-9e9b7c1991c514a5ce2c57186a01ce1662a5d135.zip
*** empty log message ***
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse')
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Button.java559
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Canvas.java249
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Caret.java523
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ColorDialog.java154
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Combo.java1279
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Composite.java1063
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Control.java2977
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Decorations.java862
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/DirectoryDialog.java277
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Display.java2807
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ExpandBar.java425
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ExpandItem.java391
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/FileDialog.java316
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/FontDialog.java286
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Group.java232
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Label.java284
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Link.java455
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/List.java1162
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Menu.java872
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/MenuItem.java727
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/MessageBox.java189
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ProgressBar.java219
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Sash.java239
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Scale.java356
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ScrollBar.java687
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Scrollable.java270
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Shell.java1206
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Slider.java490
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Spinner.java751
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TabFolder.java634
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TabItem.java361
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Table.java2314
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TableColumn.java570
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TableItem.java1087
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Text.java1353
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ToolBar.java456
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ToolItem.java820
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Tracker.java877
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Tree.java1974
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TreeColumn.java611
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TreeItem.java1304
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Widget.java1364
42 files changed, 34032 insertions, 0 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Button.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Button.java
new file mode 100644
index 0000000000..82be7332b6
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Button.java
@@ -0,0 +1,559 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.events.*;
+
+/**
+ * Instances of this class represent a selectable user interface object that
+ * issues notification when pressed and released.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>ARROW, CHECK, PUSH, RADIO, TOGGLE, FLAT</dd>
+ * <dd>UP, DOWN, LEFT, RIGHT, CENTER</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Selection</dd>
+ * </dl>
+ * <p>
+ * Note: Only one of the styles ARROW, CHECK, PUSH, RADIO, and TOGGLE
+ * may be specified.
+ * </p><p>
+ * Note: Only one of the styles LEFT, RIGHT, and CENTER may be specified.
+ * </p><p>
+ * Note: Only one of the styles UP, DOWN, LEFT, and RIGHT may be specified
+ * when the ARROW style is specified.
+ * </p><p>
+ * IMPORTANT: This class is intended to be subclassed <em>only</em>
+ * within the SWT implementation.
+ * </p>
+ */
+
+public class Button extends Control {
+ String text = "";
+ Image image;
+ int textHandle, imageHandle;
+ boolean ignoreSelection;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#ARROW
+ * @see SWT#CHECK
+ * @see SWT#PUSH
+ * @see SWT#RADIO
+ * @see SWT#TOGGLE
+ * @see SWT#FLAT
+ * @see SWT#LEFT
+ * @see SWT#RIGHT
+ * @see SWT#CENTER
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Button (Composite parent, int style) {
+ super (parent, checkStyle (style));
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the control is selected, by sending
+ * it one of the messages defined in the <code>SelectionListener</code>
+ * interface.
+ * <p>
+ * <code>widgetSelected</code> is called when the control is selected.
+ * <code>widgetDefaultSelected</code> is not called.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #removeSelectionListener
+ * @see SelectionEvent
+ */
+public void addSelectionListener (SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Selection,typedListener);
+ addListener (SWT.DefaultSelection,typedListener);
+}
+
+static int checkStyle (int style) {
+ style = checkBits (style, SWT.PUSH, SWT.ARROW, SWT.CHECK, SWT.RADIO, SWT.TOGGLE, 0);
+ if ((style & (SWT.PUSH | SWT.TOGGLE)) != 0) {
+ return checkBits (style, SWT.CENTER, SWT.LEFT, SWT.RIGHT, 0, 0, 0);
+ }
+ if ((style & (SWT.CHECK | SWT.RADIO)) != 0) {
+ return checkBits (style, SWT.LEFT, SWT.RIGHT, SWT.CENTER, 0, 0, 0);
+ }
+ if ((style & SWT.ARROW) != 0) {
+ style |= SWT.NO_FOCUS;
+ return checkBits (style, SWT.UP, SWT.DOWN, SWT.LEFT, SWT.RIGHT, 0, 0);
+ }
+ return style;
+}
+
+void createArrow () {
+ int geometry = OS.gcnew_StreamGeometry ();
+ int context = OS.StreamGeometry_Open (geometry);
+ int start = 0, point = 0, end = 0;
+ int mask = SWT.RIGHT | SWT.LEFT | SWT.DOWN | SWT.UP;
+ switch (style & mask) {
+ case SWT.RIGHT:
+ start = OS.gcnew_Point (1, 0);
+ point = OS.gcnew_Point (4, 3);
+ end = OS.gcnew_Point (1, 6);
+ break;
+ case SWT.LEFT:
+ start = OS.gcnew_Point (4, 1);
+ point = OS.gcnew_Point (1, 3);
+ end = OS.gcnew_Point (4, 6);
+ break;
+ case SWT.DOWN:
+ start = OS.gcnew_Point (0, 1);
+ point = OS.gcnew_Point (3, 4);
+ end = OS.gcnew_Point (6, 1);
+ break;
+ case SWT.UP:
+ start = OS.gcnew_Point (0, 4);
+ point = OS.gcnew_Point (3, 1);
+ end = OS.gcnew_Point (6, 4);
+ break;
+ }
+ OS.StreamGeometryContext_BeginFigure (context, start, true, true);
+ OS.StreamGeometryContext_LineTo (context, point, true, true);
+ OS.StreamGeometryContext_LineTo (context, end, true, true);
+ OS.StreamGeometryContext_Close (context);
+ int path = OS.gcnew_Path ();
+ OS.Path_Data (path, geometry);
+ int padding = OS.gcnew_Thickness (3, 3, 3, 3);
+ OS.FrameworkElement_Margin (path, padding);
+ int brush = OS.Brushes_Black ();
+ OS.Path_Fill (path, brush);
+ OS.FrameworkElement_Width (path, 6);
+ OS.FrameworkElement_Height (path, 6);
+ OS.FrameworkElement_HorizontalAlignment (path, OS.HorizontalAlignment_Center);
+ OS.FrameworkElement_VerticalAlignment (path, OS.VerticalAlignment_Center);
+ OS.ContentControl_Content (handle, path);
+ OS.GCHandle_Free (padding);
+ OS.GCHandle_Free (start);
+ OS.GCHandle_Free (point);
+ OS.GCHandle_Free (end);
+ OS.GCHandle_Free (brush);
+ OS.GCHandle_Free (path);
+ OS.GCHandle_Free (context);
+ OS.GCHandle_Free (geometry);
+}
+
+void createHandle () {
+ if ((style & SWT.PUSH) == 0) state |= THEME_BACKGROUND;
+ int bits = SWT.TOGGLE | SWT.ARROW | SWT.PUSH | SWT.RADIO | SWT.CHECK;
+ switch (style & bits) {
+ case SWT.TOGGLE:
+ handle = OS.gcnew_ToggleButton ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ break;
+ case SWT.ARROW:
+ handle = OS.gcnew_Button ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ createArrow ();
+ break;
+ case SWT.RADIO:
+ handle = OS.gcnew_RadioButton ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ break;
+ case SWT.CHECK:
+ handle = OS.gcnew_CheckBox ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ break;
+ case SWT.PUSH:
+ default:
+ handle = OS.gcnew_Button ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ break;
+ }
+ if ((style & SWT.ARROW) != 0) return;
+ int value = OS.HorizontalAlignment_Left;
+ if ((style & SWT.CENTER) != 0) value = OS.HorizontalAlignment_Center;
+ if ((style & SWT.RIGHT) != 0) value = OS.HorizontalAlignment_Right;
+ OS.Control_HorizontalContentAlignment (handle, value);
+ imageHandle = OS.gcnew_Image ();
+ if (imageHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.Image_Stretch (imageHandle, OS.Stretch_None);
+ OS.UIElement_Visibility (imageHandle, OS.Visibility_Collapsed);
+ textHandle = OS.gcnew_AccessText ();
+ if (textHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.FrameworkElement_VerticalAlignment (textHandle, OS.VerticalAlignment_Center);
+ int panel = OS.gcnew_StackPanel ();
+ if (panel == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.StackPanel_Orientation (panel, OS.Orientation_Horizontal);
+ int thickness = OS.gcnew_Thickness (1, 1, 1, 1);
+ if (thickness == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.FrameworkElement_Margin (panel, thickness);
+ OS.GCHandle_Free(thickness);
+ int children = OS.Panel_Children (panel);
+ OS.UIElementCollection_Add (children, imageHandle);
+ OS.UIElementCollection_Add (children, textHandle);
+ OS.ContentControl_Content (handle, panel);
+ OS.GCHandle_Free (children);
+ OS.GCHandle_Free (panel);
+}
+
+int defaultBackground () {
+ if ((style & SWT.PUSH) == 0) return OS.SystemColors_ControlColor;
+ return 0;
+}
+
+/**
+ * Returns a value which describes the position of the
+ * text or image in the receiver. The value will be one of
+ * <code>LEFT</code>, <code>RIGHT</code> or <code>CENTER</code>
+ * unless the receiver is an <code>ARROW</code> button, in
+ * which case, the alignment will indicate the direction of
+ * the arrow (one of <code>LEFT</code>, <code>RIGHT</code>,
+ * <code>UP</code> or <code>DOWN</code>).
+ *
+ * @return the alignment
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getAlignment () {
+ checkWidget ();
+ if ((style & SWT.ARROW) != 0) {
+ if ((style & SWT.UP) != 0) return SWT.UP;
+ if ((style & SWT.DOWN) != 0) return SWT.DOWN;
+ if ((style & SWT.LEFT) != 0) return SWT.LEFT;
+ if ((style & SWT.RIGHT) != 0) return SWT.RIGHT;
+ return SWT.UP;
+ }
+ if ((style & SWT.LEFT) != 0) return SWT.LEFT;
+ if ((style & SWT.CENTER) != 0) return SWT.CENTER;
+ if ((style & SWT.RIGHT) != 0) return SWT.RIGHT;
+ return SWT.LEFT;
+}
+
+/**
+ * Returns the receiver's image if it has one, or null
+ * if it does not.
+ *
+ * @return the receiver's image
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Image getImage () {
+ checkWidget ();
+ return image;
+}
+
+String getNameText () {
+ return getText ();
+}
+
+/**
+ * Returns <code>true</code> if the receiver is selected,
+ * and false otherwise.
+ * <p>
+ * When the receiver is of type <code>CHECK</code> or <code>RADIO</code>,
+ * it is selected when it is checked. When it is of type <code>TOGGLE</code>,
+ * it is selected when it is pushed in. If the receiver is of any other type,
+ * this method returns false.
+ *
+ * @return the selection state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getSelection () {
+ checkWidget ();
+ if ((style & (SWT.CHECK | SWT.RADIO | SWT.TOGGLE)) == 0) return false;
+ return OS.ToggleButton_IsChecked (handle);
+}
+
+/**
+ * Returns the receiver's text, which will be an empty
+ * string if it has never been set or if the receiver is
+ * an <code>ARROW</code> button.
+ *
+ * @return the receiver's text
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String getText () {
+ checkWidget ();
+ if ((style & SWT.ARROW) != 0) return "";
+ return text;
+}
+
+void HandleClick (int sender, int e) {
+ if (!checkEvent (e)) return;
+ if (!ignoreSelection) postEvent (SWT.Selection);
+}
+
+void hookEvents () {
+ super.hookEvents ();
+ if ((style & (SWT.TOGGLE | SWT.RADIO | SWT.CHECK)) != 0) {
+ int handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleClick");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.ToggleButton_Checked (handle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleClick");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.ToggleButton_Unchecked (handle, handler);
+ OS.GCHandle_Free (handler);
+ } else {
+ int handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleClick");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.ButtonBase_Click (handle, handler);
+ OS.GCHandle_Free (handler);
+ }
+}
+
+boolean isTabItem () {
+ //TEMPORARY CODE
+ //if ((style & SWT.PUSH) != 0) return true;
+ return super.isTabItem ();
+}
+
+boolean mnemonicHit (char ch) {
+ //TODO
+ return false;
+}
+
+boolean mnemonicMatch (char key) {
+ return super.mnemonicMatch (textHandle, key);
+}
+
+void releaseHandle() {
+ super.releaseHandle ();
+ if (textHandle != 0) OS.GCHandle_Free (textHandle);
+ textHandle = 0;
+ if (imageHandle !=0 )OS.GCHandle_Free (imageHandle);
+ imageHandle = 0;
+}
+
+void releaseWidget () {
+ super.releaseWidget ();
+ text = null;
+ image = null;
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the control is selected.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #addSelectionListener
+ */
+public void removeSelectionListener (SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Selection, listener);
+ eventTable.unhook (SWT.DefaultSelection,listener);
+}
+
+/**
+ * Controls how text, images and arrows will be displayed
+ * in the receiver. The argument should be one of
+ * <code>LEFT</code>, <code>RIGHT</code> or <code>CENTER</code>
+ * unless the receiver is an <code>ARROW</code> button, in
+ * which case, the argument indicates the direction of
+ * the arrow (one of <code>LEFT</code>, <code>RIGHT</code>,
+ * <code>UP</code> or <code>DOWN</code>).
+ *
+ * @param alignment the new alignment
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setAlignment (int alignment) {
+ checkWidget ();
+ if ((style & SWT.ARROW) != 0) {
+ if ((style & (SWT.UP | SWT.DOWN | SWT.LEFT | SWT.RIGHT)) == 0) return;
+ style &= ~(SWT.UP | SWT.DOWN | SWT.LEFT | SWT.RIGHT);
+ style |= alignment & (SWT.UP | SWT.DOWN | SWT.LEFT | SWT.RIGHT);
+ createArrow ();
+ return;
+ }
+ if ((alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER)) == 0) return;
+ style &= ~(SWT.LEFT | SWT.RIGHT | SWT.CENTER);
+ style |= alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER);
+ int value = OS.HorizontalAlignment_Left;
+ if ((style & SWT.CENTER) != 0) value = OS.HorizontalAlignment_Center;
+ if ((style & SWT.RIGHT) != 0) value = OS.HorizontalAlignment_Right;
+ OS.Control_HorizontalContentAlignment (handle, value);
+}
+
+void setDefault (boolean value) {
+ if ((style & SWT.PUSH) == 0) return;
+ OS.Button_IsDefault (handle, value);
+}
+
+/**
+ * Sets the receiver's image to the argument, which may be
+ * <code>null</code> indicating that no image should be displayed.
+ *
+ * @param image the image to display on the receiver (may be <code>null</code>)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setImage (Image image) {
+ checkWidget ();
+ if (image != null && image.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if ((style & SWT.ARROW) != 0) return;
+ this.image = image;
+ OS.Image_Source (imageHandle, image != null ? image.handle : 0);
+ OS.UIElement_Visibility (imageHandle, image != null ? OS.Visibility_Visible : OS.Visibility_Collapsed);
+ OS.UIElement_Visibility (textHandle, image != null && text.length () == 0 ? OS.Visibility_Collapsed : OS.Visibility_Visible);
+ int spacing = image != null && text.length ()!= 0 ? 3 : 0;
+ int margin = OS.gcnew_Thickness (0, 0, spacing, 0);
+ if (margin == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.FrameworkElement_Margin (imageHandle, margin);
+ OS.GCHandle_Free (margin);
+}
+
+/**
+ * Sets the selection state of the receiver, if it is of type <code>CHECK</code>,
+ * <code>RADIO</code>, or <code>TOGGLE</code>.
+ *
+ * <p>
+ * When the receiver is of type <code>CHECK</code> or <code>RADIO</code>,
+ * it is selected when it is checked. When it is of type <code>TOGGLE</code>,
+ * it is selected when it is pushed in.
+ *
+ * @param selected the new selection state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSelection (boolean selected) {
+ checkWidget ();
+ if ((style & (SWT.CHECK | SWT.RADIO | SWT.TOGGLE)) == 0) return;
+ ignoreSelection = true;
+ OS.ToggleButton_IsChecked (handle, selected);
+ ignoreSelection = false;
+}
+
+/**
+ * Sets the receiver's text.
+ * <p>
+ * This method sets the button label. The label may include
+ * the mnemonic character but must not contain line delimiters.
+ * </p>
+ * <p>
+ * Mnemonics are indicated by an '&amp;' that causes the next
+ * character to be the mnemonic. When the user presses a
+ * key sequence that matches the mnemonic, a selection
+ * event occurs. On most platforms, the mnemonic appears
+ * underlined but may be emphasised in a platform specific
+ * manner. The mnemonic indicator character '&amp;' can be
+ * escaped by doubling it in the string, causing a single
+ * '&amp;' to be displayed.
+ * </p>
+ *
+ * @param string the new text
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setText (String string) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if ((style & SWT.ARROW) != 0) return;
+ if (string.equals (text)) return;
+ text = string;
+ int strPtr = createDotNetString (text, true);
+ if (strPtr == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.AccessText_Text (textHandle, strPtr);
+ OS.GCHandle_Free (strPtr);
+ OS.UIElement_Visibility (textHandle, string.length () == 0 && image != null ? OS.Visibility_Collapsed : OS.Visibility_Visible);
+ int spacing = image != null && text.length () != 0 ? 3 : 0;
+ int margin = OS.gcnew_Thickness (0, 0, spacing, 0);
+ if (margin == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.FrameworkElement_Margin (imageHandle, margin);
+ OS.GCHandle_Free (margin);
+}
+
+int traversalCode (int key, int event) {
+ int code = super.traversalCode (key, event);
+ if ((style & SWT.RADIO) != 0) code |= SWT.TRAVERSE_ARROW_NEXT | SWT.TRAVERSE_ARROW_PREVIOUS;
+ return code;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Canvas.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Canvas.java
new file mode 100644
index 0000000000..6e89c1492c
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Canvas.java
@@ -0,0 +1,249 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Instances of this class provide a surface for drawing
+ * arbitrary graphics.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>(none)</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * <p>
+ * This class may be subclassed by custom control implementors
+ * who are building controls that are <em>not</em> constructed
+ * from aggregates of other controls. That is, they are either
+ * painted using SWT graphics calls or are handled by native
+ * methods.
+ * </p>
+ *
+ * @see Composite
+ */
+
+public class Canvas extends Composite {
+ Caret caret;
+
+/**
+ * Prevents uninitialized instances from being created outside the package.
+ */
+Canvas () {
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * </ul>
+ *
+ * @see SWT
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Canvas (Composite parent, int style) {
+ super (parent, style);
+}
+
+void clearArea (int x, int y, int width, int height) {
+ checkWidget ();
+// if (OS.IsWindowVisible (handle)) {
+// RECT rect = new RECT ();
+// OS.SetRect (rect, x, y, x + width, y + height);
+// int hDC = OS.GetDCEx (handle, 0, OS.DCX_CACHE | OS.DCX_CLIPCHILDREN | OS.DCX_CLIPSIBLINGS);
+// drawBackground (hDC, rect);
+// OS.ReleaseDC (handle, hDC);
+// }
+}
+
+/**
+ * Returns the caret.
+ * <p>
+ * The caret for the control is automatically hidden
+ * and shown when the control is painted or resized,
+ * when focus is gained or lost and when an the control
+ * is scrolled. To avoid drawing on top of the caret,
+ * the programmer must hide and show the caret when
+ * drawing in the window any other time.
+ * </p>
+ *
+ * @return the caret
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Caret getCaret () {
+ checkWidget ();
+ return caret;
+}
+
+int getCaretHandle () {
+ if (caret != null && !caret.isDisposed()) {
+ return caret.handle;
+ }
+ return 0;
+}
+
+void releaseChildren (boolean destroy) {
+ super.releaseChildren (destroy);
+ if (caret != null) {
+ caret.release (false);
+ caret = null;
+ }
+}
+
+/**
+ * Fills the interior of the rectangle specified by the arguments,
+ * with the receiver's background.
+ *
+ * @param gc the gc where the rectangle is to be filled
+ * @param x the x coordinate of the rectangle to be filled
+ * @param y the y coordinate of the rectangle to be filled
+ * @param width the width of the rectangle to be filled
+ * @param height the height of the rectangle to be filled
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the gc is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the gc has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public void drawBackground (GC gc, int x, int y, int width, int height) {
+ checkWidget ();
+ if (gc == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (gc.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ //int pixel = background == -1 ? gc.getBackground ().handle : -1;
+ //TODO WHAT COLOR TO USE ?
+
+ gc.fillRectangle (x, y, width, height);
+// int drawingContext = gc.handle;
+// int color = getBackgroundColor ();
+// int brush = OS.gcnew_SolidColorBrush (color);
+// int rect = OS.gcnew_Rect (x, y, width, height);
+// OS.DrawingContext_DrawRectangle (drawingContext, brush, 0, rect);
+// OS.GCHandle_Free (rect);
+// OS.GCHandle_Free (brush);
+}
+
+/**
+ * Scrolls a rectangular area of the receiver by first copying
+ * the source area to the destination and then causing the area
+ * of the source which is not covered by the destination to
+ * be repainted. Children that intersect the rectangle are
+ * optionally moved during the operation. In addition, outstanding
+ * paint events are flushed before the source area is copied to
+ * ensure that the contents of the canvas are drawn correctly.
+ *
+ * @param destX the x coordinate of the destination
+ * @param destY the y coordinate of the destination
+ * @param x the x coordinate of the source
+ * @param y the y coordinate of the source
+ * @param width the width of the area
+ * @param height the height of the area
+ * @param all <code>true</code>if children should be scrolled, and <code>false</code> otherwise
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void scroll (int destX, int destY, int x, int y, int width, int height, boolean all) {
+ checkWidget ();
+// boolean isFocus = caret != null && caret.isFocusCaret ();
+// if (isFocus) caret.killFocus ();
+ //TODO
+ redraw (false);
+// if (isFocus) caret.setFocus ();
+}
+
+/**
+ * Sets the receiver's caret.
+ * <p>
+ * The caret for the control is automatically hidden
+ * and shown when the control is painted or resized,
+ * when focus is gained or lost and when an the control
+ * is scrolled. To avoid drawing on top of the caret,
+ * the programmer must hide and show the caret when
+ * drawing in the window any other time.
+ * </p>
+ * @param caret the new caret for the receiver, may be null
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the caret has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setCaret (Caret caret) {
+ checkWidget ();
+ if (caret != null && caret.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
+ int children = OS.Panel_Children (handle);
+ if (this.caret != null) {
+ OS.UIElementCollection_Remove (children, this.caret.handle);
+ }
+ this.caret = caret;
+ if (caret != null) {
+ OS.UIElementCollection_Insert (children, 0, caret.handle);
+ if (hasFocus ()) caret.show ();
+ }
+ OS.GCHandle_Free (children);
+}
+
+public void setFont (Font font) {
+ checkWidget ();
+ if (caret != null) caret.setFont (font);
+ super.setFont (font);
+}
+
+void HandlePreviewGotKeyboardFocus (int sender, int e) {
+ if (!checkEvent (e)) return;
+ super.HandlePreviewGotKeyboardFocus (sender, e);
+ if (caret != null) caret.show ();
+}
+
+void HandlePreviewLostKeyboardFocus (int sender, int e) {
+ if (!checkEvent (e)) return;
+ super.HandlePreviewLostKeyboardFocus (sender, e);
+ if (caret != null) caret.hide ();
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Caret.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Caret.java
new file mode 100644
index 0000000000..6c0f586a87
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Caret.java
@@ -0,0 +1,523 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Instances of this class provide an i-beam that is typically used
+ * as the insertion point for text.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>(none)</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * <p>
+ * IMPORTANT: This class is intended to be subclassed <em>only</em>
+ * within the SWT implementation.
+ * </p>
+ */
+
+public class Caret extends Widget {
+ Canvas parent;
+ int x, y, width, height;
+ int imageHandle;
+ boolean isVisible;
+ Image image;
+ Font font;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Caret (Canvas parent, int style) {
+ super (parent, style);
+ this.parent = parent;
+ createWidget ();
+}
+
+void createWidget () {
+ createHandle ();
+ if (parent.getCaret () == null) {
+ parent.setCaret (this);
+ }
+}
+
+void createHandle() {
+ handle = OS.gcnew_StackPanel ();
+ //handle = OS.gcnew_ContentControl ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+
+ int animation = OS.gcnew_DoubleAnimationUsingKeyFrames ();
+ if (animation == 0) error (SWT.ERROR_NO_HANDLES);
+ int timespan = OS.gcnew_TimeSpan (6000000);
+ if (timespan == 0) error (SWT.ERROR_NO_HANDLES);
+ int duration = OS.gcnew_Duration (timespan);
+ if (duration == 0) error (SWT.ERROR_NO_HANDLES);
+ int repeatBehavior = OS.RepeatBehavior_Forever();
+
+ OS.Timeline_AutoReverse(animation, true);
+ OS.Timeline_Duration(animation, duration);
+ OS.Timeline_RepeatBehavior(animation, repeatBehavior);
+ int keyFrames = OS.DoubleAnimationUsingKeyFrames_KeyFrames(animation);
+ int keyTime = OS.KeyTime_Uniform();
+ int keyFrame0 = OS.gcnew_DiscreteDoubleKeyFrame(0, keyTime);
+ int keyFrame1 = OS.gcnew_DiscreteDoubleKeyFrame(0, keyTime);
+ OS.DoubleKeyFrameCollection_Add(keyFrames, keyFrame0);
+ OS.DoubleKeyFrameCollection_Add(keyFrames, keyFrame1);
+ int opacityProperty = OS.UIElement_OpacityProperty();
+ OS.UIElement_BeginAnimation(handle, opacityProperty, animation);
+
+ int brush = OS.SystemColors_ControlTextBrush ();
+ OS.Panel_Background(handle, brush);
+
+ imageHandle = OS.gcnew_Image ();
+ if (imageHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.Image_Stretch (imageHandle, OS.Stretch_None);
+ OS.UIElement_Visibility (imageHandle, OS.Visibility_Collapsed);
+
+ int children = OS.Panel_Children (handle);
+ OS.UIElementCollection_Add (children, imageHandle);
+ OS.GCHandle_Free (children);
+ hide ();
+ OS.GCHandle_Free(brush);
+ OS.GCHandle_Free(opacityProperty);
+ OS.GCHandle_Free(keyFrames);
+ OS.GCHandle_Free(keyTime);
+ OS.GCHandle_Free(keyFrame0);
+ OS.GCHandle_Free(keyFrame1);
+ OS.GCHandle_Free(animation);
+ OS.GCHandle_Free(duration);
+ OS.GCHandle_Free(timespan);
+ OS.GCHandle_Free(repeatBehavior);
+}
+
+/**
+ * Returns a rectangle describing the receiver's size and location
+ * relative to its parent (or its display if its parent is null).
+ *
+ * @return the receiver's bounding rectangle
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Rectangle getBounds () {
+ checkWidget();
+ if (image != null) {
+ Rectangle rect = image.getBounds ();
+ return new Rectangle (x, y, rect.width, rect.height);
+ }
+ return new Rectangle (x, y, width, height);
+}
+
+/**
+ * Returns the font that the receiver will use to paint textual information.
+ *
+ * @return the receiver's font
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Font getFont () {
+ checkWidget();
+ if (font == null) {
+ return parent.display.systemFont;
+ }
+ return font;
+}
+
+/**
+ * Returns the image that the receiver will use to paint the caret.
+ *
+ * @return the receiver's image
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Image getImage () {
+ checkWidget();
+ return image;
+}
+
+/**
+ * Returns a point describing the receiver's location relative
+ * to its parent (or its display if its parent is null).
+ *
+ * @return the receiver's location
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Point getLocation () {
+ checkWidget();
+ return new Point (x, y);
+}
+
+/**
+ * Returns the receiver's parent, which must be a <code>Canvas</code>.
+ *
+ * @return the receiver's parent
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Canvas getParent () {
+ checkWidget();
+ return parent;
+}
+
+/**
+ * Returns a point describing the receiver's size.
+ *
+ * @return the receiver's size
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Point getSize () {
+ checkWidget();
+ if (image != null) {
+ Rectangle rect = image.getBounds ();
+ return new Point (rect.width, rect.height);
+ }
+ return new Point (width, height);
+}
+
+/**
+ * Returns <code>true</code> if the receiver is visible, and
+ * <code>false</code> otherwise.
+ * <p>
+ * If one of the receiver's ancestors is not visible or some
+ * other condition makes the receiver not visible, this method
+ * may still indicate that it is considered visible even though
+ * it may not actually be showing.
+ * </p>
+ *
+ * @return the receiver's visibility state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getVisible () {
+ checkWidget ();
+ return isVisible;
+}
+
+boolean hasFocus () {
+ return OS.UIElement_IsKeyboardFocused (parent.handle);
+}
+
+boolean isFocusCaret () {
+ return parent.caret == this && hasFocus ();
+}
+
+/**
+ * Returns <code>true</code> if the receiver is visible and all
+ * of the receiver's ancestors are visible and <code>false</code>
+ * otherwise.
+ *
+ * @return the receiver's visibility state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #getVisible
+ */
+public boolean isVisible () {
+ checkWidget();
+ return OS.UIElement_IsVisible (handle) && parent.isVisible () && hasFocus ();
+}
+
+void hide () {
+ OS.UIElement_Visibility (handle, OS.Visibility_Collapsed);
+}
+
+void move (int x, int y) {
+ OS.Canvas_SetLeft (handle, x);
+ OS.Canvas_SetTop (handle, y);
+}
+
+void releaseHandle() {
+ if (imageHandle != 0) OS.GCHandle_Free (imageHandle);
+ imageHandle = 0;
+ super.releaseHandle ();
+}
+
+void releaseParent () {
+ super.releaseParent ();
+ if (this == parent.getCaret ()) parent.setCaret (null);
+}
+
+void releaseWidget () {
+ super.releaseWidget ();
+ parent = null;
+ image = null;
+ font = null;
+}
+
+void resize (int width, int height) {
+ if (image != null) {
+ Rectangle rect = image.getBounds();
+ width = rect.width;
+ height = rect.height;
+ }
+ if (width == 0) width = 1;
+ OS.FrameworkElement_Width (handle, width);
+ OS.FrameworkElement_Height (handle, height);
+}
+
+/**
+ * Sets the receiver's size and location to the rectangular
+ * area specified by the arguments. The <code>x</code> and
+ * <code>y</code> arguments are relative to the receiver's
+ * parent (or its display if its parent is null).
+ *
+ * @param x the new x coordinate for the receiver
+ * @param y the new y coordinate for the receiver
+ * @param width the new width for the receiver
+ * @param height the new height for the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setBounds (int x, int y, int width, int height) {
+ checkWidget();
+ boolean samePosition = this.x == x && this.y == y;
+ boolean sameExtent = this.width == width && this.height == height;
+ if (samePosition && sameExtent) return;
+ this.x = x; this.y = y;
+ this.width = width; this.height = height;
+ if (!sameExtent) resize (width, height);
+ if (!samePosition) move (x, y);
+}
+
+/**
+ * Sets the receiver's size and location to the rectangular
+ * area specified by the argument. The <code>x</code> and
+ * <code>y</code> fields of the rectangle are relative to
+ * the receiver's parent (or its display if its parent is null).
+ *
+ * @param rect the new bounds for the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setBounds (Rectangle rect) {
+ if (rect == null) error (SWT.ERROR_NULL_ARGUMENT);
+ setBounds (rect.x, rect.y, rect.width, rect.height);
+}
+
+void show () {
+ OS.UIElement_Visibility (handle, OS.Visibility_Visible);
+}
+
+/**
+ * Sets the font that the receiver will use to paint textual information
+ * to the font specified by the argument, or to the default font for that
+ * kind of control if the argument is null.
+ *
+ * @param font the new font (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the font has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setFont (Font font) {
+ checkWidget();
+ if (font != null && font.isDisposed ()) {
+ error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+ this.font = font;
+}
+
+/**
+ * Sets the image that the receiver will use to paint the caret
+ * to the image specified by the argument, or to the default
+ * which is a filled rectangle if the argument is null
+ *
+ * @param image the new image (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setImage (Image image) {
+ checkWidget();
+ if (image != null && image.isDisposed ()) {
+ error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+ this.image = image;
+ if (image != null) {
+ OS.Image_Source (imageHandle, image.handle);
+ OS.UIElement_Visibility (imageHandle, OS.Visibility_Visible);
+ } else {
+ OS.Image_Source (imageHandle, 0);
+ OS.UIElement_Visibility (imageHandle, OS.Visibility_Collapsed);
+ }
+ resize (width, height);
+}
+
+/**
+ * Sets the receiver's location to the point specified by
+ * the arguments which are relative to the receiver's
+ * parent (or its display if its parent is null).
+ *
+ * @param x the new x coordinate for the receiver
+ * @param y the new y coordinate for the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setLocation (int x, int y) {
+ checkWidget();
+ if (this.x == x && this.y == y) return;
+ this.x = x; this.y = y;
+ move (x, y);
+}
+
+/**
+ * Sets the receiver's location to the point specified by
+ * the argument which is relative to the receiver's
+ * parent (or its display if its parent is null).
+ *
+ * @param location the new location for the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setLocation (Point location) {
+ checkWidget();
+ if (location == null) error (SWT.ERROR_NULL_ARGUMENT);
+ setLocation (location.x, location.y);
+}
+
+/**
+ * Sets the receiver's size to the point specified by the arguments.
+ *
+ * @param width the new width for the receiver
+ * @param height the new height for the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSize (int width, int height) {
+ checkWidget();
+ if (this.width == width && this.height == height) return;
+ this.width = width; this.height = height;
+ resize (width, height);
+}
+
+/**
+ * Sets the receiver's size to the point specified by the argument.
+ *
+ * @param size the new extent for the receiver
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSize (Point size) {
+ checkWidget();
+ if (size == null) error (SWT.ERROR_NULL_ARGUMENT);
+ setSize (size.x, size.y);
+}
+
+/**
+ * Marks the receiver as visible if the argument is <code>true</code>,
+ * and marks it invisible otherwise.
+ * <p>
+ * If one of the receiver's ancestors is not visible or some
+ * other condition makes the receiver not visible, marking
+ * it visible may not actually cause it to be displayed.
+ * </p>
+ *
+ * @param visible the new visibility state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setVisible (boolean visible) {
+ checkWidget();
+ if (visible == isVisible) return;
+ isVisible = visible;
+ if (!hasFocus()) return;
+ OS.UIElement_Visibility(handle, visible ? OS.Visibility_Visible : OS.Visibility_Hidden);
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ColorDialog.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ColorDialog.java
new file mode 100644
index 0000000000..75564dcb8a
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ColorDialog.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Instances of this class allow the user to select a color
+ * from a predefined set of available colors.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>(none)</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * <p>
+ * IMPORTANT: This class is intended to be subclassed <em>only</em>
+ * within the SWT implementation.
+ * </p>
+ */
+
+public class ColorDialog extends Dialog {
+ RGB rgb;
+
+/**
+ * Constructs a new instance of this class given only its parent.
+ *
+ * @param parent a composite control which will be the parent of the new instance
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public ColorDialog (Shell parent) {
+ this (parent, SWT.PRIMARY_MODAL);
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public ColorDialog (Shell parent, int style) {
+ super (parent, style);
+ checkSubclass ();
+}
+
+/**
+ * Returns the currently selected color in the receiver.
+ *
+ * @return the RGB value for the selected color, may be null
+ *
+ * @see PaletteData#getRGBs
+ */
+public RGB getRGB () {
+ return rgb;
+}
+
+/**
+ * Makes the receiver visible and brings it to the front
+ * of the display.
+ *
+ * @return the selected color, or null if the dialog was
+ * cancelled, no color was selected, or an error
+ * occurred
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public RGB open () {
+ int dialog = OS.gcnew_ColorDialog();
+ if (rgb != null) {
+ int color = OS.DrawingColor_FromArgb(174, rgb.red, rgb.blue, rgb.green);
+ OS.ColorDialog_Color(dialog, color);
+ OS.GCHandle_Free(color);
+ }
+ Display display = parent.getDisplay();
+ int customColors = display.customColors;
+ OS.ColorDialog_AnyColor(dialog, true);
+ OS.ColorDialog_CustomColors(dialog, customColors);
+ int result = OS.FormsCommonDialog_ShowDialog(dialog);
+ RGB rgb = null;
+ if (result == OS.DialogResult_OK) {
+ int color = OS.ColorDialog_Color(dialog);
+ int argb = OS.DrawingColor_ToArgb(color);
+ int red = (argb & 0xFF0000) >> 16;
+ int green = (argb & 0xFF00) >> 8;
+ int blue = argb & 0xFF;
+ OS.GCHandle_Free (color);
+ rgb = new RGB(red, green, blue);
+ if (customColors != 0) OS.GCHandle_Free(customColors);
+ display.customColors = OS.ColorDialog_CustomColors(dialog);
+ }
+ OS.GCHandle_Free(dialog);
+ return rgb;
+}
+
+/**
+ * Sets the receiver's selected color to be the argument.
+ *
+ * @param rgb the new RGB value for the selected color, may be
+ * null to let the platform select a default when
+ * open() is called
+ * @see PaletteData#getRGBs
+ */
+public void setRGB (RGB rgb) {
+ this.rgb = rgb;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Combo.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Combo.java
new file mode 100644
index 0000000000..f08e79928e
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Combo.java
@@ -0,0 +1,1279 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.internal.wpf.OS;
+
+/**
+ * Instances of this class are controls that allow the user
+ * to choose an item from a list of items, or optionally
+ * enter a new value by typing it into an editable text
+ * field. Often, <code>Combo</code>s are used in the same place
+ * where a single selection <code>List</code> widget could
+ * be used but space is limited. A <code>Combo</code> takes
+ * less space than a <code>List</code> widget and shows
+ * similar information.
+ * <p>
+ * Note: Since <code>Combo</code>s can contain both a list
+ * and an editable text field, it is possible to confuse methods
+ * which access one versus the other (compare for example,
+ * <code>clearSelection()</code> and <code>deselectAll()</code>).
+ * The API documentation is careful to indicate either "the
+ * receiver's list" or the "the receiver's text field" to
+ * distinguish between the two cases.
+ * </p><p>
+ * Note that although this class is a subclass of <code>Composite</code>,
+ * it does not make sense to add children to it, or set a layout on it.
+ * </p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>DROP_DOWN, READ_ONLY, SIMPLE</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>DefaultSelection, Modify, Selection, Verify</dd>
+ * </dl>
+ * <p>
+ * Note: Only one of the styles DROP_DOWN and SIMPLE may be specified.
+ * </p><p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ *
+ * @see List
+ */
+
+public class Combo extends Composite {
+ int textHandle;
+ boolean ignoreSelection;
+
+ /**
+ * the operating system limit for the number of characters
+ * that the text field in an instance of this class can hold
+ */
+ public static final int LIMIT;
+
+ /*
+ * These values can be different on different platforms.
+ * Therefore they are not initialized in the declaration
+ * to stop the compiler from inlining.
+ */
+ static {
+ LIMIT = 0x7FFFFFFF;
+ }
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#DROP_DOWN
+ * @see SWT#READ_ONLY
+ * @see SWT#SIMPLE
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Combo (Composite parent, int style) {
+ super (parent, checkStyle (style));
+ /* This code is intentionally commented */
+ //if ((style & SWT.H_SCROLL) != 0) this.style |= SWT.H_SCROLL;
+ this.style |= SWT.H_SCROLL;
+}
+
+Control [] _getChildren () {
+ return new Control [0];
+}
+
+/**
+ * Adds the argument to the end of the receiver's list.
+ *
+ * @param string the new item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #add(String,int)
+ */
+public void add (String string) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int itemHandle = OS.gcnew_ComboBoxItem ();
+ int strPtr = createDotNetString (string, false);
+ OS.ContentControl_Content (itemHandle, strPtr);
+ OS.GCHandle_Free (strPtr);
+ int itemCollection = OS.ItemsControl_Items (handle);
+ OS.ItemCollection_Add (itemCollection, itemHandle);
+ OS.GCHandle_Free (itemCollection);
+ OS.GCHandle_Free (itemHandle);
+}
+
+/**
+ * Adds the argument to the receiver's list at the given
+ * zero-relative index.
+ * <p>
+ * Note: To add an item at the end of the list, use the
+ * result of calling <code>getItemCount()</code> as the
+ * index or use <code>add(String)</code>.
+ * </p>
+ *
+ * @param string the new item
+ * @param index the index for the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #add(String)
+ */
+public void add (String string, int index) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int itemHandle = OS.gcnew_ComboBoxItem ();
+ int strPtr = createDotNetString (string, false);
+ OS.ContentControl_Content (itemHandle, strPtr);
+ OS.GCHandle_Free (strPtr);
+ int itemCollection = OS.ItemsControl_Items (handle);
+ OS.ItemCollection_Insert (itemCollection, index, itemHandle);
+ OS.GCHandle_Free (itemCollection);
+ OS.GCHandle_Free (itemHandle);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the receiver's text is modified, by sending
+ * it one of the messages defined in the <code>ModifyListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ModifyListener
+ * @see #removeModifyListener
+ */
+public void addModifyListener (ModifyListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Modify, typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the receiver's selection changes, by sending
+ * it one of the messages defined in the <code>SelectionListener</code>
+ * interface.
+ * <p>
+ * <code>widgetSelected</code> is called when the combo's list selection changes.
+ * <code>widgetDefaultSelected</code> is typically called when ENTER is pressed the combo's text area.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #removeSelectionListener
+ * @see SelectionEvent
+ */
+public void addSelectionListener (SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Selection,typedListener);
+ addListener (SWT.DefaultSelection,typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the receiver's text is verified, by sending
+ * it one of the messages defined in the <code>VerifyListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see VerifyListener
+ * @see #removeVerifyListener
+ *
+ * @since 3.1
+ */
+public void addVerifyListener (VerifyListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Verify, typedListener);
+}
+
+void addWidget () {
+ super.addWidget ();
+ if ((style & SWT.READ_ONLY) == 0) {
+ OS.UIElement_UpdateLayout (handle);
+ int name = createDotNetString ("PART_EditableTextBox", false);
+ int template = OS.Control_Template (handle);
+ textHandle = OS.FrameworkTemplate_FindName (template, name, handle);
+ OS.GCHandle_Free (name);
+ OS.GCHandle_Free (template);
+ }
+}
+
+int backgroundProperty () {
+ return OS.Control_BackgroundProperty ();
+}
+
+protected void checkSubclass () {
+ if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
+}
+
+static int checkStyle (int style) {
+ /*
+ * Feature in Windows. It is not possible to create
+ * a combo box that has a border using Windows style
+ * bits. All combo boxes draw their own border and
+ * do not use the standard Windows border styles.
+ * Therefore, no matter what style bits are specified,
+ * clear the BORDER bits so that the SWT style will
+ * match the Windows widget.
+ *
+ * The Windows behavior is currently implemented on
+ * all platforms.
+ */
+ style &= ~SWT.BORDER;
+
+ /*
+ * Even though it is legal to create this widget
+ * with scroll bars, they serve no useful purpose
+ * because they do not automatically scroll the
+ * widget's client area. The fix is to clear
+ * the SWT style.
+ */
+ style &= ~(SWT.H_SCROLL | SWT.V_SCROLL);
+ style = checkBits (style, SWT.DROP_DOWN, SWT.SIMPLE, 0, 0, 0, 0);
+ if ((style & SWT.SIMPLE) != 0) return style & ~SWT.READ_ONLY;
+ return style;
+}
+
+/**
+ * Sets the selection in the receiver's text field to an empty
+ * selection starting just before the first character. If the
+ * text field is editable, this has the effect of placing the
+ * i-beam at the start of the text.
+ * <p>
+ * Note: To clear the selected items in the receiver's list,
+ * use <code>deselectAll()</code>.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #deselectAll
+ */
+public void clearSelection () {
+ checkWidget ();
+ if ((style & SWT.READ_ONLY) == 0) {
+ OS.TextBox_Select (textHandle, 0, 0);
+ }
+}
+
+public Point computeSize (int wHint, int hHint, boolean changed) {
+ checkWidget ();
+ ignoreSelection = true;
+ int itemCount = getItemCount();
+ int text = 0;
+ if (textHandle != 0) {
+ text = OS.TextBox_Text (textHandle);
+ }
+ int selectedIndex = OS.Selector_SelectedIndex (handle);
+ int width = wHint, height = hHint;
+ if (wHint == SWT.DEFAULT) width = 0x7FFFFFFF;
+ if (hHint == SWT.DEFAULT) height = 0x7FFFFFFF;
+ width = Math.max (0, width);
+ height = Math.max (0, height);
+ int availSize = OS.gcnew_Size ((double) width, (double) height);
+ if (availSize == 0) error (SWT.ERROR_NO_HANDLES);
+ double requestWidth = OS.FrameworkElement_Width (handle);
+ double requestHeight = OS.FrameworkElement_Height (handle);
+ int widthDP = OS.FrameworkElement_WidthProperty ();
+ int heightDP = OS.FrameworkElement_HeightProperty ();
+ OS.DependencyObject_ClearValue (handle, widthDP);
+ OS.DependencyObject_ClearValue (handle, heightDP);
+ OS.UIElement_Measure (handle, availSize);
+ int size = OS.UIElement_DesiredSize (handle);
+ width = (int) OS.Size_Width (size);
+ height = (int) OS.Size_Height (size);
+ OS.GCHandle_Free (size);
+ for (int i = 0; i < itemCount; i++) {
+ OS.Selector_SelectedIndex (handle, i);
+ OS.UIElement_UpdateLayout (handle);
+ OS.UIElement_Measure (handle, availSize);
+ size = OS.UIElement_DesiredSize (handle);
+ width = Math.max (width, (int) OS.Size_Width (size));
+ height = Math.max (height, (int) OS.Size_Height (size));
+ OS.GCHandle_Free (size);
+ }
+ OS.GCHandle_Free (availSize);
+ OS.FrameworkElement_Width (handle, requestWidth);
+ OS.FrameworkElement_Height (handle, requestHeight);
+ OS.Selector_SelectedIndex (handle, selectedIndex);
+ if (textHandle != 0) {
+ OS.TextBox_Text (textHandle, text);
+ OS.GCHandle_Free (text);
+ }
+ OS.GCHandle_Free (widthDP);
+ OS.GCHandle_Free (heightDP);
+ if (wHint != SWT.DEFAULT) width = wHint;
+ if (hHint != SWT.DEFAULT) height = hHint;
+ ignoreSelection = false;
+ return new Point (width, height);
+}
+
+/**
+ * Copies the selected text.
+ * <p>
+ * The current selection is copied to the clipboard.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.1
+ */
+public void copy () {
+ checkWidget ();
+ if ((style & SWT.READ_ONLY) != 0) return; //TODO
+ OS.TextBoxBase_Copy (textHandle);
+}
+
+void createHandle () {
+ handle = OS.gcnew_ComboBox ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ if ((style & SWT.READ_ONLY) == 0) {
+ OS.ComboBox_IsEditable (handle, true);
+ }
+}
+
+/**
+ * Cuts the selected text.
+ * <p>
+ * The current selection is first copied to the
+ * clipboard and then deleted from the widget.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.1
+ */
+public void cut () {
+ checkWidget ();
+ if ((style & SWT.READ_ONLY) != 0) return;
+ OS.TextBoxBase_Cut (textHandle);
+}
+
+/**
+ * Deselects the item at the given zero-relative index in the receiver's
+ * list. If the item at the index was already deselected, it remains
+ * deselected. Indices that are out of range are ignored.
+ *
+ * @param index the index of the item to deselect
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void deselect (int index) {
+ checkWidget ();
+ ignoreSelection = true;
+ OS.Selector_SelectedIndex (handle, -1);
+ ignoreSelection = false;
+// FIXME: May need to send modify event here.
+// if ((style & SWT.READ_ONLY) == 0) {
+// sendEvent (SWT.Modify);
+// }
+}
+
+/**
+ * Deselects all selected items in the receiver's list.
+ * <p>
+ * Note: To clear the selection in the receiver's text field,
+ * use <code>clearSelection()</code>.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #clearSelection
+ */
+public void deselectAll () {
+ checkWidget ();
+ ignoreSelection = true;
+ OS.Selector_SelectedIndex (handle, -1);
+ ignoreSelection = false;
+}
+
+/**
+ * Returns the item at the given, zero-relative index in the
+ * receiver's list. Throws an exception if the index is out
+ * of range.
+ *
+ * @param index the index of the item to return
+ * @return the item at the given index
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String getItem (int index) {
+ checkWidget ();
+ int count = getItemCount ();
+ if (index < 0 || index >= count) error (SWT.ERROR_INVALID_RANGE);
+ int itemCollection = OS.ItemsControl_Items (handle);
+ int comboBoxItem = OS.ItemCollection_GetItemAt (itemCollection, index);
+ OS.GCHandle_Free (itemCollection);
+ int content = OS.ContentControl_Content (comboBoxItem);
+ String string = createJavaString(content);
+ OS.GCHandle_Free (comboBoxItem);
+ OS.GCHandle_Free (content);
+ return string;
+}
+
+/**
+ * Returns the number of items contained in the receiver's list.
+ *
+ * @return the number of items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getItemCount () {
+ checkWidget ();
+ int itemCollection = OS.ItemsControl_Items (handle);
+ int count = OS.ItemCollection_Count (itemCollection);
+ OS.GCHandle_Free (itemCollection);
+ return count;
+}
+
+/**
+ * Returns the height of the area which would be used to
+ * display <em>one</em> of the items in the receiver's list.
+ *
+ * @return the height of one item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getItemHeight () {
+ checkWidget ();
+ //todo
+ int result = 0;
+// if (result == OS.CB_ERR) error (SWT.ERROR_CANNOT_GET_ITEM_HEIGHT);
+ return result;
+}
+
+/**
+ * Returns a (possibly empty) array of <code>String</code>s which are
+ * the items in the receiver's list.
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its list of items, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ *
+ * @return the items in the receiver's list
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String [] getItems () {
+ checkWidget ();
+ int count = getItemCount ();
+ String [] result = new String [count];
+ for (int i=0; i<count; i++) result [i] = getItem (i);
+ return result;
+}
+
+/**
+ * Returns <code>true</code> if the receiver's list is visible,
+ * and <code>false</code> otherwise.
+ * <p>
+ * If one of the receiver's ancestors is not visible or some
+ * other condition makes the receiver not visible, this method
+ * may still indicate that it is considered visible even though
+ * it may not actually be showing.
+ * </p>
+ *
+ * @return the receiver's list's visibility state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.3
+ */
+/*public*/ boolean getListVisible () {
+ checkWidget ();
+ return OS.ComboBox_IsDropDownOpen (handle);
+}
+
+String getNameText () {
+ return getText ();
+}
+
+/**
+ * Returns the orientation of the receiver.
+ *
+ * @return the orientation style
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public int getOrientation () {
+ checkWidget ();
+ return style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
+}
+
+/**
+ * Returns a <code>Point</code> whose x coordinate is the
+ * character position representing the start of the selection
+ * in the receiver's text field, and whose y coordinate is the
+ * character position representing the end of the selection.
+ * An "empty" selection is indicated by the x and y coordinates
+ * having the same value.
+ * <p>
+ * Indexing is zero based. The range of a selection is from
+ * 0..N where N is the number of characters in the widget.
+ * </p>
+ *
+ * @return a point representing the selection start and end
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Point getSelection () {
+ checkWidget ();
+ if ((style & SWT.READ_ONLY) != 0) return new Point (0,0);
+ int start = OS.TextBox_SelectionStart (textHandle);
+ int length = OS.TextBox_SelectionLength (textHandle);
+ return new Point (start, start + length);
+}
+
+/**
+ * Returns the zero-relative index of the item which is currently
+ * selected in the receiver's list, or -1 if no item is selected.
+ *
+ * @return the index of the selected item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getSelectionIndex () {
+ checkWidget ();
+ return OS.Selector_SelectedIndex (handle);
+}
+
+/**
+ * Returns a string containing a copy of the contents of the
+ * receiver's text field, or an empty string if there are no
+ * contents.
+ *
+ * @return the receiver's text
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String getText () {
+ checkWidget ();
+ String text;
+ if ((style & SWT.READ_ONLY) != 0) {
+ int item = OS.ComboBox_SelectionBoxItem (handle);
+ text = createJavaString (item);
+ OS.GCHandle_Free (item);
+ } else {
+ int content = OS.TextBox_Text (textHandle);
+ text = createJavaString (content);
+ OS.GCHandle_Free (content);
+ }
+ return text;
+}
+
+/**
+ * Returns the height of the receivers's text field.
+ *
+ * @return the text height
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getTextHeight () {
+ checkWidget ();
+ //FIXME
+ return 0;
+}
+
+/**
+ * Returns the maximum number of characters that the receiver's
+ * text field is capable of holding. If this has not been changed
+ * by <code>setTextLimit()</code>, it will be the constant
+ * <code>Combo.LIMIT</code>.
+ *
+ * @return the text limit
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #LIMIT
+ */
+public int getTextLimit () {
+ checkWidget ();
+ //FIXME
+ return LIMIT;
+}
+
+/**
+ * Gets the number of items that are visible in the drop
+ * down portion of the receiver's list.
+ * <p>
+ * Note: This operation is a hint and is not supported on
+ * platforms that do not have this concept.
+ * </p>
+ *
+ * @return the number of items that are visible
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public int getVisibleItemCount () {
+ checkWidget ();
+ //FIXME
+ return 0;
+}
+
+void HandleSelectionChanged (int sender, int e) {
+ if (!checkEvent (e)) return;
+ if (!ignoreSelection) postEvent (SWT.Selection);
+}
+
+void HandleTextChanged (int sender, int e) {
+ if (!checkEvent (e)) return;
+ //TODO
+// int text = OS.TextBox_Text (textHandle);
+// String str = createJavaString (text);
+// OS.GCHandle_Free (text);
+}
+
+void hookEvents() {
+ super.hookEvents ();
+ int handler = OS.gcnew_SelectionChangedEventHandler (jniRef, "HandleSelectionChanged");
+ OS.Selector_SelectionChanged (handle, handler);
+ OS.GCHandle_Free (handler);
+ //TODO
+// if (textHandle != 0) {
+// handler = OS.gcnew_TextChangedEventHandler (jniRef, "HandleTextChanged");
+// OS.TextBoxBase_TextChanged (textHandle, handler);
+// OS.GCHandle_Free (handler);
+// }
+}
+/**
+ * Searches the receiver's list starting at the first item
+ * (index 0) until an item is found that is equal to the
+ * argument, and returns the index of that item. If no item
+ * is found, returns -1.
+ *
+ * @param string the search item
+ * @return the index of the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int indexOf (String string) {
+ return indexOf (string, 0);
+}
+
+/**
+ * Searches the receiver's list starting at the given,
+ * zero-relative index until an item is found that is equal
+ * to the argument, and returns the index of that item. If
+ * no item is found or the starting index is out of range,
+ * returns -1.
+ *
+ * @param string the search item
+ * @param start the zero-relative index at which to begin the search
+ * @return the index of the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int indexOf (String string, int start) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int count = getItemCount ();
+ if (start >= count) return -1;
+ start = Math.max (start, 0);
+ int strPtr = createDotNetString (string, false);
+ int itemCollection = OS.ItemsControl_Items (handle);
+ int index = -1;
+ while (start < count && index == -1) {
+ int item = OS.ItemCollection_GetItemAt (itemCollection, start);
+ int itemContent = OS.ContentControl_Content (item);
+ OS.GCHandle_Free (item);
+ if (itemContent != 0 && OS.Object_Equals (itemContent, strPtr)) index = start;
+ OS.GCHandle_Free (itemContent);
+ start ++;
+ }
+ OS.GCHandle_Free (strPtr);
+ OS.GCHandle_Free (itemCollection);
+ return index;
+}
+
+/**
+ * Pastes text from clipboard.
+ * <p>
+ * The selected text is deleted from the widget
+ * and new text inserted from the clipboard.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.1
+ */
+public void paste () {
+ checkWidget ();
+ if ((style & SWT.READ_ONLY) != 0) return;
+ OS.TextBoxBase_Paste (textHandle);
+}
+
+void releaseHandle () {
+ super.releaseHandle ();
+ if (textHandle != 0) OS.GCHandle_Free (textHandle);
+ textHandle = 0;
+}
+/**
+ * Removes the item from the receiver's list at the given
+ * zero-relative index.
+ *
+ * @param index the index for the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void remove (int index) {
+ checkWidget ();
+ if (index < 0 || index >= getItemCount ()) error (SWT.ERROR_INVALID_RANGE);
+ int itemCollection = OS.ItemsControl_Items(handle);
+ OS.ItemCollection_RemoveAt(itemCollection, index);
+ OS.GCHandle_Free(itemCollection);
+}
+
+/**
+ * Removes the items from the receiver's list which are
+ * between the given zero-relative start and end
+ * indices (inclusive).
+ *
+ * @param start the start of the range
+ * @param end the end of the range
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if either the start or end are not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void remove (int start, int end) {
+ checkWidget ();
+ int count = getItemCount ();
+ if (start < 0 || start >= count) error (SWT.ERROR_INVALID_RANGE);
+ if (end < 0 || end >= count) error (SWT.ERROR_INVALID_RANGE);
+ int itemCollection = OS.ItemsControl_Items(handle);
+ for (int i = end; i >= start; i--) {
+ OS.ItemCollection_RemoveAt(itemCollection, i);
+ }
+ OS.GCHandle_Free(itemCollection);
+}
+
+/**
+ * Searches the receiver's list starting at the first item
+ * until an item is found that is equal to the argument,
+ * and removes that item from the list.
+ *
+ * @param string the item to remove
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the string is not found in the list</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void remove (String string) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int index = indexOf (string, 0);
+ if (index == -1) error (SWT.ERROR_INVALID_ARGUMENT);
+ remove (index);
+}
+
+/**
+ * Removes all of the items from the receiver's list and clear the
+ * contents of receiver's text field.
+ * <p>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void removeAll () {
+ checkWidget ();
+ int itemCollection = OS.ItemsControl_Items (handle);
+ OS.ItemCollection_Clear (itemCollection);
+ OS.GCHandle_Free (itemCollection);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the receiver's text is modified.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ModifyListener
+ * @see #addModifyListener
+ */
+public void removeModifyListener (ModifyListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Modify, listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the receiver's selection changes.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #addSelectionListener
+ */
+public void removeSelectionListener (SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Selection, listener);
+ eventTable.unhook (SWT.DefaultSelection,listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the control is verified.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see VerifyListener
+ * @see #addVerifyListener
+ *
+ * @since 3.1
+ */
+public void removeVerifyListener (VerifyListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Verify, listener);
+}
+
+/**
+ * Selects the item at the given zero-relative index in the receiver's
+ * list. If the item at the index was already selected, it remains
+ * selected. Indices that are out of range are ignored.
+ *
+ * @param index the index of the item to select
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void select (int index) {
+ checkWidget ();
+ int itemCollection = OS.ItemsControl_Items(handle);
+ int count = OS.ItemCollection_Count(itemCollection);
+ OS.GCHandle_Free(itemCollection);
+ if (0 <= index && index < count) {
+// int selection = OS.Selector_SelectedIndex (handle);
+ ignoreSelection = true;
+ OS.Selector_SelectedIndex(handle, index);
+ ignoreSelection = false;
+// int code = OS.Selector_SelectedIndex(handle);
+// if (code != -1 && code != selection) {
+// sendEvent (SWT.Modify);
+// }
+ }
+}
+
+void setForegroundBrush (int brush) {
+ if (brush != 0) {
+ OS.Control_Foreground (handle, brush);
+ } else {
+ int property = OS.Control_ForegroundProperty ();
+ OS.DependencyObject_ClearValue (handle, property);
+ OS.GCHandle_Free (property);
+ }
+}
+
+/**
+ * Sets the text of the item in the receiver's list at the given
+ * zero-relative index to the string argument. This is equivalent
+ * to removing the old item at the index, and then adding the new
+ * item at that index.
+ *
+ * @param index the index for the item
+ * @param string the new text for the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setItem (int index, String string) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (index < 0 || index >= getItemCount()) error (SWT.ERROR_INVALID_RANGE);
+ int itemCollection = OS.ItemsControl_Items(handle);
+ int item = OS.ItemCollection_GetItemAt(itemCollection, index);
+ OS.GCHandle_Free(itemCollection);
+ int strPtr = createDotNetString (string, false);
+ OS.ContentControl_Content(item, strPtr);
+ OS.GCHandle_Free(strPtr);
+ OS.GCHandle_Free(item);
+}
+
+/**
+ * Sets the receiver's list to be the given array of items.
+ *
+ * @param items the array of items
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the items array is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if an item in the items array is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setItems (String [] items) {
+ checkWidget ();
+ if (items == null) error (SWT.ERROR_NULL_ARGUMENT);
+ for (int i=0; i<items.length; i++) {
+ if (items [i] == null) error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+ int itemCollection = OS.ItemsControl_Items(handle);
+ OS.ItemCollection_Clear(itemCollection);
+ for (int i = 0; i < items.length; i++) {
+ int itemHandle = OS.gcnew_ComboBoxItem ();
+ int strPtr = createDotNetString (items [i], false);
+ OS.ContentControl_Content (itemHandle, strPtr);
+ OS.GCHandle_Free (strPtr);
+ OS.ItemCollection_Add (itemCollection, itemHandle);
+ OS.GCHandle_Free (itemHandle);
+ }
+ OS.GCHandle_Free(itemCollection);
+}
+
+/**
+ * Marks the receiver's list as visible if the argument is <code>true</code>,
+ * and marks it invisible otherwise.
+ * <p>
+ * If one of the receiver's ancestors is not visible or some
+ * other condition makes the receiver not visible, marking
+ * it visible may not actually cause it to be displayed.
+ * </p>
+ *
+ * @param visible the new visibility state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.3
+ */
+/*public*/ void setListVisible (boolean visible) {
+ checkWidget ();
+ OS.ComboBox_IsDropDownOpen(handle, visible);
+}
+
+/**
+ * Sets the orientation of the receiver, which must be one
+ * of the constants <code>SWT.LEFT_TO_RIGHT</code> or <code>SWT.RIGHT_TO_LEFT</code>.
+ * <p>
+ *
+ * @param orientation new orientation style
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public void setOrientation (int orientation) {
+ checkWidget();
+ //FIXME
+}
+
+/**
+ * Sets the selection in the receiver's text field to the
+ * range specified by the argument whose x coordinate is the
+ * start of the selection and whose y coordinate is the end
+ * of the selection.
+ *
+ * @param selection a point representing the new selection start and end
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSelection (Point selection) {
+ checkWidget ();
+ if ((style & SWT.READ_ONLY) != 0) return;
+ if (selection == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int start = selection.x, length = selection.y - selection.x;
+ OS.TextBox_SelectionLength (textHandle, length);
+ OS.TextBox_SelectionStart (textHandle, start);
+}
+
+/**
+ * Sets the contents of the receiver's text field to the
+ * given string.
+ * <p>
+ * Note: The text field in a <code>Combo</code> is typically
+ * only capable of displaying a single line of text. Thus,
+ * setting the text to a string containing line breaks or
+ * other special characters will probably cause it to
+ * display incorrectly.
+ * </p>
+ *
+ * @param string the new text
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setText (String string) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if ((style & SWT.READ_ONLY) != 0) {
+ int index = indexOf (string);
+ if (index != -1) select (index);
+ return;
+ }
+ int strPtr = createDotNetString (string, false);
+ OS.TextBox_Text (textHandle, strPtr);
+ OS.GCHandle_Free (strPtr);
+}
+
+/**
+ * Sets the maximum number of characters that the receiver's
+ * text field is capable of holding to be the argument.
+ * <p>
+ * To reset this value to the default, use <code>setTextLimit(Combo.LIMIT)</code>.
+ * Specifying a limit value larger than <code>Combo.LIMIT</code> sets the
+ * receiver's limit to <code>Combo.LIMIT</code>.
+ * </p>
+ * @param limit new text limit
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_CANNOT_BE_ZERO - if the limit is zero</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #LIMIT
+ */
+public void setTextLimit (int limit) {
+ checkWidget ();
+ if (limit == 0) error (SWT.ERROR_CANNOT_BE_ZERO);
+ //FIXME
+}
+
+/**
+ * Sets the number of items that are visible in the drop
+ * down portion of the receiver's list.
+ * <p>
+ * Note: This operation is a hint and is not supported on
+ * platforms that do not have this concept.
+ * </p>
+ *
+ * @param count the new number of items to be visible
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void setVisibleItemCount (int count) {
+ checkWidget ();
+ if (count < 0) return;
+ //FIXME
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Composite.java
new file mode 100644
index 0000000000..91a6c6c432
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Composite.java
@@ -0,0 +1,1063 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Instances of this class are controls which are capable
+ * of containing other controls.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>NO_BACKGROUND, NO_FOCUS, NO_MERGE_PAINTS, NO_REDRAW_RESIZE, NO_RADIO_GROUP, EMBEDDED, DOUBLE_BUFFERED</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * <p>
+ * Note: The <code>NO_BACKGROUND</code>, <code>NO_FOCUS</code>, <code>NO_MERGE_PAINTS</code>,
+ * and <code>NO_REDRAW_RESIZE</code> styles are intended for use with <code>Canvas</code>.
+ * They can be used with <code>Composite</code> if you are drawing your own, but their
+ * behavior is undefined if they are used with subclasses of <code>Composite</code> other
+ * than <code>Canvas</code>.
+ * </p><p>
+ * Note: The <code>CENTER</code> style, although undefined for composites, has the
+ * same value as <code>EMBEDDED</code> (which is used to embed widgets from other
+ * widget toolkits into SWT). On some operating systems (GTK, Motif), this may cause
+ * the children of this composite to be obscured. The <code>EMBEDDED</code> style
+ * is for use by other widget toolkits and should normally never be used.
+ * </p><p>
+ * This class may be subclassed by custom control implementors
+ * who are building controls that are constructed from aggregates
+ * of other controls.
+ * </p>
+ *
+ * @see Canvas
+ */
+
+public class Composite extends Scrollable {
+ Layout layout;
+ Control [] tabList;
+ int layoutCount, backgroundMode;
+
+/**
+ * Prevents uninitialized instances from being created outside the package.
+ */
+Composite () {
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a widget which will be the parent of the new instance (cannot be null)
+ * @param style the style of widget to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * </ul>
+ *
+ * @see SWT#NO_BACKGROUND
+ * @see SWT#NO_FOCUS
+ * @see SWT#NO_MERGE_PAINTS
+ * @see SWT#NO_REDRAW_RESIZE
+ * @see SWT#NO_RADIO_GROUP
+ * @see Widget#getStyle
+ */
+public Composite (Composite parent, int style) {
+ super (parent, style);
+}
+
+int getCaretHandle () {
+ return 0;
+}
+
+Control [] _getChildren () {
+ int parentHandle = parentingHandle ();
+ int elements = OS.Panel_Children (parentHandle);
+ int count = OS.UIElementCollection_Count (elements);
+ int caretHandle = getCaretHandle ();
+ if (caretHandle != 0) count--;
+ Control [] children = new Control [count];
+ int index = count - 1;
+ if (count != 0) {
+ int enumerator = OS.UIElementCollection_GetEnumerator (elements);
+ while (OS.IEnumerator_MoveNext (enumerator)) {
+ int current = OS.UIElementCollection_Current (enumerator);
+ if (caretHandle != 0 && OS.Object_Equals(caretHandle, current)) {
+ OS.GCHandle_Free (current);
+ continue;
+ }
+ Widget widget = display.getWidget (current);
+ if (widget != null && widget != this) {
+ if (widget instanceof Control) {
+ children [index--] = (Control)widget;
+ }
+ }
+ OS.GCHandle_Free (current);
+ }
+ OS.GCHandle_Free (enumerator);
+ }
+ OS.GCHandle_Free (elements);
+ if (index == -1) return children;
+ Control [] newChildren = new Control [count - index - 1];
+ System.arraycopy (children, index + 1, newChildren, 0, newChildren.length);
+ return newChildren;
+}
+
+Control [] _getTabList () {
+ if (tabList == null) return tabList;
+ int count = 0;
+ for (int i=0; i<tabList.length; i++) {
+ if (!tabList [i].isDisposed ()) count++;
+ }
+ if (count == tabList.length) return tabList;
+ Control [] newList = new Control [count];
+ int index = 0;
+ for (int i=0; i<tabList.length; i++) {
+ if (!tabList [i].isDisposed ()) {
+ newList [index++] = tabList [i];
+ }
+ }
+ tabList = newList;
+ return tabList;
+}
+
+void addChild (Control control) {
+ int parentHandle = parentingHandle ();
+ int children = OS.Panel_Children (parentHandle);
+ int index = 0;
+ if (parentHandle != handle) {
+ if (OS.UIElementCollection_Contains (children, handle)) {
+ index = 1;
+ }
+ }
+ int topHandle = control.topHandle ();
+ OS.UIElementCollection_Insert (children, index, topHandle);
+ OS.GCHandle_Free (children);
+ OS.FrameworkElement_Width (topHandle, 0);
+ OS.FrameworkElement_Height (topHandle, 0);
+}
+
+int backgoundProperty () {
+ return OS.Panel_BackgroundProperty();
+}
+
+/**
+ * Clears any data that has been cached by a Layout for all widgets that
+ * are in the parent hierarchy of the changed control up to and including the
+ * receiver. If an ancestor does not have a layout, it is skipped.
+ *
+ * @param changed an array of controls that changed state and require a recalculation of size
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the changed array is null any of its controls are null or have been disposed</li>
+ * <li>ERROR_INVALID_PARENT - if any control in changed is not in the widget tree of the receiver</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public void changed (Control[] changed) {
+ checkWidget ();
+ if (changed == null) error (SWT.ERROR_INVALID_ARGUMENT);
+ for (int i=0; i<changed.length; i++) {
+ Control control = changed [i];
+ if (control == null) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (control.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ boolean ancestor = false;
+ Composite composite = control.parent;
+ while (composite != null) {
+ ancestor = composite == this;
+ if (ancestor) break;
+ composite = composite.parent;
+ }
+ if (!ancestor) error (SWT.ERROR_INVALID_PARENT);
+ }
+ for (int i=0; i<changed.length; i++) {
+ Control child = changed [i];
+ Composite composite = child.parent;
+ while (child != this) {
+ if (composite.layout == null || !composite.layout.flushCache (child)) {
+ composite.state |= LAYOUT_CHANGED;
+ }
+ child = composite;
+ composite = child.parent;
+ }
+ }
+}
+
+void checkBuffered () {
+ if ((state & CANVAS) == 0) {
+ super.checkBuffered ();
+ }
+}
+
+protected void checkSubclass () {
+ /* Do nothing - Subclassing is allowed */
+}
+
+Control [] computeTabList () {
+ Control result [] = super.computeTabList ();
+ if (result.length == 0) return result;
+ Control [] list = tabList != null ? _getTabList () : _getChildren ();
+ for (int i=0; i<list.length; i++) {
+ Control child = list [i];
+ Control [] childList = child.computeTabList ();
+ if (childList.length != 0) {
+ Control [] newResult = new Control [result.length + childList.length];
+ System.arraycopy (result, 0, newResult, 0, result.length);
+ System.arraycopy (childList, 0, newResult, result.length, childList.length);
+ result = newResult;
+ }
+ }
+ return result;
+}
+
+public Point computeSize (int wHint, int hHint, boolean changed) {
+ checkWidget ();
+ Point size;
+ if (layout != null) {
+ if (wHint == SWT.DEFAULT || hHint == SWT.DEFAULT) {
+ changed |= (state & LAYOUT_CHANGED) != 0;
+ state &= ~LAYOUT_CHANGED;
+ size = layout.computeSize (this, wHint, hHint, changed);
+ } else {
+ size = new Point (wHint, hHint);
+ }
+ } else {
+ size = minimumSize (wHint, hHint, changed);
+ }
+ if (size.x == 0) size.x = DEFAULT_WIDTH;
+ if (size.y == 0) size.y = DEFAULT_HEIGHT;
+ if (wHint != SWT.DEFAULT) size.x = wHint;
+ if (hHint != SWT.DEFAULT) size.y = hHint;
+ Rectangle trim = computeTrim (0, 0, size.x, size.y);
+ return new Point (trim.width, trim.height);
+}
+
+void createHandle () {
+ state |= CANVAS;
+ if ((style & (SWT.H_SCROLL | SWT.V_SCROLL)) == 0) {
+ state |= THEME_BACKGROUND;
+ }
+ boolean scrolled = (style & (SWT.H_SCROLL | SWT.V_SCROLL)) != 0;
+ createHandle (scrolled, false);
+}
+
+void createHandle (boolean scrolled, boolean menubar) {
+ handle = OS.gcnew_SWTCanvas (jniRef);
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ if (scrolled || menubar) {
+ scrolledHandle = OS.gcnew_Grid ();
+ if (scrolledHandle == 0) error (SWT.ERROR_NO_HANDLES);
+
+ /* Create grid definition */
+ int gridLength = OS.gcnew_GridLength (1, OS.GridUnitType_Auto);
+ if (gridLength == 0) error (SWT.ERROR_NO_HANDLES);
+ int columnDefinitions = OS.Grid_ColumnDefinitions (scrolledHandle);
+ int column0 = OS.gcnew_ColumnDefinition ();
+ if (column0 == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.ColumnDefinitionCollection_Add (columnDefinitions, column0);
+ int column1 = OS.gcnew_ColumnDefinition ();
+ if (column1 == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.ColumnDefinition_Width (column1, gridLength);
+ OS.ColumnDefinitionCollection_Add (columnDefinitions, column1);
+ int rowDefinitions = OS.Grid_RowDefinitions (scrolledHandle);
+ int row0 = OS.gcnew_RowDefinition ();
+ if (row0 == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.RowDefinition_Height (row0, gridLength);
+ OS.RowDefinitionCollection_Add (rowDefinitions, row0);
+ int row1 = OS.gcnew_RowDefinition ();
+ if (row1 == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.RowDefinitionCollection_Add (rowDefinitions, row1);
+ int row2 = OS.gcnew_RowDefinition ();
+ if (row2 == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.RowDefinition_Height (row2, gridLength);
+ OS.RowDefinitionCollection_Add (rowDefinitions, row2);
+ OS.GCHandle_Free (column0);
+ OS.GCHandle_Free (column1);
+ OS.GCHandle_Free (row0);
+ OS.GCHandle_Free (row1);
+ OS.GCHandle_Free (row2);
+ OS.GCHandle_Free (gridLength);
+ OS.GCHandle_Free (columnDefinitions);
+ OS.GCHandle_Free (rowDefinitions);
+
+ /* create children */
+ int children = OS.Panel_Children (scrolledHandle);
+ OS.UIElementCollection_Add (children, handle);
+ OS.Grid_SetRow (handle, 1);
+ OS.Grid_SetColumn (handle, 0);
+ if ((style & SWT.V_SCROLL) != 0) {
+ int vScroll = OS.gcnew_ScrollBar ();
+ if (vScroll == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.ScrollBar_Orientation (vScroll, OS.Orientation_Vertical);
+ OS.RangeBase_Maximum(vScroll, 90);
+ OS.RangeBase_LargeChange (vScroll, 10);
+ OS.ScrollBar_ViewportSize (vScroll, 10);
+ OS.Grid_SetRow (vScroll, 1);
+ OS.Grid_SetColumn (vScroll, 1);
+ OS.UIElementCollection_Add (children, vScroll);
+ OS.GCHandle_Free (vScroll);
+ }
+ if ((style & SWT.H_SCROLL) != 0) {
+ int hScroll = OS.gcnew_ScrollBar ();
+ if (hScroll == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.ScrollBar_Orientation (hScroll, OS.Orientation_Horizontal);
+ OS.RangeBase_Maximum (hScroll, 90);
+ OS.RangeBase_LargeChange (hScroll, 10);
+ OS.ScrollBar_ViewportSize (hScroll, 10);
+ OS.Grid_SetRow (hScroll, 2);
+ OS.Grid_SetColumn (hScroll, 0);
+ OS.UIElementCollection_Add (children, hScroll);
+ OS.GCHandle_Free (hScroll);
+ }
+ OS.GCHandle_Free (children);
+ }
+}
+
+int defaultBackground () {
+ if ((state & CANVAS) != 0) {
+ return OS.SystemColors_ControlColor;
+ }
+ return 0;
+}
+
+Composite findDeferredControl () {
+ return layoutCount > 0 ? this : parent.findDeferredControl ();
+}
+
+Menu [] findMenus (Control control) {
+ if (control == this) return new Menu [0];
+ Menu result [] = super.findMenus (control);
+ Control [] children = _getChildren ();
+ for (int i=0; i<children.length; i++) {
+ Control child = children [i];
+ Menu [] menuList = child.findMenus (control);
+ if (menuList.length != 0) {
+ Menu [] newResult = new Menu [result.length + menuList.length];
+ System.arraycopy (result, 0, newResult, 0, result.length);
+ System.arraycopy (menuList, 0, newResult, result.length, menuList.length);
+ result = newResult;
+ }
+ }
+ return result;
+}
+
+void fixTabList (Control control) {
+ if (tabList == null) return;
+ int count = 0;
+ for (int i=0; i<tabList.length; i++) {
+ if (tabList [i] == control) count++;
+ }
+ if (count == 0) return;
+ Control [] newList = null;
+ int length = tabList.length - count;
+ if (length != 0) {
+ newList = new Control [length];
+ int index = 0;
+ for (int i=0; i<tabList.length; i++) {
+ if (tabList [i] != control) {
+ newList [index++] = tabList [i];
+ }
+ }
+ }
+ tabList = newList;
+}
+
+/**
+ * Returns the receiver's background drawing mode. This
+ * will be one of the following constants defined in class
+ * <code>SWT</code>:
+ * <code>INHERIT_NONE</code>, <code>INHERIT_DEFAULT</code>,
+ * <code>INHERTIT_FORCE</code>.
+ *
+ * @return the background mode
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SWT
+ *
+ * @since 3.2
+ */
+public int getBackgroundMode () {
+ checkWidget ();
+ return backgroundMode;
+}
+
+/**
+ * Returns a (possibly empty) array containing the receiver's children.
+ * Children are returned in the order that they are drawn. The topmost
+ * control appears at the beginning of the array. Subsequent controls
+ * draw beneath this control and appear later in the array.
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its list of children, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ *
+ * @return an array of children
+ *
+ * @see Control#moveAbove
+ * @see Control#moveBelow
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Control [] getChildren () {
+ checkWidget ();
+ return _getChildren ();
+}
+
+/**
+ * Returns layout which is associated with the receiver, or
+ * null if one has not been set.
+ *
+ * @return the receiver's layout or null
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Layout getLayout () {
+ checkWidget ();
+ return layout;
+}
+
+Point getLocation (Control child) {
+ int topHandle = child.topHandle ();
+ int x = (int) OS.Canvas_GetLeft (topHandle);
+ int y = (int) OS.Canvas_GetTop (topHandle);
+ return new Point (x, y);
+}
+
+/**
+ * Gets the (possibly empty) tabbing order for the control.
+ *
+ * @return tabList the ordered list of controls representing the tab order
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #setTabList
+ */
+public Control [] getTabList () {
+ checkWidget ();
+ Control [] tabList = _getTabList ();
+ if (tabList == null) {
+ int count = 0;
+ Control [] list =_getChildren ();
+ for (int i=0; i<list.length; i++) {
+ if (list [i].isTabGroup ()) count++;
+ }
+ tabList = new Control [count];
+ int index = 0;
+ for (int i=0; i<list.length; i++) {
+ if (list [i].isTabGroup ()) {
+ tabList [index++] = list [i];
+ }
+ }
+ }
+ return tabList;
+}
+
+boolean hooksKeys () {
+ return hooks (SWT.KeyDown) || hooks (SWT.KeyUp);
+}
+
+/**
+ * Returns <code>true</code> if the receiver has deferred
+ * the performing of layout, and <code>false</code> otherwise.
+ *
+ * @return the receiver's deferred layout state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #setLayoutDeferred(boolean)
+ * @see #isLayoutDeferred()
+ *
+ * @since 3.1
+ */
+public boolean getLayoutDeferred () {
+ checkWidget ();
+ return layoutCount > 0 ;
+}
+
+void HandlePreviewMouseDown(int sender, int e) {
+ if (!checkEvent (e)) return;
+ super.HandlePreviewMouseDown (sender, e);
+
+ /* Set focus for a canvas with no children */
+ if ((state & CANVAS) != 0) {
+ if ((style & SWT.NO_FOCUS) == 0 && hooksKeys ()) {
+ int children = OS.Panel_Children (handle);
+ int count = OS.UIElementCollection_Count (children);
+ OS.GCHandle_Free (children);
+ int caretHandle = getCaretHandle();
+ if (caretHandle != 0) count--;
+ if (count == 0) {
+ //TODO improve, set the Focusable to true in some other time so Tab works
+ OS.UIElement_Focusable (handle, true);
+ OS.UIElement_Focus (handle);
+ }
+ }
+ }
+}
+
+/**
+ * Returns <code>true</code> if the receiver or any ancestor
+ * up to and including the receiver's nearest ancestor shell
+ * has deferred the performing of layouts. Otherwise, <code>false</code>
+ * is returned.
+ *
+ * @return the receiver's deferred layout state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #setLayoutDeferred(boolean)
+ * @see #getLayoutDeferred()
+ *
+ * @since 3.1
+ */
+public boolean isLayoutDeferred () {
+ checkWidget ();
+ return findDeferredControl () != null;
+}
+
+boolean isTabGroup() {
+ if ((state & CANVAS) != 0) return true;
+ return super.isTabGroup();
+}
+
+/**
+ * If the receiver has a layout, asks the layout to <em>lay out</em>
+ * (that is, set the size and location of) the receiver's children.
+ * If the receiver does not have a layout, do nothing.
+ * <p>
+ * This is equivalent to calling <code>layout(true)</code>.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void layout () {
+ checkWidget ();
+ layout (true);
+}
+
+/**
+ * If the receiver has a layout, asks the layout to <em>lay out</em>
+ * (that is, set the size and location of) the receiver's children.
+ * If the argument is <code>true</code> the layout must not rely
+ * on any information it has cached about the immediate children. If it
+ * is <code>false</code> the layout may (potentially) optimize the
+ * work it is doing by assuming that none of the receiver's
+ * children has changed state since the last layout.
+ * If the receiver does not have a layout, do nothing.
+ * <p>
+ * If a child is resized as a result of a call to layout, the
+ * resize event will invoke the layout of the child. The layout
+ * will cascade down through all child widgets in the receiver's widget
+ * tree until a child is encountered that does not resize. Note that
+ * a layout due to a resize will not flush any cached information
+ * (same as <code>layout(false)</code>).</p>
+ *
+ * @param changed <code>true</code> if the layout must flush its caches, and <code>false</code> otherwise
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void layout (boolean changed) {
+ checkWidget ();
+ if (layout == null) return;
+ layout (changed, false);
+}
+
+/**
+ * If the receiver has a layout, asks the layout to <em>lay out</em>
+ * (that is, set the size and location of) the receiver's children.
+ * If the changed argument is <code>true</code> the layout must not rely
+ * on any information it has cached about its children. If it
+ * is <code>false</code> the layout may (potentially) optimize the
+ * work it is doing by assuming that none of the receiver's
+ * children has changed state since the last layout.
+ * If the all argument is <code>true</code> the layout will cascade down
+ * through all child widgets in the receiver's widget tree, regardless of
+ * whether the child has changed size. The changed argument is applied to
+ * all layouts. If the all argument is <code>false</code>, the layout will
+ * <em>not</em> cascade down through all child widgets in the receiver's widget
+ * tree. However, if a child is resized as a result of a call to layout, the
+ * resize event will invoke the layout of the child. Note that
+ * a layout due to a resize will not flush any cached information
+ * (same as <code>layout(false)</code>).</p>
+ *
+ * @param changed <code>true</code> if the layout must flush its caches, and <code>false</code> otherwise
+ * @param all <code>true</code> if all children in the receiver's widget tree should be laid out, and <code>false</code> otherwise
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public void layout (boolean changed, boolean all) {
+ checkWidget ();
+ if (layout == null && !all) return;
+ markLayout (changed, all);
+ updateLayout (true, all);
+}
+
+/**
+ * Forces a lay out (that is, sets the size and location) of all widgets that
+ * are in the parent hierarchy of the changed control up to and including the
+ * receiver. The layouts in the hierarchy must not rely on any information
+ * cached about the changed control or any of its ancestors. The layout may
+ * (potentially) optimize the work it is doing by assuming that none of the
+ * peers of the changed control have changed state since the last layout.
+ * If an ancestor does not have a layout, skip it.
+ *
+ * @param changed a control that has had a state change which requires a recalculation of its size
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the changed array is null any of its controls are null or have been disposed</li>
+ * <li>ERROR_INVALID_PARENT - if any control in changed is not in the widget tree of the receiver</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public void layout (Control [] changed) {
+ checkWidget ();
+ if (changed == null) error (SWT.ERROR_INVALID_ARGUMENT);
+ for (int i=0; i<changed.length; i++) {
+ Control control = changed [i];
+ if (control == null) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (control.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ boolean ancestor = false;
+ Composite composite = control.parent;
+ while (composite != null) {
+ ancestor = composite == this;
+ if (ancestor) break;
+ composite = composite.parent;
+ }
+ if (!ancestor) error (SWT.ERROR_INVALID_PARENT);
+ }
+ int updateCount = 0;
+ Composite [] update = new Composite [16];
+ for (int i=0; i<changed.length; i++) {
+ Control child = changed [i];
+ Composite composite = child.parent;
+ while (child != this) {
+ if (composite.layout != null) {
+ composite.state |= LAYOUT_NEEDED;
+ if (!composite.layout.flushCache (child)) {
+ composite.state |= LAYOUT_CHANGED;
+ }
+ }
+ if (updateCount == update.length) {
+ Composite [] newUpdate = new Composite [update.length + 16];
+ System.arraycopy (update, 0, newUpdate, 0, update.length);
+ update = newUpdate;
+ }
+ child = update [updateCount++] = composite;
+ composite = child.parent;
+ }
+ }
+ for (int i=updateCount-1; i>=0; i--) {
+ update [i].updateLayout (true, false);
+ }
+}
+
+void OnRender(int drawingContext) {
+ if (isDisposed ()) return;
+ OS.SWTCanvas_Visual (handle, 0);
+ if (!hooks (SWT.Paint)) return;
+ int width = (int)OS.FrameworkElement_ActualWidth (handle);
+ int height = (int)OS.FrameworkElement_ActualHeight (handle);
+ if (width != 0 && height != 0) {
+ GCData data = new GCData ();
+ data.device = display;
+ data.drawingContext = drawingContext;
+ GC gc = GC.wpf_new (this, data);
+ Event event = new Event ();
+ event.gc = gc;
+ event.width = width;
+ event.height = height;
+ sendEvent (SWT.Paint, event);
+ event.gc = null;
+ gc.dispose ();
+ }
+}
+
+void markLayout (boolean changed, boolean all) {
+ if (layout != null) {
+ state |= LAYOUT_NEEDED;
+ if (changed) state |= LAYOUT_CHANGED;
+ }
+ if (all) {
+ Control [] children = _getChildren ();
+ for (int i=0; i<children.length; i++) {
+ children [i].markLayout (changed, all);
+ }
+ }
+}
+
+Point minimumSize (int wHint, int hHint, boolean changed) {
+ Control [] children = _getChildren ();
+ int width = 0, height = 0;
+ for (int i=0; i<children.length; i++) {
+ Rectangle rect = children [i].getBounds ();
+ width = Math.max (width, rect.x + rect.width);
+ height = Math.max (height, rect.y + rect.height);
+ }
+ return new Point (width, height);
+}
+
+int parentingHandle () {
+ return handle;
+}
+
+void releaseChildren (boolean destroy) {
+ Control [] children = _getChildren ();
+ for (int i=0; i<children.length; i++) {
+ Control child = children [i];
+ if (child != null && !child.isDisposed ()) {
+ child.release (false);
+ }
+ }
+ super.releaseChildren (destroy);
+}
+
+void releaseWidget () {
+ super.releaseWidget ();
+// if ((state & CANVAS) != 0 && (style & SWT.EMBEDDED) != 0) {
+// int hwndChild = OS.GetWindow (handle, OS.GW_CHILD);
+// if (hwndChild != 0) {
+// int threadId = OS.GetWindowThreadProcessId (hwndChild, null);
+// if (threadId != OS.GetCurrentThreadId ()) {
+// OS.ShowWindow (hwndChild, OS.SW_HIDE);
+// OS.SetParent (hwndChild, 0);
+// }
+// }
+// }
+ layout = null;
+ tabList = null;
+}
+
+void removeChild (Control control) {
+ int topHandle = control.topHandle ();
+ int parentHandle = parentingHandle ();
+ int children = OS.Panel_Children (parentHandle);
+ OS.UIElementCollection_Remove (children, topHandle);
+ OS.GCHandle_Free (children);
+}
+
+void removeControl (Control control) {
+ fixTabList (control);
+}
+
+void setBackgroundBrush (int brush) {
+ if (brush != 0) {
+ OS.Panel_Background (handle, brush);
+ } else {
+ int property = OS.Panel_BackgroundProperty ();
+ OS.DependencyObject_ClearValue (handle, property);
+ OS.GCHandle_Free (property);
+ }
+}
+
+/**
+ * Sets the background drawing mode to the argument which should
+ * be one of the following constants defined in class <code>SWT</code>:
+ * <code>INHERIT_NONE</code>, <code>INHERIT_DEFAULT</code>,
+ * <code>INHERIT_FORCE</code>.
+ *
+ * @param mode the new background mode
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SWT
+ *
+ * @since 3.2
+ */
+public void setBackgroundMode (int mode) {
+ checkWidget ();
+ backgroundMode = mode;
+ Control [] children = _getChildren ();
+ for (int i = 0; i < children.length; i++) {
+ children [i].updateBackgroundMode ();
+ }
+}
+
+int setBounds (int x, int y, int width, int height, int flags) {
+ int result = super.setBounds (x, y, width, height, flags);
+ if ((result & RESIZED) != 0 && layout != null) {
+ markLayout (false, false);
+ updateLayout (false, false);
+ }
+ return result;
+}
+
+boolean setFixedFocus () {
+ checkWidget ();
+ Control [] children = _getChildren ();
+ for (int i=0; i<children.length; i++) {
+ Control child = children [i];
+ if (child.setRadioFocus ()) return true;
+ }
+ for (int i=0; i<children.length; i++) {
+ Control child = children [i];
+ if (child.setFixedFocus ()) return true;
+ }
+ return super.setFixedFocus ();
+}
+
+public boolean setFocus () {
+ checkWidget ();
+ if (OS.UIElement_IsFocused (handle)) return true;
+ return OS.UIElement_Focus (handle);
+}
+
+void setFont (int font, double size) {
+}
+
+void setForegroundBrush (int brush) {
+}
+
+/**
+ * Sets the layout which is associated with the receiver to be
+ * the argument which may be null.
+ *
+ * @param layout the receiver's new layout or null
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setLayout (Layout layout) {
+ checkWidget ();
+ this.layout = layout;
+}
+
+/**
+ * If the argument is <code>true</code>, causes subsequent layout
+ * operations in the receiver or any of its children to be ignored.
+ * No layout of any kind can occur in the receiver or any of its
+ * children until the flag is set to false.
+ * Layout operations that occurred while the flag was
+ * <code>true</code> are remembered and when the flag is set to
+ * <code>false</code>, the layout operations are performed in an
+ * optimized manner. Nested calls to this method are stacked.
+ *
+ * @param defer the new defer state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #layout(boolean)
+ * @see #layout(Control[])
+ *
+ * @since 3.1
+ */
+public void setLayoutDeferred (boolean defer) {
+ if (!defer) {
+ if (--layoutCount == 0) {
+ if ((state & LAYOUT_CHILD) != 0 || (state & LAYOUT_NEEDED) != 0) {
+ updateLayout (true, true);
+ }
+ }
+ } else {
+ layoutCount++;
+ }
+}
+
+/**
+ * Sets the tabbing order for the specified controls to
+ * match the order that they occur in the argument list.
+ *
+ * @param tabList the ordered list of controls representing the tab order or null
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if a widget in the tabList is null or has been disposed</li>
+ * <li>ERROR_INVALID_PARENT - if widget in the tabList is not in the same widget tree</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setTabList (Control [] tabList) {
+ checkWidget ();
+ if (tabList != null) {
+ for (int i=0; i<tabList.length; i++) {
+ Control control = tabList [i];
+ if (control == null) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (control.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (control.parent != this) error (SWT.ERROR_INVALID_PARENT);
+ }
+ Control [] newList = new Control [tabList.length];
+ System.arraycopy (tabList, 0, newList, 0, tabList.length);
+ tabList = newList;
+ }
+ this.tabList = tabList;
+}
+
+boolean setTabGroupFocus () {
+ if (isTabItem ()) return setTabItemFocus ();
+ boolean takeFocus = (style & SWT.NO_FOCUS) == 0;
+ if ((state & CANVAS) != 0) {
+ takeFocus = hooksKeys ();
+ if ((style & SWT.EMBEDDED) != 0) takeFocus = true;
+ }
+ if (takeFocus && setTabItemFocus ()) return true;
+ Control [] children = _getChildren ();
+ for (int i=0; i<children.length; i++) {
+ Control child = children [i];
+ if (child.isTabItem () && child.setRadioFocus ()) return true;
+ }
+ for (int i=0; i<children.length; i++) {
+ Control child = children [i];
+ if (child.isTabItem () && child.setTabItemFocus ()) return true;
+ }
+ return false;
+}
+
+boolean translateMnemonic (Event event, Control control) {
+ if (super.translateMnemonic (event, control)) return true;
+ if (control != null) {
+ Control [] children = _getChildren ();
+ for (int i=0; i<children.length; i++) {
+ Control child = children [i];
+ if (child.translateMnemonic (event, control)) return true;
+ }
+ }
+ return false;
+}
+
+int traversalCode(int key, int event) {
+ if ((state & CANVAS) != 0) {
+ if ((style & SWT.NO_FOCUS) != 0) return 0;
+ if (hooksKeys ()) return 0;
+ }
+ return super.traversalCode (key, event);
+}
+
+boolean translateTraversal (int msg) {
+ if ((state & CANVAS) != 0 && (style & SWT.EMBEDDED) != 0) return false;
+ return super.translateTraversal (msg);
+}
+
+void updateBackgroundColor () {
+ super.updateBackgroundColor ();
+ Control [] children = _getChildren ();
+ for (int i=0; i<children.length; i++) {
+ if ((children [i].state & PARENT_BACKGROUND) != 0) {
+ children [i].updateBackgroundColor ();
+ }
+ }
+}
+
+void updateBackgroundImage () {
+ super.updateBackgroundImage ();
+ Control [] children = _getChildren ();
+ for (int i=0; i<children.length; i++) {
+ if ((children [i].state & PARENT_BACKGROUND) != 0) {
+ children [i].updateBackgroundImage ();
+ }
+ }
+}
+
+void updateBackgroundMode () {
+ super.updateBackgroundMode ();
+ Control [] children = _getChildren ();
+ for (int i = 0; i < children.length; i++) {
+ children [i].updateBackgroundMode ();
+ }
+}
+
+void updateFont (Font oldFont, Font newFont) {
+ super.updateFont (oldFont, newFont);
+ Control [] children = _getChildren ();
+ for (int i=0; i<children.length; i++) {
+ Control control = children [i];
+ if (!control.isDisposed ()) {
+ control.updateFont (oldFont, newFont);
+ }
+ }
+}
+
+void updateLayout (boolean resize, boolean all) {
+ Composite parent = findDeferredControl ();
+ if (parent != null) {
+ parent.state |= LAYOUT_CHILD;
+ return;
+ }
+ if ((state & LAYOUT_NEEDED) != 0) {
+ boolean changed = (state & LAYOUT_CHANGED) != 0;
+ state &= ~(LAYOUT_NEEDED | LAYOUT_CHANGED);
+ layout.layout (this, changed);
+ }
+ if (all) {
+ state &= ~LAYOUT_CHILD;
+ Control [] children = _getChildren ();
+ for (int i=0; i<children.length; i++) {
+ children [i].updateLayout (resize, all);
+ }
+ }
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Control.java
new file mode 100644
index 0000000000..b850f1d2cc
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Control.java
@@ -0,0 +1,2977 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.accessibility.*;
+
+/**
+ * Control is the abstract superclass of all windowed user interface classes.
+ * <p>
+ * <dl>
+ * <dt><b>Styles:</b>
+ * <dd>BORDER</dd>
+ * <dd>LEFT_TO_RIGHT, RIGHT_TO_LEFT</dd>
+ * <dt><b>Events:</b>
+ * <dd>FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick, MouseDown, MouseEnter,
+ * MouseExit, MouseHover, MouseUp, MouseMove, Move, Paint, Resize, Traverse,
+ * DragDetect, MenuDetect</dd>
+ * </dl>
+ * </p><p>
+ * Only one of LEFT_TO_RIGHT or RIGHT_TO_LEFT may be specified.
+ * </p><p>
+ * IMPORTANT: This class is intended to be subclassed <em>only</em>
+ * within the SWT implementation.
+ * </p>
+ */
+
+public abstract class Control extends Widget implements Drawable {
+ Cursor cursor;
+ Menu menu;
+ String toolTipText;
+ Object layoutData;
+ Accessible accessible;
+ Image backgroundImage;
+// int drawCount;
+ int foreground, background;
+ Font font;
+ Composite parent;
+
+/**
+ * Prevents uninitialized instances from being created outside the package.
+ */
+Control () {
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#BORDER
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Control (Composite parent, int style) {
+ super (parent, style);
+ this.parent = parent;
+ createWidget ();
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the control is moved or resized, by sending
+ * it one of the messages defined in the <code>ControlListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ControlListener
+ * @see #removeControlListener
+ */
+public void addControlListener(ControlListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Resize,typedListener);
+ addListener (SWT.Move,typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the control gains or loses focus, by sending
+ * it one of the messages defined in the <code>FocusListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see FocusListener
+ * @see #removeFocusListener
+ */
+public void addFocusListener (FocusListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.FocusIn,typedListener);
+ addListener (SWT.FocusOut,typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when help events are generated for the control,
+ * by sending it one of the messages defined in the
+ * <code>HelpListener</code> interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see HelpListener
+ * @see #removeHelpListener
+ */
+public void addHelpListener (HelpListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Help, typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when keys are pressed and released on the system keyboard, by sending
+ * it one of the messages defined in the <code>KeyListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see KeyListener
+ * @see #removeKeyListener
+ */
+public void addKeyListener (KeyListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.KeyUp,typedListener);
+ addListener (SWT.KeyDown,typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when mouse buttons are pressed and released, by sending
+ * it one of the messages defined in the <code>MouseListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see MouseListener
+ * @see #removeMouseListener
+ */
+public void addMouseListener (MouseListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.MouseDown,typedListener);
+ addListener (SWT.MouseUp,typedListener);
+ addListener (SWT.MouseDoubleClick,typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the mouse passes or hovers over controls, by sending
+ * it one of the messages defined in the <code>MouseTrackListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see MouseTrackListener
+ * @see #removeMouseTrackListener
+ */
+public void addMouseTrackListener (MouseTrackListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.MouseEnter,typedListener);
+ addListener (SWT.MouseExit,typedListener);
+ addListener (SWT.MouseHover,typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the mouse moves, by sending it one of the
+ * messages defined in the <code>MouseMoveListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see MouseMoveListener
+ * @see #removeMouseMoveListener
+ */
+public void addMouseMoveListener (MouseMoveListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.MouseMove,typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the receiver needs to be painted, by sending it
+ * one of the messages defined in the <code>PaintListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see PaintListener
+ * @see #removePaintListener
+ */
+public void addPaintListener (PaintListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Paint,typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when traversal events occur, by sending it
+ * one of the messages defined in the <code>TraverseListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see TraverseListener
+ * @see #removeTraverseListener
+ */
+public void addTraverseListener (TraverseListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Traverse,typedListener);
+}
+
+void addWidget () {
+ parent.addChild (this);
+}
+
+int borderHandle () {
+ return handle;
+}
+
+void checkBackground () {
+ Shell shell = getShell ();
+ if (this == shell) return;
+ state &= ~PARENT_BACKGROUND;
+ Composite composite = parent;
+ do {
+ int mode = composite.backgroundMode;
+ if (mode != 0) {
+ if (mode == SWT.INHERIT_DEFAULT) {
+ Control control = this;
+ do {
+ if ((control.state & THEME_BACKGROUND) == 0) {
+ return;
+ }
+ control = control.parent;
+ } while (control != composite);
+ }
+ state |= PARENT_BACKGROUND;
+ return;
+ }
+ if (composite == shell) break;
+ composite = composite.parent;
+ } while (true);
+}
+
+void checkBorder () {
+ if (getBorderWidth () == 0) style &= ~SWT.BORDER;
+}
+
+void checkBuffered () {
+ style &= ~SWT.DOUBLE_BUFFERED;
+}
+
+/**
+ * Returns the preferred size of the receiver.
+ * <p>
+ * The <em>preferred size</em> of a control is the size that it would
+ * best be displayed at. The width hint and height hint arguments
+ * allow the caller to ask a control questions such as "Given a particular
+ * width, how high does the control need to be to show all of the contents?"
+ * To indicate that the caller does not wish to constrain a particular
+ * dimension, the constant <code>SWT.DEFAULT</code> is passed for the hint.
+ * </p>
+ *
+ * @param wHint the width hint (can be <code>SWT.DEFAULT</code>)
+ * @param hHint the height hint (can be <code>SWT.DEFAULT</code>)
+ * @return the preferred size of the control
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Layout
+ * @see #getBorderWidth
+ * @see #getBounds
+ * @see #getSize
+ * @see #pack(boolean)
+ * @see "computeTrim, getClientArea for controls that implement them"
+ */
+public Point computeSize (int wHint, int hHint) {
+ return computeSize (wHint, hHint, true);
+}
+
+/**
+ * Returns the preferred size of the receiver.
+ * <p>
+ * The <em>preferred size</em> of a control is the size that it would
+ * best be displayed at. The width hint and height hint arguments
+ * allow the caller to ask a control questions such as "Given a particular
+ * width, how high does the control need to be to show all of the contents?"
+ * To indicate that the caller does not wish to constrain a particular
+ * dimension, the constant <code>SWT.DEFAULT</code> is passed for the hint.
+ * </p><p>
+ * If the changed flag is <code>true</code>, it indicates that the receiver's
+ * <em>contents</em> have changed, therefore any caches that a layout manager
+ * containing the control may have been keeping need to be flushed. When the
+ * control is resized, the changed flag will be <code>false</code>, so layout
+ * manager caches can be retained.
+ * </p>
+ *
+ * @param wHint the width hint (can be <code>SWT.DEFAULT</code>)
+ * @param hHint the height hint (can be <code>SWT.DEFAULT</code>)
+ * @param changed <code>true</code> if the control's contents have changed, and <code>false</code> otherwise
+ * @return the preferred size of the control.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Layout
+ * @see #getBorderWidth
+ * @see #getBounds
+ * @see #getSize
+ * @see #pack(boolean)
+ * @see "computeTrim, getClientArea for controls that implement them"
+ */
+public Point computeSize (int wHint, int hHint, boolean changed) {
+ checkWidget ();
+ Point size = computeSize (handle, wHint, hHint, changed);
+ int border = getBorderWidth ();
+ int width = size.x + border * 2;
+ int height = size.y + border * 2;
+ return new Point (width, height);
+}
+
+Point computeSize (int handle, int wHint, int hHint, boolean changed) {
+ int width = wHint, height = hHint;
+ if (wHint == SWT.DEFAULT) width = 0x7FFFFFFF;
+ if (hHint == SWT.DEFAULT) height = 0x7FFFFFFF;
+ width = Math.max (0, width);
+ height = Math.max (0, height);
+ int availSize = OS.gcnew_Size ((double)width, (double)height);
+ if (availSize == 0) error (SWT.ERROR_NO_HANDLES);
+ double requestWidth = OS.FrameworkElement_Width (handle);
+ if (requestWidth >= 0) {
+ int widthDP = OS.FrameworkElement_WidthProperty ();
+ OS.DependencyObject_ClearValue (handle, widthDP);
+ OS.GCHandle_Free (widthDP);
+ }
+ double requestHeight = OS.FrameworkElement_Height (handle);
+ if (requestHeight >= 0) {
+ int heightDP = OS.FrameworkElement_HeightProperty ();
+ OS.DependencyObject_ClearValue (handle, heightDP);
+ OS.GCHandle_Free (heightDP);
+ }
+ OS.UIElement_Measure (handle, availSize);
+ OS.GCHandle_Free (availSize);
+ int size = OS.UIElement_DesiredSize (handle);
+ width = (int) OS.Size_Width (size);
+ height = (int) OS.Size_Height (size);
+ OS.GCHandle_Free (size);
+ if (requestWidth >= 0) OS.FrameworkElement_Width (handle, requestWidth);
+ if (requestHeight >= 0) OS.FrameworkElement_Height (handle, requestHeight);
+ if (wHint != SWT.DEFAULT) width = wHint;
+ if (hHint != SWT.DEFAULT) height = hHint;
+ return new Point (width, height);
+}
+
+Control computeTabGroup () {
+ if (isTabGroup ()) return this;
+ return parent.computeTabGroup ();
+}
+
+Control computeTabRoot () {
+ Control [] tabList = parent._getTabList ();
+ if (tabList != null) {
+ int index = 0;
+ while (index < tabList.length) {
+ if (tabList [index] == this) break;
+ index++;
+ }
+ if (index == tabList.length) {
+ if (isTabGroup ()) return this;
+ }
+ }
+ return parent.computeTabRoot ();
+}
+
+Control [] computeTabList () {
+ if (isTabGroup ()) {
+ if (getVisible () && getEnabled ()) {
+ return new Control [] {this};
+ }
+ }
+ return new Control [0];
+}
+
+void createWidget () {
+ checkOrientation (parent);
+ super.createWidget();
+ setClipping ();
+ if (defaultBackground () != 0) {
+ setBackground ();
+ }
+}
+
+void setClipping () {
+ OS.UIElement_ClipToBounds (topHandle(), true);
+}
+
+int defaultBackground () {
+ return 0;
+}
+
+Font defaultFont () {
+ return display.getSystemFont ();
+}
+
+int defaultForeground () {
+ return display.getSystemColor (SWT.COLOR_BLACK).handle;
+}
+
+void deregister () {
+ display.removeWidget (handle);
+}
+
+void destroyWidget () {
+ parent.removeChild (this);
+ releaseHandle ();
+}
+
+boolean drawGripper (int x, int y, int width, int height, boolean vertical) {
+ return false;
+}
+
+Control findBackgroundControl () {
+ if (background != 0 || backgroundImage != null) return this;
+ return (state & PARENT_BACKGROUND) != 0 ? parent.findBackgroundControl () : null;
+}
+
+Control findThemeControl () {
+ return background == 0 && backgroundImage == null ? parent.findThemeControl () : null;
+}
+
+Control findImageControl () {
+ Control control = findBackgroundControl ();
+ return control != null && control.backgroundImage != null ? control : null;
+}
+
+Menu [] findMenus (Control control) {
+ if (menu != null && this != control) return new Menu [] {menu};
+ return new Menu [0];
+}
+
+char findMnemonic (String string) {
+ int index = 0;
+ int length = string.length ();
+ do {
+ while (index < length && string.charAt (index) != '&') index++;
+ if (++index >= length) return '\0';
+ if (string.charAt (index) != '&') return string.charAt (index);
+ index++;
+ } while (index < length);
+ return '\0';
+}
+
+/**
+ * Forces the receiver to have the <em>keyboard focus</em>, causing
+ * all keyboard events to be delivered to it.
+ *
+ * @return <code>true</code> if the control got focus, and <code>false</code> if it was unable to.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #setFocus
+ */
+public boolean forceFocus () {
+ checkWidget ();
+// if (display.focusEvent == SWT.FocusOut) return false;
+// Decorations shell = menuShell ();
+// shell.setSavedFocus (this);
+ if (!isEnabled () || !isVisible () /*|| !isActive ()*/) return false;
+ if (isFocusControl ()) return true;
+// shell.setSavedFocus (null);
+ /*
+ * This code is intentionally commented.
+ *
+ * When setting focus to a control, it is
+ * possible that application code can set
+ * the focus to another control inside of
+ * WM_SETFOCUS. In this case, the original
+ * control will no longer have the focus
+ * and the call to setFocus() will return
+ * false indicating failure.
+ *
+ * We are still working on a solution at
+ * this time.
+ */
+// if (OS.GetFocus () != OS.SetFocus (handle)) return false;
+ OS.UIElement_Focus (handle);
+ if (isDisposed ()) return false;
+// shell.setSavedFocus (this);
+ return isFocusControl ();
+}
+
+/**
+ * Returns the accessible object for the receiver.
+ * If this is the first time this object is requested,
+ * then the object is created and returned.
+ *
+ * @return the accessible object
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Accessible#addAccessibleListener
+ * @see Accessible#addAccessibleControlListener
+ *
+ * @since 2.0
+ */
+public Accessible getAccessible () {
+ checkWidget ();
+ if (accessible == null) accessible = new_Accessible (this);
+ return accessible;
+}
+
+/**
+ * Returns the receiver's background color.
+ *
+ * @return the background color
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Color getBackground () {
+ checkWidget ();
+ Control control = findBackgroundControl ();
+ if (control == null) control = this;
+ return Color.wpf_new (display, control.getBackgroundColor ());
+}
+
+/**
+ * Returns the receiver's background image.
+ *
+ * @return the background image
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public Image getBackgroundImage () {
+ checkWidget ();
+ Control control = findBackgroundControl ();
+ if (control == null) control = this;
+ return control.backgroundImage;
+}
+
+int getBackgroundColor () {
+ int color = background;
+ if (color == 0) color = defaultBackground ();
+ if (color == 0) color = OS.SystemColors_ControlColor;//TODO
+ return color;
+}
+
+/**
+ * Returns the receiver's border width.
+ *
+ * @return the border width
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getBorderWidth () {
+ checkWidget ();
+ return 0;
+}
+
+/**
+ * Returns a rectangle describing the receiver's size and location
+ * relative to its parent (or its display if its parent is null),
+ * unless the receiver is a shell. In this case, the location is
+ * relative to the display.
+ *
+ * @return the receiver's bounding rectangle
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Rectangle getBounds () {
+ checkWidget ();
+ int topHandle = topHandle ();
+ Point location = parent.getLocation (this);
+ int width = (int) OS.FrameworkElement_Width (topHandle);
+ int height = (int) OS.FrameworkElement_Height (topHandle);
+ return new Rectangle (location.x, location.y, width, height);
+}
+
+String getClipboardText () {
+ String string = "";
+ int text = OS.Clipboard_GetText ();
+ if (text != 0) {
+ string = createJavaString (text);
+ OS.GCHandle_Free(text);
+ }
+ return string;
+}
+
+/**
+ * Returns <code>true</code> if the receiver is enabled, and
+ * <code>false</code> otherwise. A disabled control is typically
+ * not selectable from the user interface and draws with an
+ * inactive or "grayed" look.
+ *
+ * @return the receiver's enabled state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #isEnabled
+ */
+public boolean getEnabled () {
+ checkWidget ();
+ return OS.UIElement_IsEnabled (handle);
+}
+
+/**
+ * Returns the font that the receiver will use to paint textual information.
+ *
+ * @return the receiver's font
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Font getFont () {
+ checkWidget ();
+ return font != null ? font : defaultFont ();
+}
+
+/**
+ * Returns the foreground color that the receiver will use to draw.
+ *
+ * @return the receiver's foreground color
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Color getForeground () {
+ checkWidget ();
+ return Color.wpf_new (display, getForegroundColor ());
+}
+
+int getForegroundColor () {
+ return foreground != 0 ? foreground : defaultForeground ();
+}
+
+/**
+ * Returns layout data which is associated with the receiver.
+ *
+ * @return the receiver's layout data
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Object getLayoutData () {
+ checkWidget ();
+ return layoutData;
+}
+
+/**
+ * Returns a point describing the receiver's location relative
+ * to its parent (or its display if its parent is null), unless
+ * the receiver is a shell. In this case, the point is
+ * relative to the display.
+ *
+ * @return the receiver's location
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Point getLocation () {
+ checkWidget ();
+ return parent.getLocation (this);
+}
+
+/**
+ * Returns the receiver's pop up menu if it has one, or null
+ * if it does not. All controls may optionally have a pop up
+ * menu that is displayed when the user requests one for
+ * the control. The sequence of key strokes, button presses
+ * and/or button releases that are used to request a pop up
+ * menu is platform specific.
+ *
+ * @return the receiver's menu
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Menu getMenu () {
+ checkWidget ();
+ return menu;
+}
+
+/**
+ * Returns the receiver's monitor.
+ *
+ * @return the receiver's monitor
+ *
+ * @since 3.0
+ */
+public Monitor getMonitor () {
+ checkWidget ();
+ //TODO
+ return display.getPrimaryMonitor ();
+}
+
+/**
+ * Returns the receiver's parent, which must be a <code>Composite</code>
+ * or null when the receiver is a shell that was created with null or
+ * a display for a parent.
+ *
+ * @return the receiver's parent
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Composite getParent () {
+ checkWidget ();
+ return parent;
+}
+
+Control [] getPath () {
+ int count = 0;
+ Shell shell = getShell ();
+ Control control = this;
+ while (control != shell) {
+ count++;
+ control = control.parent;
+ }
+ control = this;
+ Control [] result = new Control [count];
+ while (control != shell) {
+ result [--count] = control;
+ control = control.parent;
+ }
+ return result;
+}
+
+/**
+ * Returns the receiver's shell. For all controls other than
+ * shells, this simply returns the control's nearest ancestor
+ * shell. Shells return themselves, even if they are children
+ * of other shells.
+ *
+ * @return the receiver's shell
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #getParent
+ */
+public Shell getShell () {
+ checkWidget ();
+ return parent.getShell ();
+}
+
+/**
+ * Returns a point describing the receiver's size. The
+ * x coordinate of the result is the width of the receiver.
+ * The y coordinate of the result is the height of the
+ * receiver.
+ *
+ * @return the receiver's size
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Point getSize () {
+ checkWidget ();
+ int topHandle = topHandle ();
+ int width = (int) OS.FrameworkElement_Width (topHandle);
+ int height = (int) OS.FrameworkElement_Height (topHandle);
+ return new Point (width, height);
+}
+
+/**
+ * Returns the receiver's tool tip text, or null if it has
+ * not been set.
+ *
+ * @return the receiver's tool tip text
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String getToolTipText () {
+ checkWidget ();
+ return toolTipText;
+}
+
+/**
+ * Returns <code>true</code> if the receiver is visible, and
+ * <code>false</code> otherwise.
+ * <p>
+ * If one of the receiver's ancestors is not visible or some
+ * other condition makes the receiver not visible, this method
+ * may still indicate that it is considered visible even though
+ * it may not actually be showing.
+ * </p>
+ *
+ * @return the receiver's visibility state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getVisible () {
+ checkWidget ();
+ return OS.UIElement_Visibility (topHandle ()) == OS.Visibility_Visible;
+}
+
+Control getWidgetControl () {
+ return this;
+}
+
+void hookEvents () {
+ super.hookEvents ();
+ int handler = OS.gcnew_KeyEventHandler (jniRef, "HandleKeyDown");
+ OS.UIElement_KeyDown (handle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_KeyEventHandler (jniRef, "HandleKeyUp");
+ OS.UIElement_KeyUp (handle, handler);
+ OS.GCHandle_Free (handler);
+
+ int topHandle = topHandle ();
+ handler = OS.gcnew_MouseButtonEventHandler (jniRef, "HandlePreviewMouseDown");
+ OS.UIElement_PreviewMouseDown (topHandle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_MouseButtonEventHandler (jniRef, "HandlePreviewMouseUp");
+ OS.UIElement_PreviewMouseUp (topHandle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_MouseEventHandler (jniRef, "HandleMouseEnter");
+ OS.UIElement_MouseEnter (topHandle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_MouseEventHandler (jniRef, "HandleMouseLeave");
+ OS.UIElement_MouseLeave (topHandle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_MouseEventHandler (jniRef, "HandlePreviewMouseMove");
+ OS.UIElement_PreviewMouseMove (topHandle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_MouseWheelEventHandler (jniRef, "HandlePreviewMouseWheel");
+ OS.UIElement_PreviewMouseWheel (topHandle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_TextCompositionEventHandler (jniRef, "HandleTextInput");
+ OS.UIElement_TextInput (topHandle, handler);
+ OS.GCHandle_Free (handler);
+
+ handler = OS.gcnew_KeyboardFocusChangedEventHandler (jniRef, "HandlePreviewGotKeyboardFocus");
+ OS.UIElement_PreviewGotKeyboardFocus(handle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_KeyboardFocusChangedEventHandler (jniRef, "HandlePreviewLostKeyboardFocus");
+ OS.UIElement_PreviewLostKeyboardFocus(handle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_ContextMenuEventHandler (jniRef, "HandleContextMenuOpening");
+ OS.FrameworkElement_ContextMenuOpening(handle, handler);
+ OS.GCHandle_Free (handler);
+}
+
+void HandleContextMenuOpening (int sender, int e) {
+ if (!checkEvent (e)) return;
+ int mouse = OS.Mouse_GetPosition (handle);
+ int mouse2 = OS.Visual_PointToScreen (handle, mouse);
+ int x = (int) OS.Point_X (mouse2);
+ int y = (int) OS.Point_Y (mouse2);
+ OS.GCHandle_Free (mouse);
+ OS.GCHandle_Free (mouse2);
+ showMenu (x, y);
+ OS.RoutedEventArgs_Handled (e, true);
+}
+
+void HandlePreviewGotKeyboardFocus (int sender, int e) {
+ if (!checkEvent (e)) return;
+ sendFocusEvent (SWT.FocusIn);
+}
+
+void HandlePreviewLostKeyboardFocus (int sender, int e) {
+ if (!checkEvent (e)) return;
+ sendFocusEvent (SWT.FocusOut);
+}
+
+void HandleKeyDown (int sender, int e) {
+ if (!checkEvent (e)) return;
+
+ /* Let OS handle mnemonics for now */
+// if (translateMnemonic (e)) {
+// OS.RoutedEventArgs_Handled (e, true);
+// return;
+// }
+ if (translateTraversal (e)) {
+ OS.RoutedEventArgs_Handled (e, true);
+ return;
+ }
+ sendKeyEvent (SWT.KeyDown, e, false);
+
+ //FIXME hack code
+ /*
+ * In WPF arrows key move the focus around, this
+ * behavior is not expected in SWT.
+ */
+ int key = OS.KeyEventArgs_Key(e);
+ switch (key) {
+ case OS.Key_Up:
+ case OS.Key_Left:
+ case OS.Key_Down:
+ case OS.Key_Right: {
+ OS.RoutedEventArgs_Handled (e, true);
+ }
+ }
+}
+
+void HandleKeyUp (int sender, int e) {
+ if (!checkEvent (e)) return;
+ sendKeyEvent (SWT.KeyUp, e, false);
+}
+
+void HandlePreviewMouseDown (int sender, int e) {
+ if (!checkEvent (e)) return;
+ if ((state & CANVAS) != 0) {
+ OS.UIElement_CaptureMouse (handle);
+ }
+ sendMouseEvent (SWT.MouseDown, e, false);
+}
+
+void HandlePreviewMouseUp (int sender, int e) {
+ if (!checkEvent (e)) return;
+ if ((state & CANVAS) != 0) {
+ OS.UIElement_ReleaseMouseCapture (handle);
+ }
+ sendMouseEvent (SWT.MouseUp, e, false);
+}
+
+void HandleMouseEnter (int sender, int e) {
+ if (!checkEvent (e)) return;
+ sendMouseEvent (SWT.MouseEnter, e, false);
+}
+
+void HandleMouseLeave (int sender, int e) {
+ if (!checkEvent (e)) return;
+ sendMouseEvent (SWT.MouseExit, e, false);
+}
+
+void HandlePreviewMouseMove (int sender, int e) {
+ if (!checkEvent (e)) return;
+ sendMouseEvent (SWT.MouseMove, e, false);
+}
+
+void HandlePreviewMouseWheel (int sender, int e) {
+ if (!checkEvent (e)) return;
+ sendMouseEvent (SWT.MouseWheel, e, false);
+}
+
+void HandleTextInput(int sender, int e) {
+ if (!checkEvent (e)) return;
+ sendKeyEvent (SWT.KeyDown, e, true);
+}
+
+boolean hasFocus () {
+// /*
+// * If a non-SWT child of the control has focus,
+// * then this control is considered to have focus
+// * even though it does not have focus in Windows.
+// */
+// int hwndFocus = OS.GetFocus ();
+// while (hwndFocus != 0) {
+// if (hwndFocus == handle) return true;
+// if (display.getControl (hwndFocus) != null) {
+// return false;
+// }
+// hwndFocus = OS.GetParent (hwndFocus);
+// }
+// return false;
+
+// return OS.UIElement_IsFocused (handle);
+ return OS.UIElement_IsKeyboardFocused (handle);
+}
+
+/**
+ * Invokes platform specific functionality to allocate a new GC handle.
+ * <p>
+ * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
+ * API for <code>Control</code>. It is marked public only so that it
+ * can be shared within the packages provided by SWT. It is not
+ * available on all platforms, and should never be called from
+ * application code.
+ * </p>
+ *
+ * @param data the platform specific GC data
+ * @return the platform specific GC handle
+ */
+public int internal_new_GC (GCData data) {
+ checkWidget();
+ int drawingContext = data != null ? data.drawingContext : 0;
+ int visual = handle;
+ double width = OS.FrameworkElement_ActualWidth (handle);
+ double height = OS.FrameworkElement_ActualHeight (handle);
+ int rect = OS.gcnew_Rect (0, 0, width, height);
+ int clip = OS.gcnew_RectangleGeometry (rect);
+ if (drawingContext != 0) {
+ OS.DrawingContext_PushClip(drawingContext, clip);
+ } else {
+ visual = OS.gcnew_DrawingVisual();
+ if (visual == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+ OS.ContainerVisual_Clip (visual, clip);
+ int dc = OS.DrawingVisual_RenderOpen (visual);
+ if (dc == 0) SWT.error (SWT.ERROR_NO_HANDLES);
+ if ((state & CANVAS) != 0) {
+ OS.SWTCanvas_Visual (handle, visual);
+ }
+ drawingContext = dc;
+ }
+ OS.GCHandle_Free (rect);
+ OS.GCHandle_Free (clip);
+ if (data != null) {
+ int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
+ if ((data.style & mask) == 0) {
+ data.style |= style & (mask | SWT.MIRRORED);
+ }
+ data.device = display;
+ data.foreground = getForegroundColor ();
+ Control control = findBackgroundControl ();
+ if (control == null) control = this;
+ data.background = control.getBackgroundColor ();
+ data.font = font != null ? font : defaultFont ();
+ data.visual = visual;
+ }
+ return drawingContext;
+}
+
+/**
+ * Invokes platform specific functionality to dispose a GC handle.
+ * <p>
+ * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
+ * API for <code>Control</code>. It is marked public only so that it
+ * can be shared within the packages provided by SWT. It is not
+ * available on all platforms, and should never be called from
+ * application code.
+ * </p>
+ *
+ * @param hDC the platform specific GC handle
+ * @param data the platform specific GC data
+ */
+public void internal_dispose_GC (int dc, GCData data) {
+ checkWidget ();
+ if (data != null && data.drawingContext == 0) {
+ OS.DrawingContext_Close (dc);
+ OS.GCHandle_Free (dc);
+ OS.GCHandle_Free (data.visual);
+ }
+}
+
+boolean isActive () {
+ Shell dialogShell = display.getModalDialogShell ();
+ if (dialogShell != null && dialogShell != getShell ()) {
+ return false;
+ }
+ Shell shell = null;
+ Shell [] modalShells = display.modalShells;
+ if (modalShells != null) {
+ int bits = SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL;
+ int index = modalShells.length;
+ while (--index >= 0) {
+ Shell modal = modalShells [index];
+ if (modal != null) {
+ if ((modal.style & bits) != 0) {
+ Control control = this;
+ while (control != null) {
+ if (control == modal) break;
+ control = control.parent;
+ }
+ if (control != modal) return false;
+ break;
+ }
+ if ((modal.style & SWT.PRIMARY_MODAL) != 0) {
+ if (shell == null) shell = getShell ();
+ if (modal.parent == shell) return false;
+ }
+ }
+ }
+ }
+ if (shell == null) shell = getShell ();
+ return shell.getEnabled ();
+}
+
+/**
+ * Returns <code>true</code> if the receiver is enabled and all
+ * ancestors up to and including the receiver's nearest ancestor
+ * shell are enabled. Otherwise, <code>false</code> is returned.
+ * A disabled control is typically not selectable from the user
+ * interface and draws with an inactive or "grayed" look.
+ *
+ * @return the receiver's enabled state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #getEnabled
+ */
+public boolean isEnabled () {
+ checkWidget ();
+ return getEnabled () && parent.isEnabled ();
+}
+
+/**
+ * Returns <code>true</code> if the receiver has the user-interface
+ * focus, and <code>false</code> otherwise.
+ *
+ * @return the receiver's focus state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean isFocusControl () {
+ checkWidget ();
+// Control focusControl = display.focusControl;
+// if (focusControl != null && !focusControl.isDisposed ()) {
+// return this == focusControl;
+// }
+ return hasFocus ();
+}
+
+boolean isFocusAncestor (Control control) {
+ while (control != null && control != this) {
+ control = control.parent;
+ }
+ return control == this;
+}
+
+/**
+ * Returns <code>true</code> if the underlying operating
+ * system supports this reparenting, otherwise <code>false</code>
+ *
+ * @return <code>true</code> if the widget can be reparented, otherwise <code>false</code>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean isReparentable () {
+ checkWidget ();
+ return false;
+}
+
+boolean isShowing () {
+ /*
+ * This is not complete. Need to check if the
+ * widget is obscurred by a parent or sibling.
+ */
+ if (!isVisible ()) return false;
+ Control control = this;
+ while (control != null) {
+ Point size = control.getSize ();
+ if (size.x == 0 || size.y == 0) {
+ return false;
+ }
+ control = control.parent;
+ }
+ return true;
+ /*
+ * Check to see if current damage is included.
+ */
+// if (!OS.IsWindowVisible (handle)) return false;
+// int flags = OS.DCX_CACHE | OS.DCX_CLIPCHILDREN | OS.DCX_CLIPSIBLINGS;
+// int hDC = OS.GetDCEx (handle, 0, flags);
+// int result = OS.GetClipBox (hDC, new RECT ());
+// OS.ReleaseDC (handle, hDC);
+// return result != OS.NULLREGION;
+}
+
+boolean isTabGroup () {
+ Control [] tabList = parent._getTabList ();
+ if (tabList != null) {
+ for (int i=0; i<tabList.length; i++) {
+ if (tabList [i] == this) return true;
+ }
+ }
+ int code = traversalCode (0, 0);
+ if ((code & (SWT.TRAVERSE_ARROW_PREVIOUS | SWT.TRAVERSE_ARROW_NEXT)) != 0) return false;
+ return (code & (SWT.TRAVERSE_TAB_PREVIOUS | SWT.TRAVERSE_TAB_NEXT)) != 0;
+}
+
+boolean isTabItem () {
+ Control [] tabList = parent._getTabList ();
+ if (tabList != null) {
+ for (int i=0; i<tabList.length; i++) {
+ if (tabList [i] == this) return false;
+ }
+ }
+ int code = traversalCode (0, 0);
+ return (code & (SWT.TRAVERSE_ARROW_PREVIOUS | SWT.TRAVERSE_ARROW_NEXT)) != 0;
+}
+
+/**
+ * Returns <code>true</code> if the receiver is visible and all
+ * ancestors up to and including the receiver's nearest ancestor
+ * shell are visible. Otherwise, <code>false</code> is returned.
+ *
+ * @return the receiver's visibility state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #getVisible
+ */
+public boolean isVisible () {
+ checkWidget ();
+ return OS.UIElement_IsVisible (topHandle ());
+}
+
+void markLayout (boolean changed, boolean all) {
+ /* Do nothing */
+}
+
+Decorations menuShell () {
+ return parent.menuShell ();
+}
+
+boolean mnemonicHit (char key) {
+ return false;
+}
+
+boolean mnemonicMatch (char key) {
+ return false;
+}
+
+/**
+ * Moves the receiver above the specified control in the
+ * drawing order. If the argument is null, then the receiver
+ * is moved to the top of the drawing order. The control at
+ * the top of the drawing order will not be covered by other
+ * controls even if they occupy intersecting areas.
+ *
+ * @param control the sibling control (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Control#moveBelow
+ * @see Composite#getChildren
+ */
+public void moveAbove (Control control) {
+ checkWidget ();
+ if (control != null) {
+ if (control.isDisposed ()) error(SWT.ERROR_INVALID_ARGUMENT);
+ if (parent != control.parent) return;
+ }
+ int index;
+ int parentHandle = parent.handle;
+ int children = OS.Panel_Children (parentHandle);
+ if (control != null) {
+ index = OS.UIElementCollection_IndexOf (children, control.topHandle ());
+ } else {
+ index = OS.UIElementCollection_Count (children) - 1;
+ }
+ int topHandle = topHandle ();
+ OS.UIElementCollection_Remove (children, topHandle);
+ OS.UIElementCollection_Insert (children, index, topHandle);
+ OS.GCHandle_Free (children);
+}
+
+/**
+ * Moves the receiver below the specified control in the
+ * drawing order. If the argument is null, then the receiver
+ * is moved to the bottom of the drawing order. The control at
+ * the bottom of the drawing order will be covered by all other
+ * controls which occupy intersecting areas.
+ *
+ * @param control the sibling control (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Control#moveAbove
+ * @see Composite#getChildren
+ */
+public void moveBelow (Control control) {
+ checkWidget ();
+ if (control != null) {
+ if (control.isDisposed ()) error(SWT.ERROR_INVALID_ARGUMENT);
+ if (parent != control.parent) return;
+ }
+ int index;
+ int parentHandle = parent.handle;
+ int children = OS.Panel_Children (parentHandle);
+ if (control != null) {
+ index = Math.max (0, OS.UIElementCollection_IndexOf (children, control.topHandle ()) - 1);
+ } else {
+ index = 0;
+ }
+ int topHandle = topHandle ();
+ OS.UIElementCollection_Remove (children, topHandle);
+ OS.UIElementCollection_Insert (children, index, topHandle);
+ OS.GCHandle_Free (children);
+}
+
+Accessible new_Accessible (Control control) {
+ return Accessible.internal_new_Accessible (this);
+}
+
+/**
+ * Causes the receiver to be resized to its preferred size.
+ * For a composite, this involves computing the preferred size
+ * from its layout, if there is one.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #computeSize(int, int, boolean)
+ */
+public void pack () {
+ checkWidget ();
+ pack (true);
+}
+
+/**
+ * Causes the receiver to be resized to its preferred size.
+ * For a composite, this involves computing the preferred size
+ * from its layout, if there is one.
+ * <p>
+ * If the changed flag is <code>true</code>, it indicates that the receiver's
+ * <em>contents</em> have changed, therefore any caches that a layout manager
+ * containing the control may have been keeping need to be flushed. When the
+ * control is resized, the changed flag will be <code>false</code>, so layout
+ * manager caches can be retained.
+ * </p>
+ *
+ * @param changed whether or not the receiver's contents have changed
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #computeSize(int, int, boolean)
+ */
+public void pack (boolean changed) {
+ checkWidget ();
+ setSize (computeSize (SWT.DEFAULT, SWT.DEFAULT, changed));
+}
+
+/**
+ * Causes the entire bounds of the receiver to be marked
+ * as needing to be redrawn. The next time a paint request
+ * is processed, the control will be completely painted,
+ * including the background.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #update
+ * @see PaintListener
+ * @see SWT#Paint
+ * @see SWT#NO_BACKGROUND
+ * @see SWT#NO_REDRAW_RESIZE
+ * @see SWT#NO_MERGE_PAINTS
+ * @see SWT#DOUBLE_BUFFERED
+ */
+public void redraw () {
+ checkWidget ();
+ redraw (false);
+}
+
+void redraw (boolean all) {
+// checkWidget ();
+ //TODO InvalidateVisual invalidates the entire visual tree
+ OS.UIElement_InvalidateVisual (topHandle ());
+ OS.UIElement_InvalidateVisual (handle);
+}
+
+/**
+ * Causes the rectangular area of the receiver specified by
+ * the arguments to be marked as needing to be redrawn.
+ * The next time a paint request is processed, that area of
+ * the receiver will be painted, including the background.
+ * If the <code>all</code> flag is <code>true</code>, any
+ * children of the receiver which intersect with the specified
+ * area will also paint their intersecting areas. If the
+ * <code>all</code> flag is <code>false</code>, the children
+ * will not be painted.
+ *
+ * @param x the x coordinate of the area to draw
+ * @param y the y coordinate of the area to draw
+ * @param width the width of the area to draw
+ * @param height the height of the area to draw
+ * @param all <code>true</code> if children should redraw, and <code>false</code> otherwise
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #update
+ * @see PaintListener
+ * @see SWT#Paint
+ * @see SWT#NO_BACKGROUND
+ * @see SWT#NO_REDRAW_RESIZE
+ * @see SWT#NO_MERGE_PAINTS
+ * @see SWT#DOUBLE_BUFFERED
+ */
+public void redraw (int x, int y, int width, int height, boolean all) {
+ checkWidget ();
+ if (width <= 0 || height <= 0) return;
+ //TODO redraw only rect
+ redraw(true);
+}
+
+void register () {
+ display.addWidget (handle, this);
+}
+
+void releaseHandle () {
+ super.releaseHandle ();
+ if (handle != 0) OS.GCHandle_Free (handle);
+ handle = 0;
+ parent = null;
+}
+
+void releaseParent () {
+ parent.removeControl (this);
+}
+
+void releaseWidget () {
+ super.releaseWidget ();
+// if (toolTipText != null) {
+// setToolTipText (getShell (), null);
+// }
+ toolTipText = null;
+ if (menu != null && !menu.isDisposed ()) {
+ menu.dispose ();
+ }
+ menu = null;
+ cursor = null;
+ deregister ();
+ layoutData = null;
+ if (accessible != null) {
+ accessible.internal_dispose_Accessible ();
+ }
+ accessible = null;
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the control is moved or resized.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ControlListener
+ * @see #addControlListener
+ */
+public void removeControlListener (ControlListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Move, listener);
+ eventTable.unhook (SWT.Resize, listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the control gains or loses focus.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see FocusListener
+ * @see #addFocusListener
+ */
+public void removeFocusListener(FocusListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.FocusIn, listener);
+ eventTable.unhook (SWT.FocusOut, listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the help events are generated for the control.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see HelpListener
+ * @see #addHelpListener
+ */
+public void removeHelpListener (HelpListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Help, listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when keys are pressed and released on the system keyboard.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see KeyListener
+ * @see #addKeyListener
+ */
+public void removeKeyListener(KeyListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.KeyUp, listener);
+ eventTable.unhook (SWT.KeyDown, listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the mouse passes or hovers over controls.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see MouseTrackListener
+ * @see #addMouseTrackListener
+ */
+public void removeMouseTrackListener(MouseTrackListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.MouseEnter, listener);
+ eventTable.unhook (SWT.MouseExit, listener);
+ eventTable.unhook (SWT.MouseHover, listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when mouse buttons are pressed and released.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see MouseListener
+ * @see #addMouseListener
+ */
+public void removeMouseListener (MouseListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.MouseDown, listener);
+ eventTable.unhook (SWT.MouseUp, listener);
+ eventTable.unhook (SWT.MouseDoubleClick, listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the mouse moves.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see MouseMoveListener
+ * @see #addMouseMoveListener
+ */
+public void removeMouseMoveListener(MouseMoveListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.MouseMove, listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the receiver needs to be painted.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see PaintListener
+ * @see #addPaintListener
+ */
+public void removePaintListener(PaintListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook(SWT.Paint, listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when traversal events occur.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see TraverseListener
+ * @see #addTraverseListener
+ */
+public void removeTraverseListener(TraverseListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Traverse, listener);
+}
+
+boolean sendFocusEvent (int type) {
+ Shell shell = getShell ();
+
+ Display display = this.display;
+ sendEvent (type);
+
+ /*
+ * It is possible that the shell may be
+ * disposed at this point. If this happens
+ * don't send the activate and deactivate
+ * events.
+ */
+ if (!shell.isDisposed ()) {
+ switch (type) {
+ case SWT.FocusIn:
+ shell.setActiveControl (this);
+ break;
+ case SWT.FocusOut:
+ if (shell != display.getActiveShell ()) {
+ shell.setActiveControl (null);
+ }
+ break;
+ }
+ }
+ return true;
+}
+
+/**
+ * Sets the receiver's background color to the color specified
+ * by the argument, or to the default system color for the control
+ * if the argument is null.
+ *
+ * @param color the new color (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setBackground (Color color) {
+ checkWidget ();
+ if (color != null) {
+ if (color.isDisposed ()) SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+ if (background != 0 && OS.Object_Equals (color.handle, background)) return;
+ background = color.handle;
+ } else {
+ if (background == 0) return;
+ background = 0;
+ }
+ setBackground ();
+// updateBackgroundColor ();
+}
+
+int backgroundHandle () {
+ return handle;
+}
+
+int backgroundProperty () {
+ return OS.Control_BackgroundProperty ();
+}
+
+void setBackground () {
+ int backgroundHandle = backgroundHandle ();
+ int property = backgroundProperty ();
+ int brush = 0;
+ if (backgroundImage != null) {
+ brush = OS.gcnew_ImageBrush (backgroundImage.handle);
+ OS.TileBrush_TileMode (brush, OS.TileMode_Tile);//FIXME NOT WORKING
+ } else {
+ //TODO verify parent backgroundMode
+ int color = background;
+ if (color == 0) {
+ color = defaultBackground ();
+ if ((state & THEME_BACKGROUND) != 0) {
+ Control themeControl = findThemeControl ();
+ if (themeControl != null) {
+ if (color != 0) {
+ /*
+ * Feature in WPF. If the control does not have a background
+ * brush it does not receive input events.
+ * The fix is to set a transparent background.
+ */
+ color = OS.Colors_Transparent;
+ }
+ }
+ }
+ }
+ if (color != 0) {
+ brush = OS.gcnew_SolidColorBrush (color);
+ }
+ }
+ if (brush != 0) {
+ OS.DependencyObject_SetValue (backgroundHandle, property, brush);
+ OS.GCHandle_Free (brush);
+ } else {
+ OS.DependencyObject_ClearValue (backgroundHandle, property);
+ }
+ OS.GCHandle_Free (property);
+}
+
+/**
+ * Sets the receiver's background image to the image specified
+ * by the argument, or to the default system color for the control
+ * if the argument is null. The background image is tiled to fill
+ * the available space.
+ *
+ * @param image the new image (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument is not a bitmap</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public void setBackgroundImage (Image image) {
+ checkWidget ();
+ if (image != null) {
+ if (image.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (image.type != SWT.BITMAP) error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+ if (backgroundImage == image) return;
+ backgroundImage = image;
+ setBackground ();
+}
+
+/**
+ * Sets the receiver's size and location to the rectangular
+ * area specified by the arguments. The <code>x</code> and
+ * <code>y</code> arguments are relative to the receiver's
+ * parent (or its display if its parent is null), unless
+ * the receiver is a shell. In this case, the <code>x</code>
+ * and <code>y</code> arguments are relative to the display.
+ * <p>
+ * Note: Attempting to set the width or height of the
+ * receiver to a negative number will cause that
+ * value to be set to zero instead.
+ * </p>
+ *
+ * @param x the new x coordinate for the receiver
+ * @param y the new y coordinate for the receiver
+ * @param width the new width for the receiver
+ * @param height the new height for the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setBounds (int x, int y, int width, int height) {
+ checkWidget ();
+ int flags = MOVED | RESIZED;
+ setBounds (x, y, Math.max (0, width), Math.max (0, height), flags);
+}
+
+int setBounds (int x, int y, int width, int height, int flags) {
+ int result = 0;
+ int topHandle = topHandle ();
+ if ((flags & MOVED) != 0) {
+ int oldX = (int) OS.Canvas_GetLeft (topHandle);
+ int oldY = (int) OS.Canvas_GetTop (topHandle);
+ if (oldX != x) OS.Canvas_SetLeft (topHandle, x);
+ if (oldY != y) OS.Canvas_SetTop (topHandle, y);
+ if (oldX != x || oldY != y) {
+ sendEvent (SWT.Move);
+ if (isDisposed ()) return 0;
+ result |= MOVED;
+ }
+ }
+ if ((flags & RESIZED) != 0) {
+ int oldWidth = (int) OS.FrameworkElement_Width (topHandle);
+ int oldHeight = (int) OS.FrameworkElement_Height (topHandle);
+ if (oldWidth != width) OS.FrameworkElement_Width (topHandle, width);
+ if (oldHeight != height) OS.FrameworkElement_Height (topHandle, height);
+ if (oldWidth != width || oldHeight != height) {
+ sendEvent (SWT.Resize);
+ if (isDisposed ()) return 0;
+ result |= RESIZED;
+ }
+ }
+ return result;
+}
+
+/**
+ * Sets the receiver's size and location to the rectangular
+ * area specified by the argument. The <code>x</code> and
+ * <code>y</code> fields of the rectangle are relative to
+ * the receiver's parent (or its display if its parent is null).
+ * <p>
+ * Note: Attempting to set the width or height of the
+ * receiver to a negative number will cause that
+ * value to be set to zero instead.
+ * </p>
+ *
+ * @param rect the new bounds for the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setBounds (Rectangle rect) {
+ checkWidget ();
+ if (rect == null) error (SWT.ERROR_NULL_ARGUMENT);
+ setBounds (rect.x, rect.y, rect.width, rect.height);
+}
+
+/**
+ * If the argument is <code>true</code>, causes the receiver to have
+ * all mouse events delivered to it until the method is called with
+ * <code>false</code> as the argument.
+ *
+ * @param capture <code>true</code> to capture the mouse, and <code>false</code> to release it
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setCapture (boolean capture) {
+ checkWidget ();
+ if (capture) {
+ OS.UIElement_CaptureMouse (handle);
+ } else {
+ OS.UIElement_ReleaseMouseCapture (handle);
+ }
+}
+
+/**
+ * Sets the receiver's cursor to the cursor specified by the
+ * argument, or to the default cursor for that kind of control
+ * if the argument is null.
+ * <p>
+ * When the mouse pointer passes over a control its appearance
+ * is changed to match the control's cursor.
+ * </p>
+ *
+ * @param cursor the new cursor (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setCursor (Cursor cursor) {
+ checkWidget ();
+ if (cursor != null && cursor.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ this.cursor = cursor;
+ if (cursor != null) {
+ OS.FrameworkElement_Cursor (handle, cursor.handle);
+ } else {
+ int property = OS.FrameworkElement_CursorProperty ();
+ OS.DependencyObject_ClearValue (handle, property);
+ OS.GCHandle_Free (property);
+ }
+}
+
+/**
+ * Enables the receiver if the argument is <code>true</code>,
+ * and disables it otherwise. A disabled control is typically
+ * not selectable from the user interface and draws with an
+ * inactive or "grayed" look.
+ *
+ * @param enabled the new enabled state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setEnabled (boolean enabled) {
+ checkWidget ();
+ if (OS.UIElement_IsEnabled (handle) == enabled) return;
+// /*
+// * Feature in Windows. If the receiver has focus, disabling
+// * the receiver causes no window to have focus. The fix is
+// * to assign focus to the first ancestor window that takes
+// * focus. If no window will take focus, set focus to the
+// * desktop.
+// */
+// Control control = null;
+// boolean fixFocus = false;
+// if (!enabled) {
+//// if (display.focusEvent != SWT.FocusOut) {
+// control = display.getFocusControl ();
+// fixFocus = isFocusAncestor (control);
+//// }
+// }
+ OS.UIElement_IsEnabled (handle, enabled);
+// if (fixFocus) fixFocus (control);
+}
+
+boolean setFixedFocus () {
+ if ((style & SWT.NO_FOCUS) != 0) return false;
+ return forceFocus ();
+}
+
+/**
+ * Causes the receiver to have the <em>keyboard focus</em>,
+ * such that all keyboard events will be delivered to it. Focus
+ * reassignment will respect applicable platform constraints.
+ *
+ * @return <code>true</code> if the control got focus, and <code>false</code> if it was unable to.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #forceFocus
+ */
+public boolean setFocus () {
+ checkWidget ();
+ if ((style & SWT.NO_FOCUS) != 0) return false;
+ return forceFocus ();
+}
+
+/**
+ * Sets the font that the receiver will use to paint textual information
+ * to the font specified by the argument, or to the default font for that
+ * kind of control if the argument is null.
+ *
+ * @param font the new font (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setFont (Font font) {
+ checkWidget ();
+ if (font != null) {
+ if (font.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ this.font = font;
+ if (font == null) font = defaultFont();
+ setFont (font.handle, font.size);
+}
+
+void setFont (int font, double size) {
+ if (font != 0) {
+ int fontFamily = OS.Typeface_FontFamily( font);
+ int style = OS.Typeface_Style (font);
+ int weight = OS.Typeface_Weight (font);
+ int stretch = OS.Typeface_Stretch (font);
+ OS.Control_FontFamily (handle, fontFamily);
+ OS.Control_FontStyle (handle, style);
+ OS.Control_FontWeight (handle, weight);
+ OS.Control_FontStretch (handle, stretch);
+ OS.Control_FontSize (handle, size);
+ OS.GCHandle_Free (fontFamily);
+ OS.GCHandle_Free (style);
+ OS.GCHandle_Free (weight);
+ OS.GCHandle_Free (stretch);
+ } else {
+ int property = OS.Control_FontFamilyProperty ();
+ OS.DependencyObject_ClearValue (handle, property);
+ OS.GCHandle_Free (property);
+ property = OS.Control_FontStyleProperty ();
+ OS.DependencyObject_ClearValue (handle, property);
+ OS.GCHandle_Free (property);
+ property = OS.Control_FontWeightProperty ();
+ OS.DependencyObject_ClearValue (handle, property);
+ OS.GCHandle_Free (property);
+ property = OS.Control_FontStretchProperty ();
+ OS.DependencyObject_ClearValue (handle, property);
+ OS.GCHandle_Free (property);
+ property = OS.Control_FontSizeProperty ();
+ OS.DependencyObject_ClearValue (handle, property);
+ OS.GCHandle_Free (property);
+ }
+}
+
+/**
+ * Sets the receiver's foreground color to the color specified
+ * by the argument, or to the default system color for the control
+ * if the argument is null.
+ *
+ * @param color the new color (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setForeground (Color color) {
+ checkWidget ();
+ int brush = 0;
+ if (color != null) {
+ if (color.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ if (foreground != 0 && OS.Object_Equals (color.handle, foreground)) return;
+ foreground = color.handle;
+ brush = OS.gcnew_SolidColorBrush (foreground);
+ } else {
+ if (foreground == 0) return;
+ foreground = 0;
+ }
+ setForegroundBrush (brush);
+ if (brush != 0) OS.GCHandle_Free (brush);
+}
+
+void setForegroundBrush (int brush) {
+ if (brush != 0) {
+ OS.Control_Foreground (handle, brush);
+ } else {
+ int property = OS.Control_ForegroundProperty ();
+ OS.DependencyObject_ClearValue (handle, property);
+ OS.GCHandle_Free (property);
+ }
+}
+
+/**
+ * Sets the layout data associated with the receiver to the argument.
+ *
+ * @param layoutData the new layout data for the receiver.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setLayoutData (Object layoutData) {
+ checkWidget ();
+ this.layoutData = layoutData;
+}
+
+/**
+ * Sets the receiver's location to the point specified by
+ * the arguments which are relative to the receiver's
+ * parent (or its display if its parent is null), unless
+ * the receiver is a shell. In this case, the point is
+ * relative to the display.
+ *
+ * @param x the new x coordinate for the receiver
+ * @param y the new y coordinate for the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setLocation (int x, int y) {
+ checkWidget ();
+ int flags = MOVED;
+ setBounds (x, y, 0, 0, flags);
+}
+
+/**
+ * Sets the receiver's location to the point specified by
+ * the arguments which are relative to the receiver's
+ * parent (or its display if its parent is null), unless
+ * the receiver is a shell. In this case, the point is
+ * relative to the display.
+ *
+ * @param location the new location for the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setLocation (Point location) {
+ checkWidget ();
+ if (location == null) error (SWT.ERROR_NULL_ARGUMENT);
+ setLocation (location.x, location.y);
+}
+
+/**
+ * Sets the receiver's pop up menu to the argument.
+ * All controls may optionally have a pop up
+ * menu that is displayed when the user requests one for
+ * the control. The sequence of key strokes, button presses
+ * and/or button releases that are used to request a pop up
+ * menu is platform specific.
+ * <p>
+ * Note: Disposing of a control that has a pop up menu will
+ * dispose of the menu. To avoid this behavior, set the
+ * menu to null before the control is disposed.
+ * </p>
+ *
+ * @param menu the new pop up menu
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_MENU_NOT_POP_UP - the menu is not a pop up menu</li>
+ * <li>ERROR_INVALID_PARENT - if the menu is not in the same widget tree</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the menu has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setMenu (Menu menu) {
+ checkWidget ();
+ if (menu != null) {
+ if (menu.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ if ((menu.style & SWT.POP_UP) == 0) {
+ error (SWT.ERROR_MENU_NOT_POP_UP);
+ }
+ if (menu.parent != menuShell ()) {
+ error (SWT.ERROR_INVALID_PARENT);
+ }
+ }
+ this.menu = menu;
+ OS.FrameworkElement_ContextMenu(handle, menu != null ? menu.handle : 0);
+}
+
+boolean setRadioFocus () {
+ return false;
+}
+
+boolean setRadioSelection (boolean value) {
+ return false;
+}
+
+/**
+ * If the argument is <code>false</code>, causes subsequent drawing
+ * operations in the receiver to be ignored. No drawing of any kind
+ * can occur in the receiver until the flag is set to true.
+ * Graphics operations that occurred while the flag was
+ * <code>false</code> are lost. When the flag is set to <code>true</code>,
+ * the entire widget is marked as needing to be redrawn. Nested calls
+ * to this method are stacked.
+ * <p>
+ * Note: This operation is a hint and may not be supported on some
+ * platforms or for some widgets.
+ * </p>
+ *
+ * @param redraw the new redraw state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #redraw(int, int, int, int, boolean)
+ * @see #update
+ */
+public void setRedraw (boolean redraw) {
+ checkWidget ();
+ /*
+ * Feature in Windows. When WM_SETREDRAW is used to turn
+ * off drawing in a widget, it clears the WS_VISIBLE bits
+ * and then sets them when redraw is turned back on. This
+ * means that WM_SETREDRAW will make a widget unexpectedly
+ * visible. The fix is to track the visibility state while
+ * drawing is turned off and restore it when drawing is
+ * turned back on.
+ */
+// if (drawCount == 0) {
+// int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
+// if ((bits & OS.WS_VISIBLE) == 0) state |= HIDDEN;
+// }
+// if (redraw) {
+// if (--drawCount == 0) {
+// OS.SendMessage (handle, OS.WM_SETREDRAW, 1, 0);
+// if ((state & HIDDEN) != 0) {
+// state &= ~HIDDEN;
+// OS.ShowWindow (handle, OS.SW_HIDE);
+// } else {
+// if (OS.IsWinCE) {
+// OS.InvalidateRect (handle, null, true);
+// } else {
+// int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE | OS.RDW_ALLCHILDREN;
+// OS.RedrawWindow (handle, null, 0, flags);
+// }
+// }
+// }
+// } else {
+// if (drawCount++ == 0) {
+// OS.SendMessage (handle, OS.WM_SETREDRAW, 0, 0);
+// }
+// }
+ redraw ();
+}
+
+boolean setSavedFocus () {
+ return forceFocus ();
+}
+
+/**
+ * Sets the receiver's size to the point specified by the arguments.
+ * <p>
+ * Note: Attempting to set the width or height of the
+ * receiver to a negative number will cause that
+ * value to be set to zero instead.
+ * </p>
+ *
+ * @param width the new width for the receiver
+ * @param height the new height for the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSize (int width, int height) {
+ checkWidget ();
+ int flags = RESIZED;
+ setBounds (0, 0, Math.max (0, width), Math.max (0, height), flags);
+}
+
+/**
+ * Sets the receiver's size to the point specified by the argument.
+ * <p>
+ * Note: Attempting to set the width or height of the
+ * receiver to a negative number will cause them to be
+ * set to zero instead.
+ * </p>
+ *
+ * @param size the new size for the receiver
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSize (Point size) {
+ checkWidget ();
+ if (size == null) error (SWT.ERROR_NULL_ARGUMENT);
+ setSize (size.x, size.y);
+}
+
+boolean setTabGroupFocus () {
+ return setTabItemFocus ();
+}
+
+boolean setTabItemFocus () {
+ if (!isShowing ()) return false;
+ return forceFocus ();
+}
+
+/**
+ * Sets the receiver's tool tip text to the argument, which
+ * may be null indicating that no tool tip text should be shown.
+ *
+ * @param string the new tool tip text (or null)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setToolTipText (String string) {
+ checkWidget ();
+ toolTipText = string;
+ int strPtr = createDotNetString (string, false);
+ OS.FrameworkElement_ToolTip (handle, strPtr);
+ if (strPtr != 0) OS.GCHandle_Free (strPtr);
+}
+
+/**
+ * Marks the receiver as visible if the argument is <code>true</code>,
+ * and marks it invisible otherwise.
+ * <p>
+ * If one of the receiver's ancestors is not visible or some
+ * other condition makes the receiver not visible, marking
+ * it visible may not actually cause it to be displayed.
+ * </p>
+ *
+ * @param visible the new visibility state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setVisible (boolean visible) {
+ checkWidget ();
+ int topHandle = topHandle ();
+ if ((OS.UIElement_Visibility (topHandle) == OS.Visibility_Visible) == visible) return;
+ if (visible) {
+ sendEvent (SWT.Show);
+ if (isDisposed ()) return;
+ }
+
+ /*
+ * Feature in Windows. If the receiver has focus, hiding
+ * the receiver causes no window to have focus. The fix is
+ * to assign focus to the first ancestor window that takes
+ * focus. If no window will take focus, set focus to the
+ * desktop.
+ */
+// Control control = null;
+// boolean fixFocus = false;
+// if (!visible) {
+//// if (display.focusEvent != SWT.FocusOut) {
+// control = display.getFocusControl ();
+// fixFocus = isFocusAncestor (control);
+//// }
+// }
+ OS.UIElement_Visibility (topHandle, visible ? OS.Visibility_Visible : OS.Visibility_Hidden);
+ if (isDisposed ()) return;
+ if (!visible) {
+ sendEvent (SWT.Hide);
+ if (isDisposed ()) return;
+ }
+// if (fixFocus) fixFocus (control);
+}
+
+void sort (int [] items) {
+ /* Shell Sort from K&R, pg 108 */
+ int length = items.length;
+ for (int gap=length/2; gap>0; gap/=2) {
+ for (int i=gap; i<length; i++) {
+ for (int j=i-gap; j>=0; j-=gap) {
+ if (items [j] <= items [j + gap]) {
+ int swap = items [j];
+ items [j] = items [j + gap];
+ items [j + gap] = swap;
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Returns a point which is the result of converting the
+ * argument, which is specified in display relative coordinates,
+ * to coordinates relative to the receiver.
+ * <p>
+ * @param x the x coordinate to be translated
+ * @param y the y coordinate to be translated
+ * @return the translated coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.1
+ */
+public Point toControl (int x, int y) {
+ checkWidget ();
+ int point = OS.gcnew_Point (x, y);
+ int result = OS.Visual_PointFromScreen (handle, point);
+ OS.GCHandle_Free (point);
+ x = (int) OS.Point_X (result);
+ y = (int) OS.Point_Y (result);
+ OS.GCHandle_Free (result);
+ return new Point (x, y);
+}
+
+/**
+ * Returns a point which is the result of converting the
+ * argument, which is specified in display relative coordinates,
+ * to coordinates relative to the receiver.
+ * <p>
+ * @param point the point to be translated (must not be null)
+ * @return the translated coordinates
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Point toControl (Point point) {
+ checkWidget ();
+ if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
+ return toControl (point.x, point.y);
+}
+
+/**
+ * Returns a point which is the result of converting the
+ * argument, which is specified in coordinates relative to
+ * the receiver, to display relative coordinates.
+ * <p>
+ * @param x the x coordinate to be translated
+ * @param y the y coordinate to be translated
+ * @return the translated coordinates
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.1
+ */
+public Point toDisplay (int x, int y) {
+ checkWidget ();
+ int point = OS.gcnew_Point (x, y);
+ int result = OS.Visual_PointToScreen (handle, point);
+ OS.GCHandle_Free (point);
+ x = (int) OS.Point_X (result);
+ y = (int) OS.Point_Y (result);
+ OS.GCHandle_Free (result);
+ return new Point (x, y);
+}
+
+/**
+ * Returns a point which is the result of converting the
+ * argument, which is specified in coordinates relative to
+ * the receiver, to display relative coordinates.
+ * <p>
+ * @param point the point to be translated (must not be null)
+ * @return the translated coordinates
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Point toDisplay (Point point) {
+ checkWidget ();
+ if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
+ return toDisplay (point.x, point.y);
+}
+
+boolean translateMnemonic (Event event, Control control) {
+ if (control == this) return false;
+ if (!isVisible () || !isEnabled ()) return false;
+ event.doit = mnemonicMatch (event.character);
+ return traverse (event);
+}
+
+boolean translateMnemonic (int e) {
+ int key = OS.KeyEventArgs_Key(e);
+ if (key < 0x20) return false;
+ int keyboardDevice = OS.KeyboardEventArgs_KeyboardDevice(e);
+ int modifiers = OS.KeyboardDevice_Modifiers(keyboardDevice);
+ OS.GCHandle_Free(keyboardDevice);
+ if (modifiers == 0) {
+ int code = traversalCode (key, e);
+ if ((code & SWT.TRAVERSE_MNEMONIC) == 0) return false;
+ } else {
+ if ((modifiers & OS.ModifierKeys_Alt) == 0) return false;
+ }
+ Decorations shell = menuShell ();
+ if (shell.isVisible () && shell.isEnabled ()) {
+ Event event = new Event ();
+ event.detail = SWT.TRAVERSE_MNEMONIC;
+ if (setKeyState (event, SWT.Traverse, e)) {
+ return translateMnemonic (event, null) || shell.translateMnemonic (event, this);
+ }
+ }
+ return false;
+}
+
+int traversalCode (int key, int event) {
+ int code = SWT.TRAVERSE_RETURN | SWT.TRAVERSE_TAB_NEXT | SWT.TRAVERSE_TAB_PREVIOUS | SWT.TRAVERSE_PAGE_NEXT | SWT.TRAVERSE_PAGE_PREVIOUS;
+ Shell shell = getShell ();
+ if (shell.parent != null) code |= SWT.TRAVERSE_ESCAPE;
+ return code;
+}
+
+boolean translateTraversal (int e) {
+ int detail = SWT.TRAVERSE_NONE;
+ int key = OS.KeyEventArgs_Key(e);
+ int code = traversalCode (key, e);
+ boolean all = false;
+ switch (key) {
+ case OS.Key_Escape: {
+ all = true;
+ detail = SWT.TRAVERSE_ESCAPE;
+ break;
+ }
+ case OS.Key_Return: {
+ all = true;
+ detail = SWT.TRAVERSE_RETURN;
+ break;
+ }
+ case OS.Key_Tab: {
+ int keyboardDevice = OS.KeyboardEventArgs_KeyboardDevice(e);
+ int modifiers = OS.KeyboardDevice_Modifiers(keyboardDevice);
+ OS.GCHandle_Free(keyboardDevice);
+ boolean next = (modifiers & OS.ModifierKeys_Shift) == 0;
+ detail = next ? SWT.TRAVERSE_TAB_NEXT : SWT.TRAVERSE_TAB_PREVIOUS;
+ break;
+ }
+ case OS.Key_Up:
+ case OS.Key_Left:
+ case OS.Key_Down:
+ case OS.Key_Right: {
+ boolean next = key == OS.Key_Down || key == OS.Key_Right;
+ detail = next ? SWT.TRAVERSE_ARROW_NEXT : SWT.TRAVERSE_ARROW_PREVIOUS;
+ break;
+ }
+ case OS.Key_PageUp:
+ case OS.Key_PageDown: {
+ all = true;
+ //if ((keyEvent.state & OS.GDK_CONTROL_MASK) == 0) return false;
+ detail = key == OS.Key_PageDown ? SWT.TRAVERSE_PAGE_NEXT : SWT.TRAVERSE_PAGE_PREVIOUS;
+ break;
+ }
+ default:
+ return false;
+ }
+ Event event = new Event ();
+ event.doit = (code & detail) != 0;
+ event.detail = detail;
+ event.time = OS.InputEventArgs_Timestamp (e);
+ if (!setKeyState (event, SWT.Traverse, e)) return false;
+ Shell shell = getShell ();
+ Control control = this;
+ do {
+ if (control.traverse (event)) return true;
+ if (!event.doit && control.hooks (SWT.Traverse)) return false;
+ if (control == shell) return false;
+ control = control.parent;
+ } while (all && control != null);
+ return false;
+}
+
+boolean traverse (Event event) {
+ /*
+ * It is possible (but unlikely), that application
+ * code could have disposed the widget in the traverse
+ * event. If this happens, return true to stop further
+ * event processing.
+ */
+ sendEvent (SWT.Traverse, event);
+ if (isDisposed ()) return true;
+ if (!event.doit) return false;
+ switch (event.detail) {
+ case SWT.TRAVERSE_NONE: return true;
+ case SWT.TRAVERSE_ESCAPE: return traverseEscape ();
+ case SWT.TRAVERSE_RETURN: return traverseReturn ();
+ case SWT.TRAVERSE_TAB_NEXT: return traverseGroup (true);
+ case SWT.TRAVERSE_TAB_PREVIOUS: return traverseGroup (false);
+ case SWT.TRAVERSE_ARROW_NEXT: return traverseItem (true);
+ case SWT.TRAVERSE_ARROW_PREVIOUS: return traverseItem (false);
+ case SWT.TRAVERSE_MNEMONIC: return traverseMnemonic (event.character);
+ case SWT.TRAVERSE_PAGE_NEXT: return traversePage (true);
+ case SWT.TRAVERSE_PAGE_PREVIOUS: return traversePage (false);
+ }
+ return false;
+}
+
+/**
+ * Based on the argument, perform one of the expected platform
+ * traversal action. The argument should be one of the constants:
+ * <code>SWT.TRAVERSE_ESCAPE</code>, <code>SWT.TRAVERSE_RETURN</code>,
+ * <code>SWT.TRAVERSE_TAB_NEXT</code>, <code>SWT.TRAVERSE_TAB_PREVIOUS</code>,
+ * <code>SWT.TRAVERSE_ARROW_NEXT</code> and <code>SWT.TRAVERSE_ARROW_PREVIOUS</code>.
+ *
+ * @param traversal the type of traversal
+ * @return true if the traversal succeeded
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean traverse (int traversal) {
+ checkWidget ();
+ Event event = new Event ();
+ event.doit = true;
+ event.detail = traversal;
+ return traverse (event);
+}
+
+boolean traverseEscape () {
+ return false;
+}
+
+boolean traverseGroup (boolean next) {
+ Control root = computeTabRoot ();
+ Control group = computeTabGroup ();
+ Control [] list = root.computeTabList ();
+ int length = list.length;
+ int index = 0;
+ while (index < length) {
+ if (list [index] == group) break;
+ index++;
+ }
+ /*
+ * It is possible (but unlikely), that application
+ * code could have disposed the widget in focus in
+ * or out events. Ensure that a disposed widget is
+ * not accessed.
+ */
+ if (index == length) return false;
+ int start = index, offset = (next) ? 1 : -1;
+ while ((index = ((index + offset + length) % length)) != start) {
+ Control control = list [index];
+ if (!control.isDisposed () && control.setTabGroupFocus ()) {
+ return true;
+ }
+ }
+ if (group.isDisposed ()) return false;
+ return group.setTabGroupFocus ();
+}
+
+boolean traverseItem (boolean next) {
+ Control [] children = parent._getChildren ();
+ int length = children.length;
+ int index = 0;
+ while (index < length) {
+ if (children [index] == this) break;
+ index++;
+ }
+ /*
+ * It is possible (but unlikely), that application
+ * code could have disposed the widget in focus in
+ * or out events. Ensure that a disposed widget is
+ * not accessed.
+ */
+ if (index == length) return false;
+ int start = index, offset = (next) ? 1 : -1;
+ while ((index = (index + offset + length) % length) != start) {
+ Control child = children [index];
+ if (!child.isDisposed () && child.isTabItem ()) {
+ if (child.setTabItemFocus ()) return true;
+ }
+ }
+ return false;
+}
+
+boolean traverseMnemonic (char key) {
+ return mnemonicHit (key);
+}
+
+boolean traversePage (boolean next) {
+ return false;
+}
+
+boolean traverseReturn () {
+ return false;
+}
+
+/**
+ * Forces all outstanding paint requests for the widget
+ * to be processed before this method returns.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #redraw
+ * @see #redraw(int, int, int, int, boolean)
+ * @see PaintListener
+ * @see SWT#Paint
+ */
+public void update () {
+ checkWidget ();
+ update (false);
+}
+
+void update (boolean all) {
+ checkWidget ();
+ //TODO
+// if (OS.IsWinCE) {
+// OS.UpdateWindow (handle);
+// } else {
+// int flags = OS.RDW_UPDATENOW;
+// if (all) flags |= OS.RDW_ALLCHILDREN;
+// OS.RedrawWindow (handle, null, 0, flags);
+// }
+}
+
+void updateBackgroundColor () {
+// Control control = findBackgroundControl ();
+// if (control == null) control = this;
+// setBackgroundPixel (control.background);
+}
+
+void updateBackgroundImage () {
+// Control control = findBackgroundControl ();
+// Image image = control != null ? control.backgroundImage : backgroundImage;
+// setBackgroundImage (image != null ? image.handle : 0);
+}
+
+void updateBackgroundMode () {
+ int oldState = state & PARENT_BACKGROUND;
+ checkBackground ();
+ if (oldState != (state & PARENT_BACKGROUND)) {
+ setBackground ();
+ }
+}
+
+void updateFont (Font oldFont, Font newFont) {
+ if (getFont ().equals (oldFont)) setFont (newFont);
+}
+
+void updateImages () {
+ /* Do nothing */
+}
+
+void updateLayout (boolean resize, boolean all) {
+ /* Do nothing */
+}
+
+int widgetParent () {
+ return parent.handle;
+}
+
+/**
+ * Changes the parent of the widget to be the one provided if
+ * the underlying operating system supports this feature.
+ * Returns <code>true</code> if the parent is successfully changed.
+ *
+ * @param parent the new parent for the control.
+ * @return <code>true</code> if the parent is changed and <code>false</code> otherwise.
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is <code>null</code></li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean setParent (Composite parent) {
+ checkWidget ();
+ if (parent == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (parent.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ if (this.parent == parent) return true;
+ if (!isReparentable ()) return false;
+ return true;
+}
+
+}
+
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Decorations.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Decorations.java
new file mode 100644
index 0000000000..3aeef98f2d
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Decorations.java
@@ -0,0 +1,862 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Instances of this class provide the appearance and
+ * behavior of <code>Shells</code>, but are not top
+ * level shells or dialogs. Class <code>Shell</code>
+ * shares a significant amount of code with this class,
+ * and is a subclass.
+ * <p>
+ * IMPORTANT: This class was intended to be abstract and
+ * should <em>never</em> be referenced or instantiated.
+ * Instead, the class <code>Shell</code> should be used.
+ * </p>
+ * <p>
+ * Instances are always displayed in one of the maximized,
+ * minimized or normal states:
+ * <ul>
+ * <li>
+ * When an instance is marked as <em>maximized</em>, the
+ * window manager will typically resize it to fill the
+ * entire visible area of the display, and the instance
+ * is usually put in a state where it can not be resized
+ * (even if it has style <code>RESIZE</code>) until it is
+ * no longer maximized.
+ * </li><li>
+ * When an instance is in the <em>normal</em> state (neither
+ * maximized or minimized), its appearance is controlled by
+ * the style constants which were specified when it was created
+ * and the restrictions of the window manager (see below).
+ * </li><li>
+ * When an instance has been marked as <em>minimized</em>,
+ * its contents (client area) will usually not be visible,
+ * and depending on the window manager, it may be
+ * "iconified" (that is, replaced on the desktop by a small
+ * simplified representation of itself), relocated to a
+ * distinguished area of the screen, or hidden. Combinations
+ * of these changes are also possible.
+ * </li>
+ * </ul>
+ * </p>
+ * Note: The styles supported by this class must be treated
+ * as <em>HINT</em>s, since the window manager for the
+ * desktop on which the instance is visible has ultimate
+ * control over the appearance and behavior of decorations.
+ * For example, some window managers only support resizable
+ * windows and will always assume the RESIZE style, even if
+ * it is not set.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>BORDER, CLOSE, MIN, MAX, NO_TRIM, RESIZE, TITLE, ON_TOP, TOOL</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * Class <code>SWT</code> provides two "convenience constants"
+ * for the most commonly required style combinations:
+ * <dl>
+ * <dt><code>SHELL_TRIM</code></dt>
+ * <dd>
+ * the result of combining the constants which are required
+ * to produce a typical application top level shell: (that
+ * is, <code>CLOSE | TITLE | MIN | MAX | RESIZE</code>)
+ * </dd>
+ * <dt><code>DIALOG_TRIM</code></dt>
+ * <dd>
+ * the result of combining the constants which are required
+ * to produce a typical application dialog shell: (that
+ * is, <code>TITLE | CLOSE | BORDER</code>)
+ * </dd>
+ * </dl>
+ * <p>
+ * IMPORTANT: This class is intended to be subclassed <em>only</em>
+ * within the SWT implementation.
+ * </p>
+ *
+ * @see #getMinimized
+ * @see #getMaximized
+ * @see Shell
+ * @see SWT
+ */
+
+public class Decorations extends Canvas {
+ int shellHandle;
+ Image image;
+// Image image, smallImage, largeImage;
+ Image [] images;
+ Menu menuBar;
+ Menu [] menus;
+ Control savedFocus;
+ Button defaultButton, saveDefault;
+
+/**
+ * Prevents uninitialized instances from being created outside the package.
+ */
+Decorations () {
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#BORDER
+ * @see SWT#CLOSE
+ * @see SWT#MIN
+ * @see SWT#MAX
+ * @see SWT#RESIZE
+ * @see SWT#TITLE
+ * @see SWT#NO_TRIM
+ * @see SWT#SHELL_TRIM
+ * @see SWT#DIALOG_TRIM
+ * @see SWT#ON_TOP
+ * @see SWT#TOOL
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Decorations (Composite parent, int style) {
+ super (parent, checkStyle (style));
+}
+
+void addMenu (Menu menu) {
+ if (menus == null) menus = new Menu [4];
+ for (int i=0; i<menus.length; i++) {
+ if (menus [i] == null) {
+ menus [i] = menu;
+ return;
+ }
+ }
+ Menu [] newMenus = new Menu [menus.length + 4];
+ newMenus [menus.length] = menu;
+ System.arraycopy (menus, 0, newMenus, 0, menus.length);
+ menus = newMenus;
+}
+
+void bringToTop () {
+// /*
+// * This code is intentionally commented. On some platforms,
+// * the ON_TOP style creates a shell that will stay on top
+// * of every other shell on the desktop. Using SetWindowPos ()
+// * with HWND_TOP caused problems on Windows 98 so this code is
+// * commented out until this functionality is specified and
+// * the problems are fixed.
+// */
+//// if ((style & SWT.ON_TOP) != 0) {
+//// int flags = OS.SWP_NOSIZE | OS.SWP_NOMOVE | OS.SWP_NOACTIVATE;
+//// OS.SetWindowPos (handle, OS.HWND_TOP, 0, 0, 0, 0, flags);
+//// } else {
+// OS.BringWindowToTop (handle);
+// // widget could be disposed at this point
+//// }
+}
+
+static int checkStyle (int style) {
+ if ((style & SWT.NO_TRIM) != 0) {
+ style &= ~(SWT.CLOSE | SWT.TITLE | SWT.MIN | SWT.MAX | SWT.RESIZE | SWT.BORDER);
+ }
+ if ((style & (SWT.MENU | SWT.MIN | SWT.MAX | SWT.CLOSE)) != 0) {
+ style |= SWT.TITLE;
+ }
+//
+// /*
+// * If either WS_MINIMIZEBOX or WS_MAXIMIZEBOX are set,
+// * we must also set WS_SYSMENU or the buttons will not
+// * appear.
+// */
+// if ((style & (SWT.MIN | SWT.MAX)) != 0) style |= SWT.CLOSE;
+//
+// /*
+// * Both WS_SYSMENU and WS_CAPTION must be set in order
+// * to for the system menu to appear.
+// */
+// if ((style & SWT.CLOSE) != 0) style |= SWT.TITLE;
+//
+// /*
+// * Bug in Windows. The WS_CAPTION style must be
+// * set when the window is resizable or it does not
+// * draw properly.
+// */
+// /*
+// * This code is intentionally commented. It seems
+// * that this problem originally in Windows 3.11,
+// * has been fixed in later versions. Because the
+// * exact nature of the drawing problem is unknown,
+// * keep the commented code around in case it comes
+// * back.
+// */
+//// if ((style & SWT.RESIZE) != 0) style |= SWT.TITLE;
+//
+ return style;
+}
+
+void checkBorder () {
+ /* Do nothing */
+}
+
+void checkOpened () {
+ //TODO - add back
+// if (!opened) resized = false;
+}
+
+protected void checkSubclass () {
+ if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
+}
+
+void closeWidget () {
+ Event event = new Event ();
+ sendEvent (SWT.Close, event);
+ if (event.doit && !isDisposed ()) dispose ();
+}
+
+int compare (ImageData data1, ImageData data2, int width, int height, int depth) {
+ int value1 = Math.abs (data1.width - width), value2 = Math.abs (data2.width - width);
+ if (value1 == value2) {
+ int transparent1 = data1.getTransparencyType ();
+ int transparent2 = data2.getTransparencyType ();
+ if (transparent1 == transparent2) {
+ if (data1.depth == data2.depth) return 0;
+ return data1.depth > data2.depth && data1.depth <= depth ? -1 : 1;
+ }
+ //if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (5, 1)) {
+ if (transparent1 == SWT.TRANSPARENCY_ALPHA) return -1;
+ if (transparent2 == SWT.TRANSPARENCY_ALPHA) return 1;
+ //}
+ if (transparent1 == SWT.TRANSPARENCY_MASK) return -1;
+ if (transparent2 == SWT.TRANSPARENCY_MASK) return 1;
+ if (transparent1 == SWT.TRANSPARENCY_PIXEL) return -1;
+ if (transparent2 == SWT.TRANSPARENCY_PIXEL) return 1;
+ return 0;
+ }
+ return value1 < value2 ? -1 : 1;
+}
+
+Control computeTabGroup () {
+ return this;
+}
+
+Control computeTabRoot () {
+ return this;
+}
+
+public void dispose () {
+ if (isDisposed()) return;
+ if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
+ if (!(this instanceof Shell)) {
+ setVisible (false);
+ if (!traverseDecorations (false)) {
+ Shell shell = getShell ();
+ shell.setFocus ();
+ }
+ }
+ super.dispose ();
+}
+
+Menu findMenu (int hMenu) {
+ if (menus == null) return null;
+ for (int i=0; i<menus.length; i++) {
+ Menu menu = menus [i];
+ if (menu != null && hMenu == menu.handle) return menu;
+ }
+ return null;
+}
+
+void fixDecorations (Decorations newDecorations, Control control, Menu [] menus) {
+ if (this == newDecorations) return;
+ if (control == savedFocus) savedFocus = null;
+ if (control == defaultButton) defaultButton = null;
+ if (control == saveDefault) saveDefault = null;
+ if (menus == null) return;
+ Menu menu = control.menu;
+ if (menu != null) {
+ int index = 0;
+ while (index <menus.length) {
+ if (menus [index] == menu) {
+ control.setMenu (null);
+ return;
+ }
+ index++;
+ }
+ menu.fixMenus (newDecorations);
+// destroyAccelerators ();
+// newDecorations.destroyAccelerators ();
+ }
+}
+
+/**
+ * Returns the receiver's default button if one had
+ * previously been set, otherwise returns null.
+ *
+ * @return the default button or null
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #setDefaultButton
+ */
+public Button getDefaultButton () {
+ checkWidget ();
+ return defaultButton;
+}
+
+/**
+ * Returns the receiver's image if it had previously been
+ * set using <code>setImage()</code>. The image is typically
+ * displayed by the window manager when the instance is
+ * marked as iconified, and may also be displayed somewhere
+ * in the trim when the instance is in normal or maximized
+ * states.
+ * <p>
+ * Note: This method will return null if called before
+ * <code>setImage()</code> is called. It does not provide
+ * access to a window manager provided, "default" image
+ * even if one exists.
+ * </p>
+ *
+ * @return the image
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Image getImage () {
+ checkWidget ();
+ return image;
+}
+
+/**
+ * Returns the receiver's images if they had previously been
+ * set using <code>setImages()</code>. Images are typically
+ * displayed by the window manager when the instance is
+ * marked as iconified, and may also be displayed somewhere
+ * in the trim when the instance is in normal or maximized
+ * states. Depending where the icon is displayed, the platform
+ * chooses the icon with the "best" attributes. It is expected
+ * that the array will contain the same icon rendered at different
+ * sizes, with different depth and transparency attributes.
+ *
+ * <p>
+ * Note: This method will return an empty array if called before
+ * <code>setImages()</code> is called. It does not provide
+ * access to a window manager provided, "default" image
+ * even if one exists.
+ * </p>
+ *
+ * @return the images
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public Image [] getImages () {
+ checkWidget ();
+ if (images == null) return new Image [0];
+ Image [] result = new Image [images.length];
+ System.arraycopy (images, 0, result, 0, images.length);
+ return result;
+}
+
+/**
+ * Returns <code>true</code> if the receiver is currently
+ * maximized, and false otherwise.
+ * <p>
+ *
+ * @return the maximized state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #setMaximized
+ */
+public boolean getMaximized () {
+ checkWidget ();
+ return OS.Window_WindowState (shellHandle) == OS.WindowState_Maximized;
+}
+
+/**
+ * Returns the receiver's menu bar if one had previously
+ * been set, otherwise returns null.
+ *
+ * @return the menu bar or null
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Menu getMenuBar () {
+ checkWidget ();
+ return menuBar;
+}
+
+/**
+ * Returns <code>true</code> if the receiver is currently
+ * minimized, and false otherwise.
+ * <p>
+ *
+ * @return the minimized state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #setMinimized
+ */
+public boolean getMinimized () {
+ checkWidget ();
+ return OS.Window_WindowState (shellHandle) == OS.WindowState_Minimized;
+}
+
+String getNameText () {
+ return getText ();
+}
+
+/**
+ * Returns the receiver's text, which is the string that the
+ * window manager will typically display as the receiver's
+ * <em>title</em>. If the text has not previously been set,
+ * returns an empty string.
+ *
+ * @return the text
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String getText () {
+ checkWidget ();
+ int shellHandle = topHandle ();
+ int str = OS.Window_Title (shellHandle);
+ String string = createJavaString(str);
+ OS.GCHandle_Free (str);
+ return string;
+}
+
+public boolean isReparentable () {
+ checkWidget ();
+ /*
+ * Feature in Windows. Calling SetParent() for a shell causes
+ * a kind of fake MDI to happen. It doesn't work well on Windows
+ * and is not supported on the other platforms. The fix is to
+ * disallow the SetParent().
+ */
+ return false;
+}
+
+boolean isTabGroup () {
+ /*
+ * Can't test WS_TAB bits because they are the same as WS_MAXIMIZEBOX.
+ */
+ return true;
+}
+
+boolean isTabItem () {
+ /*
+ * Can't test WS_TAB bits because they are the same as WS_MAXIMIZEBOX.
+ */
+ return false;
+}
+
+Decorations menuShell () {
+ return this;
+}
+
+void releaseChildren (boolean destroy) {
+ if (menuBar != null) {
+ menuBar.release (false);
+ menuBar = null;
+ }
+ super.releaseChildren (destroy);
+ if (menus != null) {
+ for (int i=0; i<menus.length; i++) {
+ Menu menu = menus [i];
+ if (menu != null && !menu.isDisposed ()) {
+ menu.dispose ();
+ }
+ }
+ menus = null;
+ }
+}
+
+void releaseWidget () {
+ super.releaseWidget ();
+ image = null;
+ images = null;
+// savedFocus = null;
+// defaultButton = saveDefault = null;
+}
+
+void removeMenu (Menu menu) {
+ if (menus == null) return;
+ for (int i=0; i<menus.length; i++) {
+ if (menus [i] == menu) {
+ menus [i] = null;
+ return;
+ }
+ }
+}
+
+boolean restoreFocus () {
+// if (display.ignoreRestoreFocus) return true;
+
+ if (savedFocus != null && savedFocus.isDisposed ()) savedFocus = null;
+ if (savedFocus != null && savedFocus.setSavedFocus ()) return true;
+ /*
+ * This code is intentionally commented. When no widget
+ * has been given focus, some platforms give focus to the
+ * default button. Windows doesn't do this.
+ */
+// if (defaultButton != null && !defaultButton.isDisposed ()) {
+// if (defaultButton.setFocus ()) return true;
+// }
+ return false;
+}
+
+void saveFocus () {
+ Control control = display._getFocusControl ();
+ if (control != null && control != this && this == control.menuShell ()) {
+ setSavedFocus (control);
+ }
+}
+
+/**
+ * If the argument is not null, sets the receiver's default
+ * button to the argument, and if the argument is null, sets
+ * the receiver's default button to the first button which
+ * was set as the receiver's default button (called the
+ * <em>saved default button</em>). If no default button had
+ * previously been set, or the saved default button was
+ * disposed, the receiver's default button will be set to
+ * null.
+ * <p>
+ * The default button is the button that is selected when
+ * the receiver is active and the user presses ENTER.
+ * </p>
+ *
+ * @param button the new default button
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the button has been disposed</li>
+ * <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setDefaultButton (Button button) {
+ checkWidget ();
+ if (button != null) {
+ if (button.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (button.menuShell () != this) error(SWT.ERROR_INVALID_PARENT);
+ }
+ setDefaultButton (button, true);
+}
+
+void setDefaultButton (Button button, boolean save) {
+ if (button == null) {
+ if (defaultButton == saveDefault) {
+ if (save) saveDefault = null;
+ return;
+ }
+ } else {
+ if ((button.style & SWT.PUSH) == 0) return;
+ if (button == defaultButton) return;
+ }
+ if (defaultButton != null) {
+ if (!defaultButton.isDisposed ()) defaultButton.setDefault (false);
+ }
+ if ((defaultButton = button) == null) defaultButton = saveDefault;
+ if (defaultButton != null) {
+ if (!defaultButton.isDisposed ()) defaultButton.setDefault (true);
+ }
+ if (save) saveDefault = defaultButton;
+ if (saveDefault != null && saveDefault.isDisposed ()) saveDefault = null;
+}
+
+/**
+ * Sets the receiver's image to the argument, which may
+ * be null. The image is typically displayed by the window
+ * manager when the instance is marked as iconified, and
+ * may also be displayed somewhere in the trim when the
+ * instance is in normal or maximized states.
+ *
+ * @param image the new image (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setImage (Image image) {
+ checkWidget ();
+ if (image != null && image.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ this.image = image;
+ setImages (image, null);
+}
+
+void setImages (Image image, Image [] images) {
+ //TODO
+}
+
+/**
+ * Sets the receiver's images to the argument, which may
+ * be an empty array. Images are typically displayed by the
+ * window manager when the instance is marked as iconified,
+ * and may also be displayed somewhere in the trim when the
+ * instance is in normal or maximized states. Depending where
+ * the icon is displayed, the platform chooses the icon with
+ * the "best" attributes. It is expected that the array will
+ * contain the same icon rendered at different sizes, with
+ * different depth and transparency attributes.
+ *
+ * @param images the new image array
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the array of images is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if one of the images is null or has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void setImages (Image [] images) {
+ checkWidget ();
+ if (images == null) error (SWT.ERROR_INVALID_ARGUMENT);
+ for (int i = 0; i < images.length; i++) {
+ if (images [i] == null || images [i].isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+ this.images = images;
+ setImages (null, images);
+}
+
+/**
+ * Sets the maximized state of the receiver.
+ * If the argument is <code>true</code> causes the receiver
+ * to switch to the maximized state, and if the argument is
+ * <code>false</code> and the receiver was previously maximized,
+ * causes the receiver to switch back to either the minimized
+ * or normal states.
+ * <p>
+ * Note: The result of intermixing calls to <code>setMaximized(true)</code>
+ * and <code>setMinimized(true)</code> will vary by platform. Typically,
+ * the behavior will match the platform user's expectations, but not
+ * always. This should be avoided if possible.
+ * </p>
+ *
+ * @param maximized the new maximized state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #setMinimized
+ */
+public void setMaximized (boolean maximized) {
+ checkWidget ();
+ int state = maximized ? OS.WindowState_Maximized : OS.WindowState_Normal;
+ OS.Window_WindowState (shellHandle, state);
+}
+
+/**
+ * Sets the receiver's menu bar to the argument, which
+ * may be null.
+ *
+ * @param menu the new menu bar
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the menu has been disposed</li>
+ * <li>ERROR_INVALID_PARENT - if the menu is not in the same widget tree</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setMenuBar (Menu menu) {
+ checkWidget ();
+ if (menuBar == menu) return;
+ if (menu != null) {
+ if (menu.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
+ if ((menu.style & SWT.BAR) == 0) error (SWT.ERROR_MENU_NOT_BAR);
+ if (menu.parent != this) error (SWT.ERROR_INVALID_PARENT);
+ }
+ int children = OS.Panel_Children (scrolledHandle);
+ if (menuBar != null) {
+ OS.Menu_IsMainMenu (menuBar.handle, false);
+ OS.UIElementCollection_Remove (children, menuBar.handle);
+ }
+ menuBar = menu;
+ if (menuBar != null) {
+ int menuHandle = menuBar.handle;
+ OS.Menu_IsMainMenu (menuHandle, true);
+ OS.Grid_SetRow (menuHandle, 0);
+ OS.Grid_SetColumn (menuHandle, 0);
+ OS.Grid_SetColumnSpan (menuHandle, 2);
+ OS.UIElementCollection_Add (children, menuHandle);
+ }
+ OS.GCHandle_Free (children);
+}
+
+/**
+ * Sets the minimized stated of the receiver.
+ * If the argument is <code>true</code> causes the receiver
+ * to switch to the minimized state, and if the argument is
+ * <code>false</code> and the receiver was previously minimized,
+ * causes the receiver to switch back to either the maximized
+ * or normal states.
+ * <p>
+ * Note: The result of intermixing calls to <code>setMaximized(true)</code>
+ * and <code>setMinimized(true)</code> will vary by platform. Typically,
+ * the behavior will match the platform user's expectations, but not
+ * always. This should be avoided if possible.
+ * </p>
+ *
+ * @param minimized the new maximized state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #setMaximized
+ */
+public void setMinimized (boolean minimized) {
+ checkWidget ();
+ int state = minimized ? OS.WindowState_Minimized : OS.WindowState_Normal;
+ OS.Window_WindowState (shellHandle, state);
+}
+
+void setSavedFocus (Control control) {
+ savedFocus = control;
+}
+
+/**
+ * Sets the receiver's text, which is the string that the
+ * window manager will typically display as the receiver's
+ * <em>title</em>, to the argument, which must not be null.
+ *
+ * @param string the new text
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setText (String string) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int strPtr = createDotNetString (string, false);
+ int shellHandle = topHandle ();
+ OS.Window_Title (shellHandle, strPtr);
+ OS.GCHandle_Free (strPtr);
+}
+
+void sort (Image [] images, ImageData [] datas, int width, int height, int depth) {
+ /* Shell Sort from K&R, pg 108 */
+ int length = images.length;
+ if (length <= 1) return;
+ for (int gap=length/2; gap>0; gap/=2) {
+ for (int i=gap; i<length; i++) {
+ for (int j=i-gap; j>=0; j-=gap) {
+ if (compare (datas [j], datas [j + gap], width, height, depth) >= 0) {
+ Image swap = images [j];
+ images [j] = images [j + gap];
+ images [j + gap] = swap;
+ ImageData swapData = datas [j];
+ datas [j] = datas [j + gap];
+ datas [j + gap] = swapData;
+ }
+ }
+ }
+ }
+}
+
+boolean traverseDecorations (boolean next) {
+ Control [] children = parent._getChildren ();
+ int length = children.length;
+ int index = 0;
+ while (index < length) {
+ if (children [index] == this) break;
+ index++;
+ }
+ /*
+ * It is possible (but unlikely), that application
+ * code could have disposed the widget in focus in
+ * or out events. Ensure that a disposed widget is
+ * not accessed.
+ */
+ int start = index, offset = (next) ? 1 : -1;
+ while ((index = (index + offset + length) % length) != start) {
+ Control child = children [index];
+ if (!child.isDisposed () && child instanceof Decorations) {
+ if (child.setFocus ()) return true;
+ }
+ }
+ return false;
+}
+
+boolean traverseItem (boolean next) {
+ return false;
+}
+
+boolean traverseReturn () {
+ if (defaultButton == null || defaultButton.isDisposed ()) return false;
+ if (!defaultButton.isVisible () || !defaultButton.isEnabled ()) return false;
+// defaultButton.click ();
+ return true;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/DirectoryDialog.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/DirectoryDialog.java
new file mode 100644
index 0000000000..c80338b8d9
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/DirectoryDialog.java
@@ -0,0 +1,277 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.*;
+
+/**
+ * Instances of this class allow the user to navigate
+ * the file system and select a directory.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>(none)</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * <p>
+ * IMPORTANT: This class is intended to be subclassed <em>only</em>
+ * within the SWT implementation.
+ * </p>
+ */
+
+public class DirectoryDialog extends Dialog {
+ String message = "", filterPath = ""; //$NON-NLS-1$//$NON-NLS-2$
+ String directoryPath;
+
+/**
+ * Constructs a new instance of this class given only its parent.
+ *
+ * @param parent a shell which will be the parent of the new instance
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ */
+public DirectoryDialog (Shell parent) {
+ this (parent, SWT.PRIMARY_MODAL);
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a shell which will be the parent of the new instance
+ * @param style the style of dialog to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ */
+public DirectoryDialog (Shell parent, int style) {
+ super (parent, style);
+ checkSubclass ();
+}
+
+/**
+ * Returns the path which the dialog will use to filter
+ * the directories it shows.
+ *
+ * @return the filter path
+ *
+ * @see #setFilterPath
+ */
+public String getFilterPath () {
+ return filterPath;
+}
+
+/**
+ * Returns the dialog's message, which is a description of
+ * the purpose for which it was opened. This message will be
+ * visible on the dialog while it is open.
+ *
+ * @return the message
+ */
+public String getMessage () {
+ return message;
+}
+
+/**
+ * Makes the dialog visible and brings it to the front
+ * of the display.
+ *
+ * @return a string describing the absolute path of the selected directory,
+ * or null if the dialog was cancelled or an error occurred
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the dialog has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the dialog</li>
+ * </ul>
+ */
+public String open () {
+// if (OS.IsWinCE) SWT.error (SWT.ERROR_NOT_IMPLEMENTED);
+//
+// int hHeap = OS.GetProcessHeap ();
+//
+// /* Get the owner HWND for the dialog */
+// int hwndOwner = 0;
+// if (parent != null) hwndOwner = parent.handle;
+//
+// /* Copy the message to OS memory */
+// int lpszTitle = 0;
+// if (message.length () != 0) {
+// String string = message;
+// if (string.indexOf ('&') != -1) {
+// int length = string.length ();
+// char [] buffer = new char [length * 2];
+// int index = 0;
+// for (int i=0; i<length; i++) {
+// char ch = string.charAt (i);
+// if (ch == '&') buffer [index++] = '&';
+// buffer [index++] = ch;
+// }
+// string = new String (buffer, 0, index);
+// }
+// /* Use the character encoding for the default locale */
+// TCHAR buffer = new TCHAR (0, string, true);
+// int byteCount = buffer.length () * TCHAR.sizeof;
+// lpszTitle = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
+// OS.MoveMemory (lpszTitle, buffer, byteCount);
+// }
+//
+// /* Create the BrowseCallbackProc */
+// Callback callback = new Callback (this, "BrowseCallbackProc", 4); //$NON-NLS-1$
+// int address = callback.getAddress ();
+// if (address == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
+//
+// /* Make the parent shell be temporary modal */
+// Shell oldModal = null;
+// Display display = parent.getDisplay ();
+// if ((style & (SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) != 0) {
+// oldModal = display.getModalDialogShell ();
+// display.setModalDialogShell (parent);
+// }
+//
+// directoryPath = null;
+// BROWSEINFO lpbi = new BROWSEINFO ();
+// lpbi.hwndOwner = hwndOwner;
+// lpbi.lpszTitle = lpszTitle;
+// lpbi.ulFlags = OS.BIF_NEWDIALOGSTYLE | OS.BIF_RETURNONLYFSDIRS | OS.BIF_EDITBOX | OS.BIF_VALIDATE;
+// lpbi.lpfn = address;
+// /*
+// * Bug in Windows. On some hardware configurations, SHBrowseForFolder()
+// * causes warning dialogs with the message "There is no disk in the drive
+// * Please insert a disk into \Device\Harddisk0\DR0". This is possibly
+// * caused by SHBrowseForFolder() calling internally GetVolumeInformation().
+// * MSDN for GetVolumeInformation() says:
+// *
+// * "If you are attempting to obtain information about a floppy drive
+// * that does not have a floppy disk or a CD-ROM drive that does not
+// * have a compact disc, the system displays a message box asking the
+// * user to insert a floppy disk or a compact disc, respectively.
+// * To prevent the system from displaying this message box, call the
+// * SetErrorMode function with SEM_FAILCRITICALERRORS."
+// *
+// * The fix is to save and restore the error mode using SetErrorMode()
+// * with the SEM_FAILCRITICALERRORS flag around SHBrowseForFolder().
+// */
+// int oldErrorMode = OS.SetErrorMode (OS.SEM_FAILCRITICALERRORS);
+//
+// /*
+// * Bug in Windows. When a WH_MSGFILTER hook is used to run code
+// * during the message loop for SHBrowseForFolder(), running code
+// * in the hook can cause a GP. Specifically, SetWindowText()
+// * for static controls seemed to make the problem happen.
+// * The fix is to disable async messages while the directory
+// * dialog is open.
+// *
+// * NOTE: This only happens in versions of the comctl32.dll
+// * earlier than 6.0.
+// */
+// boolean oldRunMessages = display.runMessages;
+// if (OS.COMCTL32_MAJOR < 6) display.runMessages = false;
+// int lpItemIdList = OS.SHBrowseForFolder (lpbi);
+// if (OS.COMCTL32_MAJOR < 6) display.runMessages = oldRunMessages;
+// OS.SetErrorMode (oldErrorMode);
+//
+// /* Clear the temporary dialog modal parent */
+// if ((style & (SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) != 0) {
+// display.setModalDialogShell (oldModal);
+// }
+//
+// boolean success = lpItemIdList != 0;
+// if (success) {
+// /* Use the character encoding for the default locale */
+// TCHAR buffer = new TCHAR (0, OS.MAX_PATH);
+// if (OS.SHGetPathFromIDList (lpItemIdList, buffer)) {
+// directoryPath = buffer.toString (0, buffer.strlen ());
+// filterPath = directoryPath;
+// }
+// }
+//
+// /* Free the BrowseCallbackProc */
+// callback.dispose ();
+//
+// /* Free the OS memory */
+// if (lpszTitle != 0) OS.HeapFree (hHeap, 0, lpszTitle);
+//
+// /* Free the pointer to the ITEMIDLIST */
+// int [] ppMalloc = new int [1];
+// if (OS.SHGetMalloc (ppMalloc) == OS.S_OK) {
+// /* void Free (struct IMalloc *this, void *pv); */
+// OS.VtblCall (5, ppMalloc [0], lpItemIdList);
+// }
+//
+// /*
+// * This code is intentionally commented. On some
+// * platforms, the owner window is repainted right
+// * away when a dialog window exits. This behavior
+// * is currently unspecified.
+// */
+//// if (hwndOwner != 0) OS.UpdateWindow (hwndOwner);
+//
+// /* Return the directory path */
+// if (!success) return null;
+// return directoryPath;
+ return null;
+}
+
+/**
+ * Sets the path that the dialog will use to filter
+ * the directories it shows to the argument, which may
+ * be null. If the string is null, then the operating
+ * system's default filter path will be used.
+ * <p>
+ * Note that the path string is platform dependent.
+ * For convenience, either '/' or '\' can be used
+ * as a path separator.
+ * </p>
+ *
+ * @param string the filter path
+ */
+public void setFilterPath (String string) {
+ filterPath = string;
+}
+
+/**
+ * Sets the dialog's message, which is a description of
+ * the purpose for which it was opened. This message will be
+ * visible on the dialog while it is open.
+ *
+ * @param string the message
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ */
+public void setMessage (String string) {
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ message = string;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Display.java
new file mode 100644
index 0000000000..8eb93dd46f
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Display.java
@@ -0,0 +1,2807 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Instances of this class are responsible for managing the
+ * connection between SWT and the underlying operating
+ * system. Their most important function is to implement
+ * the SWT event loop in terms of the platform event model.
+ * They also provide various methods for accessing information
+ * about the operating system, and have overall control over
+ * the operating system resources which SWT allocates.
+ * <p>
+ * Applications which are built with SWT will <em>almost always</em>
+ * require only a single display. In particular, some platforms
+ * which SWT supports will not allow more than one <em>active</em>
+ * display. In other words, some platforms do not support
+ * creating a new display if one already exists that has not been
+ * sent the <code>dispose()</code> message.
+ * <p>
+ * In SWT, the thread which creates a <code>Display</code>
+ * instance is distinguished as the <em>user-interface thread</em>
+ * for that display.
+ * </p>
+ * The user-interface thread for a particular display has the
+ * following special attributes:
+ * <ul>
+ * <li>
+ * The event loop for that display must be run from the thread.
+ * </li>
+ * <li>
+ * Some SWT API methods (notably, most of the public methods in
+ * <code>Widget</code> and its subclasses), may only be called
+ * from the thread. (To support multi-threaded user-interface
+ * applications, class <code>Display</code> provides inter-thread
+ * communication methods which allow threads other than the
+ * user-interface thread to request that it perform operations
+ * on their behalf.)
+ * </li>
+ * <li>
+ * The thread is not allowed to construct other
+ * <code>Display</code>s until that display has been disposed.
+ * (Note that, this is in addition to the restriction mentioned
+ * above concerning platform support for multiple displays. Thus,
+ * the only way to have multiple simultaneously active displays,
+ * even on platforms which support it, is to have multiple threads.)
+ * </li>
+ * </ul>
+ * Enforcing these attributes allows SWT to be implemented directly
+ * on the underlying operating system's event model. This has
+ * numerous benefits including smaller footprint, better use of
+ * resources, safer memory management, clearer program logic,
+ * better performance, and fewer overall operating system threads
+ * required. The down side however, is that care must be taken
+ * (only) when constructing multi-threaded applications to use the
+ * inter-thread communication mechanisms which this class provides
+ * when required.
+ * </p><p>
+ * All SWT API methods which may only be called from the user-interface
+ * thread are distinguished in their documentation by indicating that
+ * they throw the "<code>ERROR_THREAD_INVALID_ACCESS</code>"
+ * SWT exception.
+ * </p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>(none)</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Close, Dispose</dd>
+ * </dl>
+ * <p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ * @see #syncExec
+ * @see #asyncExec
+ * @see #wake
+ * @see #readAndDispatch
+ * @see #sleep
+ * @see Device#dispose
+ */
+
+public class Display extends Device {
+
+
+ int application, dispatcher, frame, jniRef;
+ boolean idle;
+ int sleep;
+ int operationCount;
+
+ /* Windows and Events */
+ Event [] eventQueue;
+ EventTable eventTable, filterTable;
+
+ int lastKey;
+ char lastChar;
+ boolean deadChar;
+
+// /* Focus */
+// int focusEvent;
+// Control focusControl;
+//
+ /* Menus */
+ Menu [] popups;
+
+ /* Sync/Async Widget Communication */
+ Synchronizer synchronizer = new Synchronizer (this);
+ Thread thread;
+
+ /* Display Shutdown */
+ Runnable [] disposeList;
+
+ /* System Tray */
+ Tray tray;
+
+ /* Timers */
+ int timerHandler;
+ int [] timerHandles;
+ Runnable [] timerList;
+
+// /* System Resources */
+ Font systemFont;
+ Image errorImage, infoImage, questionImage, warningIcon;
+ Cursor [] cursors = new Cursor [SWT.CURSOR_HAND + 1];
+ Color [] colors;
+
+ /* Sort Indicators */
+// Image upArrow, downArrow;
+
+ /* Color dialog custom dialgos */
+ int customColors;
+
+ /* Display Data */
+ Object data;
+ String [] keys;
+ Object [] values;
+
+ /* Key Mappings */
+ static final int [] [] KeyTable = {
+
+ /* Keyboard and Mouse Masks */
+ {OS.Key_LeftAlt, SWT.ALT},
+ {OS.Key_RightAlt, SWT.ALT},
+ {OS.Key_LeftShift, SWT.SHIFT},
+ {OS.Key_RightShift, SWT.SHIFT},
+ {OS.Key_LeftCtrl, SWT.CONTROL},
+ {OS.Key_RightCtrl, SWT.CONTROL},
+// {OS.VK_????, SWT.COMMAND},
+
+ /* NOT CURRENTLY USED */
+// {OS.VK_LBUTTON, SWT.BUTTON1},
+// {OS.VK_MBUTTON, SWT.BUTTON3},
+// {OS.VK_RBUTTON, SWT.BUTTON2},
+
+ /* Non-Numeric Keypad Keys */
+ {OS.Key_Up, SWT.ARROW_UP},
+ {OS.Key_Down, SWT.ARROW_DOWN},
+ {OS.Key_Left, SWT.ARROW_LEFT},
+ {OS.Key_Right, SWT.ARROW_RIGHT},
+ {OS.Key_PageUp, SWT.PAGE_UP},
+ {OS.Key_PageDown, SWT.PAGE_DOWN},
+ {OS.Key_Home, SWT.HOME},
+ {OS.Key_End, SWT.END},
+ {OS.Key_Insert, SWT.INSERT},
+
+ /* Virtual and Ascii Keys */
+ {OS.Key_Back, SWT.BS},
+ {OS.Key_Return, SWT.CR},
+ {OS.Key_Delete, SWT.DEL},
+ {OS.Key_Escape, SWT.ESC},
+ {OS.Key_Return, SWT.LF},
+ {OS.Key_Tab, SWT.TAB},
+
+ /* Functions Keys */
+ {OS.Key_F1, SWT.F1},
+ {OS.Key_F2, SWT.F2},
+ {OS.Key_F3, SWT.F3},
+ {OS.Key_F4, SWT.F4},
+ {OS.Key_F5, SWT.F5},
+ {OS.Key_F6, SWT.F6},
+ {OS.Key_F7, SWT.F7},
+ {OS.Key_F8, SWT.F8},
+ {OS.Key_F9, SWT.F9},
+ {OS.Key_F10, SWT.F10},
+ {OS.Key_F11, SWT.F11},
+ {OS.Key_F12, SWT.F12},
+ {OS.Key_F13, SWT.F13},
+ {OS.Key_F14, SWT.F14},
+ {OS.Key_F15, SWT.F15},
+
+ /* Numeric Keypad Keys */
+ {OS.Key_Multiply, SWT.KEYPAD_MULTIPLY},
+ {OS.Key_Add, SWT.KEYPAD_ADD},
+ {OS.Key_Return, SWT.KEYPAD_CR},
+ {OS.Key_Subtract, SWT.KEYPAD_SUBTRACT},
+ {OS.Key_Decimal, SWT.KEYPAD_DECIMAL},
+ {OS.Key_Divide, SWT.KEYPAD_DIVIDE},
+ {OS.Key_NumPad0, SWT.KEYPAD_0},
+ {OS.Key_NumPad1, SWT.KEYPAD_1},
+ {OS.Key_NumPad2, SWT.KEYPAD_2},
+ {OS.Key_NumPad3, SWT.KEYPAD_3},
+ {OS.Key_NumPad4, SWT.KEYPAD_4},
+ {OS.Key_NumPad5, SWT.KEYPAD_5},
+ {OS.Key_NumPad6, SWT.KEYPAD_6},
+ {OS.Key_NumPad7, SWT.KEYPAD_7},
+ {OS.Key_NumPad8, SWT.KEYPAD_8},
+ {OS.Key_NumPad9, SWT.KEYPAD_9},
+// {OS.VK_????, SWT.KEYPAD_EQUAL},
+
+ /* Other keys */
+ {OS.Key_CapsLock, SWT.CAPS_LOCK},
+ {OS.Key_NumLock, SWT.NUM_LOCK},
+ {OS.Key_Scroll, SWT.SCROLL_LOCK},
+ {OS.Key_Pause, SWT.PAUSE},
+ {OS.Key_Cancel, SWT.BREAK},
+ {OS.Key_PrintScreen, SWT.PRINT_SCREEN},
+// {OS.VK_????, SWT.HELP},
+
+
+ {OS.Key_D0, '0'},
+ {OS.Key_D1, '1'},
+ {OS.Key_D2, '2'},
+ {OS.Key_D3, '3'},
+ {OS.Key_D4, '4'},
+ {OS.Key_D5, '5'},
+ {OS.Key_D6, '6'},
+ {OS.Key_D7, '7'},
+ {OS.Key_D8, '8'},
+ {OS.Key_D9, '9'},
+ {OS.Key_A, 'a'},
+ {OS.Key_B, 'b'},
+ {OS.Key_C, 'c'},
+ {OS.Key_D, 'd'},
+ {OS.Key_E, 'e'},
+ {OS.Key_F, 'f'},
+ {OS.Key_G, 'g'},
+ {OS.Key_H, 'h'},
+ {OS.Key_I, 'i'},
+ {OS.Key_J, 'j'},
+ {OS.Key_K, 'k'},
+ {OS.Key_L, 'l'},
+ {OS.Key_M, 'm'},
+ {OS.Key_N, 'n'},
+ {OS.Key_O, 'o'},
+ {OS.Key_P, 'p'},
+ {OS.Key_Q, 'q'},
+ {OS.Key_R, 'r'},
+ {OS.Key_S, 's'},
+ {OS.Key_T, 't'},
+ {OS.Key_U, 'u'},
+ {OS.Key_V, 'v'},
+ {OS.Key_W, 'w'},
+ {OS.Key_X, 'x'},
+ {OS.Key_Y, 'y'},
+ {OS.Key_Z, 'z'},
+
+ {OS.Key_OemTilde, '`'},
+ {OS.Key_OemMinus, '-'},
+ {OS.Key_OemPlus, '='},
+ {OS.Key_Oem4, '['},
+ {OS.Key_Oem6, ']'},
+ {OS.Key_OemPipe, '\\'},
+ {OS.Key_OemSemicolon, ';'},
+ {OS.Key_Oem7, '\''},
+ {OS.Key_OemComma, ','},
+ {OS.Key_OemPeriod, '.'},
+ {OS.Key_Oem2, '/'},
+
+ };
+
+ /* Multiple Displays */
+ static Display Default;
+ static Display [] Displays = new Display [4];
+
+ /* Multiple Monitors */
+ static Monitor[] monitors = null;
+ static int monitorCount = 0;
+
+ /* Modality */
+ Shell [] modalShells;
+ Shell modalDialogShell;
+ static boolean TrimEnabled = false;
+
+ /* Private SWT Window Messages */
+// static final int SWT_GETACCELCOUNT = OS.WM_APP;
+// static final int SWT_GETACCEL = OS.WM_APP + 1;
+// static final int SWT_KEYMSG = OS.WM_APP + 2;
+// static final int SWT_DESTROY = OS.WM_APP + 3;
+// static final int SWT_TRAYICONMSG = OS.WM_APP + 4;
+// static final int SWT_NULL = OS.WM_APP + 5;
+// static int SWT_TASKBARCREATED;
+
+ /* Workaround for Adobe Reader 7.0 */
+ int hitCount;
+
+ /* Package Name */
+ static final String PACKAGE_PREFIX = "org.eclipse.swt.widgets."; //$NON-NLS-1$
+ /*
+ * This code is intentionally commented. In order
+ * to support CLDC, .class cannot be used because
+ * it does not compile on some Java compilers when
+ * they are targeted for CLDC.
+ */
+// static {
+// String name = Display.class.getName ();
+// int index = name.lastIndexOf ('.');
+// PACKAGE_PREFIX = name.substring (0, index + 1);
+// }
+
+ /*
+ * TEMPORARY CODE. Install the runnable that
+ * gets the current display. This code will
+ * be removed in the future.
+ */
+ static {
+ DeviceFinder = new Runnable () {
+ public void run () {
+ Device device = getCurrent ();
+ if (device == null) {
+ device = getDefault ();
+ }
+ setDevice (device);
+ }
+ };
+ }
+
+/*
+* TEMPORARY CODE.
+*/
+static void setDevice (Device device) {
+ CurrentDevice = device;
+}
+
+/**
+ * Constructs a new instance of this class.
+ * <p>
+ * Note: The resulting display is marked as the <em>current</em>
+ * display. If this is the first display which has been
+ * constructed since the application started, it is also
+ * marked as the <em>default</em> display.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if called from a thread that already created an existing display</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see #getCurrent
+ * @see #getDefault
+ * @see Widget#checkSubclass
+ * @see Shell
+ */
+public Display () {
+ this (null);
+}
+
+/**
+ * Constructs a new instance of this class using the parameter.
+ *
+ * @param data the device data
+ */
+public Display (DeviceData data) {
+ super (data);
+}
+
+Control _getFocusControl () {
+ int focusedElement = OS.Keyboard_FocusedElement ();
+ Control control = null;
+ if (focusedElement != 0) {
+ Widget widget = getWidget (focusedElement);
+ if (widget != null) control = widget.getWidgetControl ();
+ OS.GCHandle_Free (focusedElement);
+ }
+ return control;
+}
+
+void addWidget (int handle, Widget widget) {
+ if (handle == 0) return;
+ int tag = OS.gcnew_IntPtr (widget.jniRef);
+ OS.FrameworkElement_Tag (handle, tag);
+ OS.GCHandle_Free (tag);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when an event of the given type occurs anywhere
+ * in a widget. The event type is one of the event constants
+ * defined in class <code>SWT</code>. When the event does occur,
+ * the listener is notified by sending it the <code>handleEvent()</code>
+ * message.
+ * <p>
+ * Setting the type of an event to <code>SWT.None</code> from
+ * within the <code>handleEvent()</code> method can be used to
+ * change the event type and stop subsequent Java listeners
+ * from running. Because event filters run before other listeners,
+ * event filters can both block other listeners and set arbitrary
+ * fields within an event. For this reason, event filters are both
+ * powerful and dangerous. They should generally be avoided for
+ * performance, debugging and code maintenance reasons.
+ * </p>
+ *
+ * @param eventType the type of event to listen for
+ * @param listener the listener which should be notified when the event occurs
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see Listener
+ * @see SWT
+ * @see #removeFilter
+ * @see #removeListener
+ *
+ * @since 3.0
+ */
+public void addFilter (int eventType, Listener listener) {
+ checkDevice ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (filterTable == null) filterTable = new EventTable ();
+ filterTable.hook (eventType, listener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when an event of the given type occurs. The event
+ * type is one of the event constants defined in class <code>SWT</code>.
+ * When the event does occur in the display, the listener is notified by
+ * sending it the <code>handleEvent()</code> message.
+ *
+ * @param eventType the type of event to listen for
+ * @param listener the listener which should be notified when the event occurs
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see Listener
+ * @see SWT
+ * @see #removeListener
+ *
+ * @since 2.0
+ */
+public void addListener (int eventType, Listener listener) {
+ checkDevice ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) eventTable = new EventTable ();
+ eventTable.hook (eventType, listener);
+}
+
+void addPopup (Menu menu) {
+ if (popups == null) popups = new Menu [4];
+ int length = popups.length;
+ for (int i=0; i<length; i++) {
+ if (popups [i] == menu) return;
+ }
+ int index = 0;
+ while (index < length) {
+ if (popups [index] == null) break;
+ index++;
+ }
+ if (index == length) {
+ Menu [] newPopups = new Menu [length + 4];
+ System.arraycopy (popups, 0, newPopups, 0, length);
+ popups = newPopups;
+ }
+ popups [index] = menu;
+}
+
+/**
+ * Causes the <code>run()</code> method of the runnable to
+ * be invoked by the user-interface thread at the next
+ * reasonable opportunity. The caller of this method continues
+ * to run in parallel, and is not notified when the
+ * runnable has completed. Specifying <code>null</code> as the
+ * runnable simply wakes the user-interface thread when run.
+ * <p>
+ * Note that at the time the runnable is invoked, widgets
+ * that have the receiver as their display may have been
+ * disposed. Therefore, it is necessary to check for this
+ * case inside the runnable before accessing the widget.
+ * </p>
+ *
+ * @param runnable code to run on the user-interface thread or <code>null</code>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see #syncExec
+ */
+public void asyncExec (Runnable runnable) {
+ if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
+ synchronizer.asyncExec (runnable);
+}
+
+/**
+ * Causes the system hardware to emit a short sound
+ * (if it supports this capability).
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public void beep () {
+ checkDevice ();
+ OS.Console_Beep ();
+}
+
+/**
+ * Checks that this class can be subclassed.
+ * <p>
+ * IMPORTANT: See the comment in <code>Widget.checkSubclass()</code>.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see Widget#checkSubclass
+ */
+protected void checkSubclass () {
+ if (!isValidClass (getClass ())) error (SWT.ERROR_INVALID_SUBCLASS);
+}
+
+protected void checkDevice () {
+ if (thread == null) error (SWT.ERROR_WIDGET_DISPOSED);
+ if (thread != Thread.currentThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
+ if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
+}
+
+static synchronized void checkDisplay (Thread thread, boolean multiple) {
+ for (int i=0; i<Displays.length; i++) {
+ if (Displays [i] != null) {
+ if (!multiple) SWT.error (SWT.ERROR_NOT_IMPLEMENTED, null, " [multiple displays]");
+ if (Displays [i].thread == thread) SWT.error (SWT.ERROR_THREAD_INVALID_ACCESS);
+ }
+ }
+}
+
+void checkExitFrame (int e) {
+ int operation = OS.DispatcherHookEventArgs_Operation (e);
+ int priority = OS.DispatcherOperation_Priority (operation);
+ OS.GCHandle_Free (operation);
+ if (priority != OS.DispatcherPriority_Send) {
+ OS.DispatcherFrame_Continue (frame, false);
+ }
+}
+
+void clearModal (Shell shell) {
+// if (modalShells == null) return;
+// int index = 0, length = modalShells.length;
+// while (index < length) {
+// if (modalShells [index] == shell) break;
+// if (modalShells [index] == null) return;
+// index++;
+// }
+// if (index == length) return;
+// System.arraycopy (modalShells, index + 1, modalShells, index, --length - index);
+// modalShells [length] = null;
+// if (index == 0 && modalShells [0] == null) modalShells = null;
+// Shell [] shells = getShells ();
+// for (int i=0; i<shells.length; i++) shells [i].updateModal ();
+}
+
+/**
+ * Requests that the connection between SWT and the underlying
+ * operating system be closed.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see Device#dispose
+ *
+ * @since 2.0
+ */
+public void close () {
+ checkDevice ();
+ Event event = new Event ();
+ sendEvent (SWT.Close, event);
+ if (event.doit) dispose ();
+}
+
+/**
+ * Creates the device in the operating system. If the device
+ * does not have a handle, this method may do nothing depending
+ * on the device.
+ * <p>
+ * This method is called before <code>init</code>.
+ * </p>
+ *
+ * @param data the DeviceData which describes the receiver
+ *
+ * @see #init
+ */
+protected void create (DeviceData data) {
+ checkSubclass ();
+ checkDisplay (thread = Thread.currentThread (), true);
+ createDisplay (data);
+ register (this);
+ if (Default == null) Default = this;
+}
+
+void createDisplay (DeviceData data) {
+ COM.OleInitialize (0);
+ application = OS.gcnew_Application();
+ if (application == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+ OS.Application_ShutdownMode (application, OS.ShutdownMode_OnExplicitShutdown);
+}
+
+static synchronized void deregister (Display display) {
+ for (int i=0; i<Displays.length; i++) {
+ if (display == Displays [i]) Displays [i] = null;
+ }
+}
+
+/**
+ * Destroys the device in the operating system and releases
+ * the device's handle. If the device does not have a handle,
+ * this method may do nothing depending on the device.
+ * <p>
+ * This method is called after <code>release</code>.
+ * </p>
+ * @see Device#dispose
+ * @see #release
+ */
+protected void destroy () {
+ if (this == Default) Default = null;
+ deregister (this);
+ destroyDisplay ();
+}
+
+void destroyDisplay () {
+}
+
+/**
+ * Causes the <code>run()</code> method of the runnable to
+ * be invoked by the user-interface thread just before the
+ * receiver is disposed. Specifying a <code>null</code> runnable
+ * is ignored.
+ *
+ * @param runnable code to run at dispose time.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public void disposeExec (Runnable runnable) {
+ checkDevice ();
+ if (disposeList == null) disposeList = new Runnable [4];
+ for (int i=0; i<disposeList.length; i++) {
+ if (disposeList [i] == null) {
+ disposeList [i] = runnable;
+ return;
+ }
+ }
+ Runnable [] newDisposeList = new Runnable [disposeList.length + 4];
+ System.arraycopy (disposeList, 0, newDisposeList, 0, disposeList.length);
+ newDisposeList [disposeList.length] = runnable;
+ disposeList = newDisposeList;
+}
+
+/**
+ * Does whatever display specific cleanup is required, and then
+ * uses the code in <code>SWTError.error</code> to handle the error.
+ *
+ * @param code the descriptive error code
+ *
+ * @see SWT#error(int)
+ */
+void error (int code) {
+ SWT.error (code);
+}
+
+boolean filterEvent (Event event) {
+ if (filterTable != null) filterTable.sendEvent (event);
+ return false;
+}
+
+boolean filters (int eventType) {
+ if (filterTable == null) return false;
+ return filterTable.hooks (eventType);
+}
+
+/**
+ * Given the operating system handle for a widget, returns
+ * the instance of the <code>Widget</code> subclass which
+ * represents it in the currently running application, if
+ * such exists, or null if no matching widget can be found.
+ * <p>
+ * <b>IMPORTANT:</b> This method should not be called from
+ * application code. The arguments are platform-specific.
+ * </p>
+ *
+ * @param handle the handle for the widget
+ * @return the SWT widget that the handle represents
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public Widget findWidget (int handle) {
+ checkDevice ();
+ return getWidget (handle);
+}
+
+/**
+ * Given the operating system handle for a widget,
+ * and widget-specific id, returns the instance of
+ * the <code>Widget</code> subclass which represents
+ * the handle/id pair in the currently running application,
+ * if such exists, or null if no matching widget can be found.
+ * <p>
+ * <b>IMPORTANT:</b> This method should not be called from
+ * application code. The arguments are platform-specific.
+ * </p>
+ *
+ * @param handle the handle for the widget
+ * @param id the id for the subwidget (usually an item)
+ * @return the SWT widget that the handle/id pair represents
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public Widget findWidget (int handle, int id) {
+ checkDevice ();
+ return null;
+}
+
+/**
+ * Given a widget and a widget-specific id, returns the
+ * instance of the <code>Widget</code> subclass which represents
+ * the widget/id pair in the currently running application,
+ * if such exists, or null if no matching widget can be found.
+ *
+ * @param widget the widget
+ * @param id the id for the subwidget (usually an item)
+ * @return the SWT subwidget (usually an item) that the widget/id pair represents
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 3.3
+ */
+public Widget findWidget (Widget widget, int id) {
+ checkDevice ();
+ return null;
+}
+
+/**
+ * Returns the display which the given thread is the
+ * user-interface thread for, or null if the given thread
+ * is not a user-interface thread for any display. Specifying
+ * <code>null</code> as the thread will return <code>null</code>
+ * for the display.
+ *
+ * @param thread the user-interface thread
+ * @return the display for the given thread
+ */
+public static synchronized Display findDisplay (Thread thread) {
+ for (int i=0; i<Displays.length; i++) {
+ Display display = Displays [i];
+ if (display != null && display.thread == thread) {
+ return display;
+ }
+ }
+ return null;
+}
+
+/**
+ * Returns the currently active <code>Shell</code>, or null
+ * if no shell belonging to the currently running application
+ * is active.
+ *
+ * @return the active shell or null
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public Shell getActiveShell () {
+ checkDevice ();
+ int windows = OS.Application_Windows (application);
+ int count = OS.WindowCollection_Count (windows);
+ int activeWindow = 0;
+ if (count != 0) {
+ int enumerator = OS.WindowCollection_GetEnumerator (windows);
+ while (OS.IEnumerator_MoveNext (enumerator)) {
+ int window = OS.WindowCollection_Current (enumerator);
+ if (OS.Window_IsActive (window)) {
+ activeWindow = window;
+ break;
+ }
+ OS.GCHandle_Free (window);
+ }
+ OS.GCHandle_Free (enumerator);
+ }
+ OS.GCHandle_Free (windows);
+ Shell shell = (Shell)getWidget (activeWindow);
+ if (activeWindow != 0) OS.GCHandle_Free (activeWindow);
+ return shell;
+}
+
+/**
+ * Returns a rectangle describing the receiver's size and location.
+ *
+ * @return the bounding rectangle
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public Rectangle getBounds () {
+ checkDevice ();
+ if (true/*OS.GetSystemMetrics (OS.SM_CMONITORS) < 2*/) {
+ int width = (int) OS.SystemParameters_PrimaryScreenWidth ();
+ int height = (int) OS.SystemParameters_PrimaryScreenHeight ();
+ return new Rectangle (0, 0, width, height);
+ }
+ int x = (int) OS.SystemParameters_VirtualScreenLeft ();
+ int y = (int) OS.SystemParameters_VirtualScreenTop ();
+ int width = (int) OS.SystemParameters_VirtualScreenWidth ();
+ int height = (int) OS.SystemParameters_VirtualScreenHeight ();
+ return new Rectangle (x, y, width, height);
+}
+
+/**
+ * Returns the display which the currently running thread is
+ * the user-interface thread for, or null if the currently
+ * running thread is not a user-interface thread for any display.
+ *
+ * @return the current display
+ */
+public static synchronized Display getCurrent () {
+ return findDisplay (Thread.currentThread ());
+}
+
+/**
+ * Returns a rectangle which describes the area of the
+ * receiver which is capable of displaying data.
+ *
+ * @return the client area
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see #getBounds
+ */
+public Rectangle getClientArea () {
+ checkDevice ();
+ if (true/*OS.GetSystemMetrics (OS.SM_CMONITORS) < 2*/) {
+ int rect = OS.SystemParameters_WorkArea ();
+ int x = (int) OS.Rect_X (rect);
+ int y = (int) OS.Rect_Y (rect);
+ int width = (int) OS.Rect_Width (rect);
+ int height = (int) OS.Rect_Height (rect);
+ OS.GCHandle_Free (rect);
+ return new Rectangle (x, y, width, height);
+ }
+ int x = (int) OS.SystemParameters_VirtualScreenLeft ();
+ int y = (int) OS.SystemParameters_VirtualScreenTop ();
+ int width = (int) OS.SystemParameters_VirtualScreenWidth ();
+ int height = (int) OS.SystemParameters_VirtualScreenHeight ();
+ return new Rectangle (x, y, width, height);
+}
+
+Widget getWidget (int handle) {
+ if (handle == 0) return null;
+ int frameworkElementType = OS.FrameworkElement_typeid ();
+ int frameworkContentElementType = OS.FrameworkContentElement_typeid ();
+ int widget = handle;
+ int jniRef = 0;
+ do {
+ int parent = 0;
+ if (OS.Type_IsInstanceOfType (frameworkElementType, widget)) {
+ int tag = OS.FrameworkElement_Tag (widget);
+ if (tag != 0) {
+ jniRef = OS.IntPtr_ToInt32 (tag);
+ OS.GCHandle_Free (tag);
+ break;
+ }
+ parent = OS.FrameworkElement_Parent (widget);
+ if (parent == 0) {
+ parent = OS.VisualTreeHelper_GetParent (widget);
+ }
+ } else {
+ if (OS.Type_IsInstanceOfType (frameworkContentElementType, widget)) {
+ parent = OS.FrameworkContentElement_Parent (widget);
+ }
+ }
+ if (widget != handle) OS.GCHandle_Free (widget);
+ widget = parent;
+ } while (widget != 0);
+ if (widget != handle && widget != 0) OS.GCHandle_Free (widget);
+ OS.GCHandle_Free (frameworkElementType);
+ OS.GCHandle_Free (frameworkContentElementType);
+ return jniRef != 0 ? (Widget) OS.JNIGetObject (jniRef) : null;
+}
+
+/**
+ * Returns the control which the on-screen pointer is currently
+ * over top of, or null if it is not currently over one of the
+ * controls built by the currently running application.
+ *
+ * @return the control under the cursor
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public Control getCursorControl () {
+ checkDevice ();
+ int inputElement = OS.Mouse_DirectlyOver ();
+ if (inputElement != 0) {
+ Widget widget = getWidget (inputElement);
+ OS.GCHandle_Free (inputElement);
+ if (widget != null) return widget.getWidgetControl ();
+ }
+ return null;
+}
+
+/**
+ * Returns the location of the on-screen pointer relative
+ * to the top left corner of the screen.
+ *
+ * @return the cursor location
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public Point getCursorLocation () {
+ checkDevice ();
+ POINT pt = new POINT ();
+ OS.GetCursorPos (pt);
+ return new Point (pt.x, pt.y);
+}
+
+/**
+ * Returns an array containing the recommended cursor sizes.
+ *
+ * @return the array of cursor sizes
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public Point [] getCursorSizes () {
+ checkDevice ();
+// return new Point [] {
+// new Point (OS.GetSystemMetrics (OS.SM_CXCURSOR), OS.GetSystemMetrics (OS.SM_CYCURSOR))};
+ return null;
+}
+
+/**
+ * Returns the default display. One is created (making the
+ * thread that invokes this method its user-interface thread)
+ * if it did not already exist.
+ *
+ * @return the default display
+ */
+public static synchronized Display getDefault () {
+ if (Default == null) Default = new Display ();
+ return Default;
+}
+
+static boolean isValidClass (Class clazz) {
+ String name = clazz.getName ();
+ int index = name.lastIndexOf ('.');
+ return name.substring (0, index + 1).equals (PACKAGE_PREFIX);
+}
+
+/**
+ * Returns the application defined property of the receiver
+ * with the specified name, or null if it has not been set.
+ * <p>
+ * Applications may have associated arbitrary objects with the
+ * receiver in this fashion. If the objects stored in the
+ * properties need to be notified when the display is disposed
+ * of, it is the application's responsibility to provide a
+ * <code>disposeExec()</code> handler which does so.
+ * </p>
+ *
+ * @param key the name of the property
+ * @return the value of the property or null if it has not been set
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the key is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see #setData(String, Object)
+ * @see #disposeExec(Runnable)
+ */
+public Object getData (String key) {
+ checkDevice ();
+ if (key == null) error (SWT.ERROR_NULL_ARGUMENT);
+// if (key.equals (RUN_MESSAGES_IN_IDLE_KEY)) {
+// return new Boolean (runMessagesInIdle);
+// }
+ if (keys == null) return null;
+ for (int i=0; i<keys.length; i++) {
+ if (keys [i].equals (key)) return values [i];
+ }
+ return null;
+}
+
+/**
+ * Returns the application defined, display specific data
+ * associated with the receiver, or null if it has not been
+ * set. The <em>display specific data</em> is a single,
+ * unnamed field that is stored with every display.
+ * <p>
+ * Applications may put arbitrary objects in this field. If
+ * the object stored in the display specific data needs to
+ * be notified when the display is disposed of, it is the
+ * application's responsibility to provide a
+ * <code>disposeExec()</code> handler which does so.
+ * </p>
+ *
+ * @return the display specific data
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see #setData(Object)
+ * @see #disposeExec(Runnable)
+ */
+public Object getData () {
+ checkDevice ();
+ return data;
+}
+
+/**
+ * Returns the button dismissal alignment, one of <code>LEFT</code> or <code>RIGHT</code>.
+ * The button dismissal alignment is the ordering that should be used when positioning the
+ * default dismissal button for a dialog. For example, in a dialog that contains an OK and
+ * CANCEL button, on platforms where the button dismissal alignment is <code>LEFT</code>, the
+ * button ordering should be OK/CANCEL. When button dismissal alignment is <code>RIGHT</code>,
+ * the button ordering should be CANCEL/OK.
+ *
+ * @return the button dismissal order
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1
+ */
+public int getDismissalAlignment () {
+ checkDevice ();
+ return SWT.LEFT;
+}
+
+
+/**
+ * Returns the longest duration, in milliseconds, between
+ * two mouse button clicks that will be considered a
+ * <em>double click</em> by the underlying operating system.
+ *
+ * @return the double click time
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public int getDoubleClickTime () {
+ checkDevice ();
+ //TODO
+ return 500;
+}
+
+/**
+ * Returns the control which currently has keyboard focus,
+ * or null if keyboard events are not currently going to
+ * any of the controls built by the currently running
+ * application.
+ *
+ * @return the control under the cursor
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public Control getFocusControl () {
+ checkDevice ();
+ return _getFocusControl ();
+}
+
+/**
+ * Returns true when the high contrast mode is enabled.
+ * Otherwise, false is returned.
+ * <p>
+ * Note: This operation is a hint and is not supported on
+ * platforms that do not have this concept.
+ * </p>
+ *
+ * @return the high contrast mode
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public boolean getHighContrast () {
+ checkDevice ();
+ return OS.SystemParameters_HighContrast ();
+}
+
+/**
+ * Returns the maximum allowed depth of icons on this display, in bits per pixel.
+ * On some platforms, this may be different than the actual depth of the display.
+ *
+ * @return the maximum icon depth
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see Device#getDepth
+ */
+public int getIconDepth () {
+ checkDevice ();
+// if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (5, 1)) {
+// if (getDepth () >= 24) return 32;
+// }
+//
+// /* Use the character encoding for the default locale */
+// TCHAR buffer1 = new TCHAR (0, "Control Panel\\Desktop\\WindowMetrics", true); //$NON-NLS-1$
+//
+// int [] phkResult = new int [1];
+// int result = OS.RegOpenKeyEx (OS.HKEY_CURRENT_USER, buffer1, 0, OS.KEY_READ, phkResult);
+// if (result != 0) return 4;
+ int depth = 4;
+// int [] lpcbData = new int [1];
+//
+// /* Use the character encoding for the default locale */
+// TCHAR buffer2 = new TCHAR (0, "Shell Icon BPP", true); //$NON-NLS-1$
+// result = OS.RegQueryValueEx (phkResult [0], buffer2, 0, null, (TCHAR) null, lpcbData);
+// if (result == 0) {
+// TCHAR lpData = new TCHAR (0, lpcbData [0] / TCHAR.sizeof);
+// result = OS.RegQueryValueEx (phkResult [0], buffer2, 0, null, lpData, lpcbData);
+// if (result == 0) {
+// try {
+// depth = Integer.parseInt (lpData.toString (0, lpData.strlen ()));
+// } catch (NumberFormatException e) {}
+// }
+// }
+// OS.RegCloseKey (phkResult [0]);
+ return depth;
+}
+
+/**
+ * Returns an array containing the recommended icon sizes.
+ *
+ * @return the array of icon sizes
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see Decorations#setImages(Image[])
+ *
+ * @since 3.0
+ */
+public Point [] getIconSizes () {
+ checkDevice ();
+ //TODO
+// return new Point [] {
+// new Point (OS.GetSystemMetrics (OS.SM_CXSMICON), OS.GetSystemMetrics (OS.SM_CYSMICON)),
+// new Point (OS.GetSystemMetrics (OS.SM_CXICON), OS.GetSystemMetrics (OS.SM_CYICON)),
+// };
+ return null;
+}
+
+int getLastEventTime () {
+ //TODO - use OS
+ return (int)System.currentTimeMillis();
+}
+
+int getMessageCount () {
+ return synchronizer.getMessageCount ();
+}
+
+
+Shell getModalShell () {
+ if (modalShells == null) return null;
+ int index = modalShells.length;
+ while (--index >= 0) {
+ Shell shell = modalShells [index];
+ if (shell != null) return shell;
+ }
+ return null;
+}
+
+Shell getModalDialogShell () {
+ if (modalDialogShell != null && modalDialogShell.isDisposed ()) modalDialogShell = null;
+ return modalDialogShell;
+}
+
+/**
+ * Returns an array of monitors attached to the device.
+ *
+ * @return the array of monitors
+ *
+ * @since 3.0
+ */
+public Monitor [] getMonitors () {
+ checkDevice ();
+ //TODO
+ return new Monitor [] { getPrimaryMonitor() };
+}
+
+/**
+ * Returns the primary monitor for that device.
+ *
+ * @return the primary monitor
+ *
+ * @since 3.0
+ */
+public Monitor getPrimaryMonitor () {
+ checkDevice ();
+ Monitor monitor = new Monitor ();
+ monitor.x = 0;
+ monitor.y = 0;
+ monitor.width = (int) OS.SystemParameters_PrimaryScreenWidth ();
+ monitor.height = (int) OS.SystemParameters_PrimaryScreenHeight ();
+ monitor.clientX = (int) OS.SystemParameters_VirtualScreenLeft ();
+ monitor.clientY = (int) OS.SystemParameters_VirtualScreenTop ();
+ monitor.clientWidth = (int) OS.SystemParameters_VirtualScreenWidth ();
+ monitor.clientHeight = (int) OS.SystemParameters_VirtualScreenHeight ();
+ return monitor;
+}
+
+/**
+ * Returns a (possibly empty) array containing all shells which have
+ * not been disposed and have the receiver as their display.
+ *
+ * @return the receiver's shells
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public Shell [] getShells () {
+ checkDevice ();
+ int index = 0;
+ int windows = OS.Application_Windows (application);
+ int count = OS.WindowCollection_Count (windows);
+ Shell [] result = new Shell [count];
+ if (count != 0) {
+ int enumerator = OS.WindowCollection_GetEnumerator (windows);
+ while (OS.IEnumerator_MoveNext (enumerator)) {
+ int window = OS.WindowCollection_Current (enumerator);
+ Widget widget = getWidget (window);
+ if (widget != null && widget instanceof Shell) {
+ result [index++] = (Shell) widget;
+ }
+ OS.GCHandle_Free (window);
+ }
+ OS.GCHandle_Free (enumerator);
+ }
+ OS.GCHandle_Free (windows);
+ if (index == result.length) return result;
+ Shell [] newResult = new Shell [index];
+ System.arraycopy (result, 0, newResult, 0, index);
+ return newResult;
+}
+
+/**
+ * Returns the thread that has invoked <code>syncExec</code>
+ * or null if no such runnable is currently being invoked by
+ * the user-interface thread.
+ * <p>
+ * Note: If a runnable invoked by asyncExec is currently
+ * running, this method will return null.
+ * </p>
+ *
+ * @return the receiver's sync-interface thread
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public Thread getSyncThread () {
+ if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
+ return synchronizer.syncThread;
+}
+
+/**
+ * Returns the matching standard color for the given
+ * constant, which should be one of the color constants
+ * specified in class <code>SWT</code>. Any value other
+ * than one of the SWT color constants which is passed
+ * in will result in the color black. This color should
+ * not be free'd because it was allocated by the system,
+ * not the application.
+ *
+ * @param id the color constant
+ * @return the matching color
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see SWT
+ */
+public Color getSystemColor (int id) {
+ checkDevice ();
+ Color color = null;
+ if (0 <= id && id < colors.length) {
+ color = colors [id];
+ }
+ return color != null ? color : super.getSystemColor (id);
+}
+
+/**
+ * Returns the matching standard platform cursor for the given
+ * constant, which should be one of the cursor constants
+ * specified in class <code>SWT</code>. This cursor should
+ * not be free'd because it was allocated by the system,
+ * not the application. A value of <code>null</code> will
+ * be returned if the supplied constant is not an SWT cursor
+ * constant.
+ *
+ * @param id the SWT cursor constant
+ * @return the corresponding cursor or <code>null</code>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see SWT#CURSOR_ARROW
+ * @see SWT#CURSOR_WAIT
+ * @see SWT#CURSOR_CROSS
+ * @see SWT#CURSOR_APPSTARTING
+ * @see SWT#CURSOR_HELP
+ * @see SWT#CURSOR_SIZEALL
+ * @see SWT#CURSOR_SIZENESW
+ * @see SWT#CURSOR_SIZENS
+ * @see SWT#CURSOR_SIZENWSE
+ * @see SWT#CURSOR_SIZEWE
+ * @see SWT#CURSOR_SIZEN
+ * @see SWT#CURSOR_SIZES
+ * @see SWT#CURSOR_SIZEE
+ * @see SWT#CURSOR_SIZEW
+ * @see SWT#CURSOR_SIZENE
+ * @see SWT#CURSOR_SIZESE
+ * @see SWT#CURSOR_SIZESW
+ * @see SWT#CURSOR_SIZENW
+ * @see SWT#CURSOR_UPARROW
+ * @see SWT#CURSOR_IBEAM
+ * @see SWT#CURSOR_NO
+ * @see SWT#CURSOR_HAND
+ *
+ * @since 3.0
+ */
+public Cursor getSystemCursor (int id) {
+ checkDevice ();
+ if (!(0 <= id && id < cursors.length)) return null;
+ if (cursors [id] == null) {
+ cursors [id] = new Cursor (this, id);
+ }
+ return cursors [id];
+}
+
+/**
+ * Returns the matching standard platform image for the given
+ * constant, which should be one of the icon constants
+ * specified in class <code>SWT</code>. This image should
+ * not be free'd because it was allocated by the system,
+ * not the application. A value of <code>null</code> will
+ * be returned either if the supplied constant is not an
+ * SWT icon constant or if the platform does not define an
+ * image that corresponds to the constant.
+ *
+ * @param id the SWT icon constant
+ * @return the corresponding image or <code>null</code>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see SWT#ICON_ERROR
+ * @see SWT#ICON_INFORMATION
+ * @see SWT#ICON_QUESTION
+ * @see SWT#ICON_WARNING
+ * @see SWT#ICON_WORKING
+ *
+ * @since 3.0
+ */
+public Image getSystemImage (int id) {
+ checkDevice ();
+ switch (id) {
+ case SWT.ICON_ERROR: {
+ if (errorImage != null) return errorImage;
+ int hIcon = OS.LoadImage (0, OS.OIC_HAND, OS.IMAGE_ICON, 0, 0, OS.LR_SHARED);
+ int empty = OS.Int32Rect_Empty ();
+ int source = OS.Imaging_CreateBitmapSourceFromHIcon (hIcon, empty, 0);
+ errorImage = Image.wpf_new (this, SWT.BITMAP, source);
+ OS.GCHandle_Free (empty);
+ OS.DestroyIcon (hIcon);
+ return errorImage;
+ }
+ case SWT.ICON_WORKING:
+ case SWT.ICON_INFORMATION: {
+ if (infoImage != null) return infoImage;
+ int hIcon = OS.LoadImage (0, OS.OIC_INFORMATION, OS.IMAGE_ICON, 0, 0, OS.LR_SHARED);
+ int empty = OS.Int32Rect_Empty ();
+ int source = OS.Imaging_CreateBitmapSourceFromHIcon (hIcon, empty, 0);
+ infoImage = Image.wpf_new (this, SWT.BITMAP, source);
+ OS.GCHandle_Free (empty);
+ OS.DestroyIcon (hIcon);
+ return infoImage;
+ }
+ case SWT.ICON_QUESTION: {
+ if (questionImage != null) return questionImage;
+ int hIcon = OS.LoadImage (0, OS.OIC_QUES, OS.IMAGE_ICON, 0, 0, OS.LR_SHARED);
+ int empty = OS.Int32Rect_Empty ();
+ int source = OS.Imaging_CreateBitmapSourceFromHIcon (hIcon, empty, 0);
+ questionImage = Image.wpf_new (this, SWT.BITMAP, source);
+ OS.GCHandle_Free (empty);
+ OS.DestroyIcon (hIcon);
+ return questionImage;
+ }
+ case SWT.ICON_WARNING: {
+ if (warningIcon != null) return warningIcon;
+ int hIcon = OS.LoadImage (0, OS.OIC_BANG, OS.IMAGE_ICON, 0, 0, OS.LR_SHARED);
+ int empty = OS.Int32Rect_Empty ();
+ int source = OS.Imaging_CreateBitmapSourceFromHIcon (hIcon, empty, 0);
+ warningIcon = Image.wpf_new (this, SWT.BITMAP, source);
+ OS.GCHandle_Free (empty);
+ OS.DestroyIcon (hIcon);
+ return warningIcon;
+ }
+ }
+ return null;
+}
+
+/**
+ * Returns the single instance of the system tray or null
+ * when there is no system tray available for the platform.
+ *
+ * @return the system tray or <code>null</code>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public Tray getSystemTray () {
+ checkDevice ();
+ if (tray != null) return tray;
+ tray = new Tray (this, SWT.NONE);
+ return tray;
+}
+
+/**
+ * Returns the user-interface thread for the receiver.
+ *
+ * @return the receiver's user-interface thread
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public Thread getThread () {
+ if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
+ return thread;
+}
+
+/**
+ * Invokes platform specific functionality to allocate a new GC handle.
+ * <p>
+ * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
+ * API for <code>Display</code>. It is marked public only so that it
+ * can be shared within the packages provided by SWT. It is not
+ * available on all platforms, and should never be called from
+ * application code.
+ * </p>
+ *
+ * @param data the platform specific GC data
+ * @return the platform specific GC handle
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ * @exception SWTError <ul>
+ * <li>ERROR_NO_HANDLES if a handle could not be obtained for gc creation</li>
+ * </ul>
+ */
+public int internal_new_GC (GCData data) {
+ if (isDisposed()) SWT.error(SWT.ERROR_DEVICE_DISPOSED);
+ //TODO
+ return 0;
+}
+
+/**
+ * Initializes any internal resources needed by the
+ * device.
+ * <p>
+ * This method is called after <code>create</code>.
+ * </p>
+ *
+ * @see #create
+ */
+protected void init () {
+ super.init ();
+
+ dispatcher = OS.Application_Dispatcher (application);
+ if (dispatcher == 0) SWT.error (SWT.ERROR_NO_HANDLES);
+ frame = OS.gcnew_DispatcherFrame ();
+ if (frame == 0) SWT.error (SWT.ERROR_NO_HANDLES);
+ jniRef = OS.NewGlobalRef (this);
+ if (jniRef == 0) SWT.error (SWT.ERROR_NO_HANDLES);
+ int hooks = OS.Dispatcher_Hooks (dispatcher);
+ int handler = OS.gcnew_EventHandler (jniRef, "HandleDispatcherInactive");
+ OS.DispatcherHooks_DispatcherInactive (hooks, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_DispatcherHookEventHandler (jniRef, "HandleOperationCompleted");
+ OS.DispatcherHooks_OperationCompleted (hooks, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_DispatcherHookEventHandler (jniRef, "HandleOperationPosted");
+ OS.DispatcherHooks_OperationPosted (hooks, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_DispatcherHookEventHandler (jniRef, "HandleOperationAborted");
+ OS.DispatcherHooks_OperationAborted (hooks, handler);
+ OS.GCHandle_Free (handler);
+ OS.GCHandle_Free (hooks);
+ timerHandler = OS.gcnew_TimerHandler(jniRef, "timerProc");
+
+
+ /* Create the standard colors */
+ colors = new Color [SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT + 1];
+ colors [SWT.COLOR_WIDGET_DARK_SHADOW] = Color.wpf_new( this, OS.SystemColors_ControlDarkDarkColor ());
+ colors [SWT.COLOR_WIDGET_NORMAL_SHADOW] = Color.wpf_new (this, OS.SystemColors_ControlDarkColor ());
+ colors [SWT.COLOR_WIDGET_LIGHT_SHADOW] = Color.wpf_new (this, OS.SystemColors_ControlLightColor ());
+ colors [SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW] = Color.wpf_new (this, OS.SystemColors_ControlDarkDarkColor ());
+ colors [SWT.COLOR_WIDGET_FOREGROUND] = Color.wpf_new (this, OS.SystemColors_ControlTextColor ());
+ colors [SWT.COLOR_WIDGET_BACKGROUND] = Color.wpf_new (this, OS.SystemColors_ControlColor ());
+ colors [SWT.COLOR_WIDGET_BORDER] = Color.wpf_new (this, OS.SystemColors_ActiveBorderColor ());
+ colors [SWT.COLOR_LIST_FOREGROUND] = Color.wpf_new (this, OS.SystemColors_WindowTextColor ());
+ colors [SWT.COLOR_LIST_BACKGROUND] = Color.wpf_new (this, OS.SystemColors_WindowColor ());
+// colors [SWT.COLOR_LIST_SELECTION] = Color.wpf_new (this, OS.SystemColors_HighlightColor ());
+ colors [SWT.COLOR_LIST_SELECTION] = Color.wpf_new (this, OS.Colors_LightSkyBlue ());
+ colors [SWT.COLOR_LIST_SELECTION_TEXT] = Color.wpf_new (this, OS.SystemColors_HighlightTextColor ());
+ colors [SWT.COLOR_INFO_FOREGROUND] = Color.wpf_new (this, OS.SystemColors_InfoTextColor ());
+ colors [SWT.COLOR_INFO_BACKGROUND] = Color.wpf_new (this, OS.SystemColors_InfoColor ());
+ colors [SWT.COLOR_TITLE_FOREGROUND] = Color.wpf_new (this, OS.SystemColors_ActiveCaptionTextColor ());
+ colors [SWT.COLOR_TITLE_BACKGROUND] = Color.wpf_new (this, OS.SystemColors_ActiveCaptionColor ());
+ colors [SWT.COLOR_TITLE_BACKGROUND_GRADIENT] = Color.wpf_new (this, OS.SystemColors_GradientActiveCaptionColor ());
+ colors [SWT.COLOR_TITLE_INACTIVE_FOREGROUND] = Color.wpf_new (this, OS.SystemColors_InactiveCaptionTextColor ());
+ colors [SWT.COLOR_TITLE_INACTIVE_BACKGROUND] = Color.wpf_new (this, OS.SystemColors_InactiveCaptionColor ());
+ colors [SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT] = Color.wpf_new (this, OS.SystemColors_GradientInactiveCaptionColor ());
+
+}
+
+void HandleDispatcherInactive (int sender, int e) {
+ if (runAsyncMessages (false)) wakeThread ();
+ idle = true;
+}
+
+void HandleOperationAborted (int sender, int e) {
+// operationCount--;
+ checkExitFrame (e);
+// idle = false;
+}
+
+void HandleOperationCompleted (int sender, int e) {
+// operationCount--;
+ checkExitFrame (e);
+ idle = false;
+}
+
+void HandleOperationPosted (int sender, int e) {
+// operationCount++;
+// idle = false;
+// wakeThread ();
+}
+
+/**
+ * Invokes platform specific functionality to dispose a GC handle.
+ * <p>
+ * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
+ * API for <code>Display</code>. It is marked public only so that it
+ * can be shared within the packages provided by SWT. It is not
+ * available on all platforms, and should never be called from
+ * application code.
+ * </p>
+ *
+ * @param hDC the platform specific GC handle
+ * @param data the platform specific GC data
+ */
+public void internal_dispose_GC (int hDC, GCData data) {
+}
+
+boolean isValidThread () {
+ return thread == Thread.currentThread ();
+}
+
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param point to be mapped
+ * @return point with mapped coordinates
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Point map (Control from, Control to, Point point) {
+ checkDevice ();
+ if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
+ return map (from, to, point.x, point.y);
+}
+
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param x coordinates to be mapped
+ * @param y coordinates to be mapped
+ * @return point with mapped coordinates
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Point map (Control from, Control to, int x, int y) {
+ checkDevice ();
+ if (from != null && from.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ int point = OS.gcnew_Point (x, y);
+ if (from != null && OS.FrameworkElement_IsLoaded(from.handle)) {
+ int result = OS.Visual_PointToScreen (from.handle, point);
+ OS.GCHandle_Free (point);
+ point = result;
+ }
+ if (to != null && OS.FrameworkElement_IsLoaded(to.handle)) {
+ int result = OS.Visual_PointFromScreen (to.handle, point);
+ OS.GCHandle_Free (point);
+ point = result;
+ }
+ Point result = new Point ((int)OS.Point_X (point), (int)OS.Point_Y (point));
+ OS.GCHandle_Free (point);
+ return result;
+}
+
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param rectangle to be mapped
+ * @return rectangle with mapped coordinates
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Rectangle map (Control from, Control to, Rectangle rectangle) {
+ checkDevice ();
+ if (rectangle == null) error (SWT.ERROR_NULL_ARGUMENT);
+ return map (from, to, rectangle.x, rectangle.y, rectangle.width, rectangle.height);
+}
+
+/**
+ * Maps a point from one coordinate system to another.
+ * When the control is null, coordinates are mapped to
+ * the display.
+ * <p>
+ * NOTE: On right-to-left platforms where the coordinate
+ * systems are mirrored, special care needs to be taken
+ * when mapping coordinates from one control to another
+ * to ensure the result is correctly mirrored.
+ *
+ * Mapping a point that is the origin of a rectangle and
+ * then adding the width and height is not equivalent to
+ * mapping the rectangle. When one control is mirrored
+ * and the other is not, adding the width and height to a
+ * point that was mapped causes the rectangle to extend
+ * in the wrong direction. Mapping the entire rectangle
+ * instead of just one point causes both the origin and
+ * the corner of the rectangle to be mapped.
+ * </p>
+ *
+ * @param from the source <code>Control</code> or <code>null</code>
+ * @param to the destination <code>Control</code> or <code>null</code>
+ * @param x coordinates to be mapped
+ * @param y coordinates to be mapped
+ * @param width coordinates to be mapped
+ * @param height coordinates to be mapped
+ * @return rectangle with mapped coordinates
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public Rectangle map (Control from, Control to, int x, int y, int width, int height) {
+ checkDevice ();
+ if (from != null && from.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ //FIXME - HACK
+ Point point = map(from, to, x, y);
+ return new Rectangle (point.x, point.y, width, height);
+}
+
+/**
+ * Generate a low level system event.
+ *
+ * <code>post</code> is used to generate low level keyboard
+ * and mouse events. The intent is to enable automated UI
+ * testing by simulating the input from the user. Most
+ * SWT applications should never need to call this method.
+ * <p>
+ * Note that this operation can fail when the operating system
+ * fails to generate the event for any reason. For example,
+ * this can happen when there is no such key or mouse button
+ * or when the system event queue is full.
+ * </p>
+ * <p>
+ * <b>Event Types:</b>
+ * <p>KeyDown, KeyUp
+ * <p>The following fields in the <code>Event</code> apply:
+ * <ul>
+ * <li>(in) type KeyDown or KeyUp</li>
+ * <p> Either one of:
+ * <li>(in) character a character that corresponds to a keyboard key</li>
+ * <li>(in) keyCode the key code of the key that was typed,
+ * as defined by the key code constants in class <code>SWT</code></li>
+ * </ul>
+ * <p>MouseDown, MouseUp</p>
+ * <p>The following fields in the <code>Event</code> apply:
+ * <ul>
+ * <li>(in) type MouseDown or MouseUp
+ * <li>(in) button the button that is pressed or released
+ * </ul>
+ * <p>MouseMove</p>
+ * <p>The following fields in the <code>Event</code> apply:
+ * <ul>
+ * <li>(in) type MouseMove
+ * <li>(in) x the x coordinate to move the mouse pointer to in screen coordinates
+ * <li>(in) y the y coordinate to move the mouse pointer to in screen coordinates
+ * </ul>
+ * </dl>
+ *
+ * @param event the event to be generated
+ *
+ * @return true if the event was generated or false otherwise
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the event is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 3.0
+ *
+ */
+public boolean post (Event event) {
+ if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
+ if (event == null) error (SWT.ERROR_NULL_ARGUMENT);
+// int type = event.type;
+// switch (type){
+// case SWT.KeyDown:
+// case SWT.KeyUp: {
+// KEYBDINPUT inputs = new KEYBDINPUT ();
+// inputs.wVk = (short) untranslateKey (event.keyCode);
+// if (inputs.wVk == 0) {
+// char key = event.character;
+// switch (key) {
+// case SWT.BS: inputs.wVk = (short) OS.VK_BACK; break;
+// case SWT.CR: inputs.wVk = (short) OS.VK_RETURN; break;
+// case SWT.DEL: inputs.wVk = (short) OS.VK_DELETE; break;
+// case SWT.ESC: inputs.wVk = (short) OS.VK_ESCAPE; break;
+// case SWT.TAB: inputs.wVk = (short) OS.VK_TAB; break;
+// /*
+// * Since there is no LF key on the keyboard, do not attempt
+// * to map LF to CR or attempt to post an LF key.
+// */
+//// case SWT.LF: inputs.wVk = (short) OS.VK_RETURN; break;
+// case SWT.LF: return false;
+// default: {
+// if (OS.IsWinCE) {
+// inputs.wVk = OS.CharUpper ((short) key);
+// } else {
+// inputs.wVk = OS.VkKeyScan ((short) wcsToMbcs (key, 0));
+// if (inputs.wVk == -1) return false;
+// inputs.wVk &= 0xFF;
+// }
+// }
+// }
+// }
+// inputs.dwFlags = type == SWT.KeyUp ? OS.KEYEVENTF_KEYUP : 0;
+// int hHeap = OS.GetProcessHeap ();
+// int pInputs = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, INPUT.sizeof);
+// OS.MoveMemory(pInputs, new int[] {OS.INPUT_KEYBOARD}, 4);
+// OS.MoveMemory (pInputs + 4, inputs, KEYBDINPUT.sizeof);
+// boolean result = OS.SendInput (1, pInputs, INPUT.sizeof) != 0;
+// OS.HeapFree (hHeap, 0, pInputs);
+// return result;
+// }
+// case SWT.MouseDown:
+// case SWT.MouseMove:
+// case SWT.MouseUp: {
+// MOUSEINPUT inputs = new MOUSEINPUT ();
+// if (type == SWT.MouseMove){
+// inputs.dwFlags = OS.MOUSEEVENTF_MOVE | OS.MOUSEEVENTF_ABSOLUTE;
+// inputs.dx = event.x * 65535 / (OS.GetSystemMetrics (OS.SM_CXSCREEN) - 1);
+// inputs.dy = event.y * 65535 / (OS.GetSystemMetrics (OS.SM_CYSCREEN) - 1);
+// } else {
+// switch (event.button) {
+// case 1: inputs.dwFlags = type == SWT.MouseDown ? OS.MOUSEEVENTF_LEFTDOWN : OS.MOUSEEVENTF_LEFTUP; break;
+// case 2: inputs.dwFlags = type == SWT.MouseDown ? OS.MOUSEEVENTF_MIDDLEDOWN : OS.MOUSEEVENTF_MIDDLEUP; break;
+// case 3: inputs.dwFlags = type == SWT.MouseDown ? OS.MOUSEEVENTF_RIGHTDOWN : OS.MOUSEEVENTF_RIGHTUP; break;
+// default: return false;
+// }
+// }
+// int hHeap = OS.GetProcessHeap ();
+// int pInputs = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, INPUT.sizeof);
+// OS.MoveMemory(pInputs, new int[] {OS.INPUT_MOUSE}, 4);
+// OS.MoveMemory (pInputs + 4, inputs, MOUSEINPUT.sizeof);
+// boolean result = OS.SendInput (1, pInputs, INPUT.sizeof) != 0;
+// OS.HeapFree (hHeap, 0, pInputs);
+// return result;
+// }
+// }
+ return false;
+}
+
+void postEvent (Event event) {
+ /*
+ * Place the event at the end of the event queue.
+ * This code is always called in the Display's
+ * thread so it must be re-enterant but does not
+ * need to be synchronized.
+ */
+ if (eventQueue == null) eventQueue = new Event [4];
+ int index = 0;
+ int length = eventQueue.length;
+ while (index < length) {
+ if (eventQueue [index] == null) break;
+ index++;
+ }
+ if (index == length) {
+ Event [] newQueue = new Event [length + 4];
+ System.arraycopy (eventQueue, 0, newQueue, 0, length);
+ eventQueue = newQueue;
+ }
+ eventQueue [index] = event;
+}
+
+void removePopup (Menu menu) {
+ if (popups == null) return;
+ for (int i=0; i<popups.length; i++) {
+ if (popups [i] == menu) {
+ popups [i] = null;
+ return;
+ }
+ }
+}
+
+/**
+ * Reads an event from the operating system's event queue,
+ * dispatches it appropriately, and returns <code>true</code>
+ * if there is potentially more work to do, or <code>false</code>
+ * if the caller can sleep until another event is placed on
+ * the event queue.
+ * <p>
+ * In addition to checking the system event queue, this method also
+ * checks if any inter-thread messages (created by <code>syncExec()</code>
+ * or <code>asyncExec()</code>) are waiting to be processed, and if
+ * so handles them before returning.
+ * </p>
+ *
+ * @return <code>false</code> if the caller can sleep upon return from this method
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_FAILED_EXEC - if an exception occurred while running an inter-thread message</li>
+ * </ul>
+ *
+ * @see #sleep
+ * @see #wake
+ */
+public boolean readAndDispatch () {
+ checkDevice ();
+// System.out.print("[");
+ runPopups ();
+ try {
+ OS.DispatcherFrame_Continue(frame, true);
+ OS.Dispatcher_PushFrame(frame);
+ if (!idle) {
+ runDeferredEvents();
+ return true;
+ }
+// return runAsyncMessages (false);
+ return true;
+ } finally {
+// System.out.print("]");
+ }
+}
+
+static synchronized void register (Display display) {
+ for (int i=0; i<Displays.length; i++) {
+ if (Displays [i] == null) {
+ Displays [i] = display;
+ return;
+ }
+ }
+ Display [] newDisplays = new Display [Displays.length + 4];
+ System.arraycopy (Displays, 0, newDisplays, 0, Displays.length);
+ newDisplays [Displays.length] = display;
+ Displays = newDisplays;
+}
+
+/**
+ * Releases any internal resources back to the operating
+ * system and clears all fields except the device handle.
+ * <p>
+ * Disposes all shells which are currently open on the display.
+ * After this method has been invoked, all related related shells
+ * will answer <code>true</code> when sent the message
+ * <code>isDisposed()</code>.
+ * </p><p>
+ * When a device is destroyed, resources that were acquired
+ * on behalf of the programmer need to be returned to the
+ * operating system. For example, if the device allocated a
+ * font to be used as the system font, this font would be
+ * freed in <code>release</code>. Also,to assist the garbage
+ * collector and minimize the amount of memory that is not
+ * reclaimed when the programmer keeps a reference to a
+ * disposed device, all fields except the handle are zero'd.
+ * The handle is needed by <code>destroy</code>.
+ * </p>
+ * This method is called before <code>destroy</code>.
+ *
+ * @see Device#dispose
+ * @see #destroy
+ */
+protected void release () {
+ sendEvent (SWT.Dispose, new Event ());
+ Shell [] shells = getShells ();
+ for (int i=0; i<shells.length; i++) {
+ Shell shell = shells [i];
+ if (!shell.isDisposed ()) shell.dispose ();
+ }
+ if (tray != null) tray.dispose ();
+ tray = null;
+
+ //hack... readAndDispatch Always returns true right now, prevents apps from shutting down.
+ //while (readAndDispatch ()) {}
+
+ if (disposeList != null) {
+ for (int i=0; i<disposeList.length; i++) {
+ if (disposeList [i] != null) disposeList [i].run ();
+ }
+ }
+ disposeList = null;
+ synchronizer.releaseSynchronizer ();
+ synchronizer = null;
+ releaseDisplay ();
+ super.release ();
+}
+
+void releaseDisplay () {
+ OS.Application_Shutdown(application);
+ if (application != 0) OS.GCHandle_Free (application);
+ application = 0;
+ if (dispatcher != 0) OS.GCHandle_Free (dispatcher);
+ dispatcher = 0;
+ if (frame != 0) OS.GCHandle_Free (frame);
+ frame = 0;
+ if (jniRef != 0) OS.DeleteGlobalRef (jniRef);
+ jniRef = 0;
+
+ for (int i = 0; i < colors.length; i++) {
+ if (colors [i] != null) colors [i].dispose ();
+ }
+ colors = null;
+
+ /* Release the timers */
+ OS.GCHandle_Free (timerHandler);
+ timerHandler = 0;
+ if (timerHandles != null) {
+ for (int i = 0; i < timerHandles.length; i++) {
+ int timer = timerHandles [i];
+ if (timer != 0) {
+ OS.DispatcherTimer_Stop (timer);
+ OS.GCHandle_Free (timer);
+ }
+ }
+ }
+ timerHandles = null;
+ timerList = null;
+
+// /* Release the System fonts */
+// if (systemFont != null) systemFont.dispose ();
+// systemFont = null;
+// lfSystemFont = null;
+//
+ /* Release the System Images */
+ if (errorImage != null) errorImage.dispose ();
+ if (infoImage != null) infoImage.dispose ();
+ if (questionImage != null) questionImage.dispose ();
+ if (warningIcon != null) warningIcon.dispose ();
+ errorImage = infoImage = questionImage = warningIcon = null;
+
+ /* Release the System Cursors */
+ for (int i = 0; i < cursors.length; i++) {
+ if (cursors [i] != null) cursors [i].dispose ();
+ }
+ cursors = null;
+
+// /* Release Acquired Resources */
+// if (resources != null) {
+// for (int i=0; i<resources.length; i++) {
+// if (resources [i] != null) resources [i].dispose ();
+// }
+// resources = null;
+// }
+//
+ /* Release Custom Colors for ChooseColor */
+ if (customColors != 0) OS.GCHandle_Free (customColors);
+ customColors = 0;
+
+ /* Release references */
+ thread = null;
+// keyboard = null;
+// modalDialogShell = null;
+// modalShells = null;
+// data = null;
+ keys = null;
+ values = null;
+ popups = null;
+
+ /* Uninitialize OLE */
+ COM.OleUninitialize ();
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when an event of the given type occurs anywhere in
+ * a widget. The event type is one of the event constants defined
+ * in class <code>SWT</code>.
+ *
+ * @param eventType the type of event to listen for
+ * @param listener the listener which should no longer be notified when the event occurs
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Listener
+ * @see SWT
+ * @see #addFilter
+ * @see #addListener
+ *
+ * @since 3.0
+ */
+public void removeFilter (int eventType, Listener listener) {
+ checkDevice ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (filterTable == null) return;
+ filterTable.unhook (eventType, listener);
+ if (filterTable.size () == 0) filterTable = null;
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when an event of the given type occurs. The event type
+ * is one of the event constants defined in class <code>SWT</code>.
+ *
+ * @param eventType the type of event to listen for
+ * @param listener the listener which should no longer be notified when the event occurs
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see Listener
+ * @see SWT
+ * @see #addListener
+ *
+ * @since 2.0
+ */
+public void removeListener (int eventType, Listener listener) {
+ checkDevice ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (eventType, listener);
+}
+
+Widget removeWidget (int handle) {
+ if (handle == 0) return null;
+ int tag = OS.FrameworkElement_Tag (handle), ref = 0;
+ if (tag != 0) {
+ ref = OS.IntPtr_ToInt32(tag);
+ OS.GCHandle_Free(tag);
+ }
+ Widget widget = null;
+ if (ref != 0) {
+ OS.FrameworkElement_Tag (handle, 0);
+ widget = (Widget) OS.JNIGetObject (ref);
+ }
+ return widget;
+}
+
+boolean runAsyncMessages (boolean all) {
+ return synchronizer.runAsyncMessages (all);
+}
+
+boolean runDeferredEvents () {
+ /*
+ * Run deferred events. This code is always
+ * called in the Display's thread so it must
+ * be re-enterant but need not be synchronized.
+ */
+ while (eventQueue != null) {
+
+ /* Take an event off the queue */
+ Event event = eventQueue [0];
+ if (event == null) break;
+ int length = eventQueue.length;
+ System.arraycopy (eventQueue, 1, eventQueue, 0, --length);
+ eventQueue [length] = null;
+
+ /* Run the event */
+ Widget widget = event.widget;
+ if (widget != null && !widget.isDisposed ()) {
+ Widget item = event.item;
+ if (item == null || !item.isDisposed ()) {
+ widget.sendEvent (event);
+ }
+ }
+
+ /*
+ * At this point, the event queue could
+ * be null due to a recursive invokation
+ * when running the event.
+ */
+ }
+
+ /* Clear the queue */
+ eventQueue = null;
+ return true;
+}
+
+boolean runPopups () {
+ if (popups == null) return false;
+ boolean result = false;
+ while (popups != null) {
+ Menu menu = popups [0];
+ if (menu == null) break;
+ int length = popups.length;
+ System.arraycopy (popups, 1, popups, 0, --length);
+ popups [length] = null;
+ runDeferredEvents ();
+ if (!menu.isDisposed()) menu._setVisible (true);
+ result = true;
+ }
+ popups = null;
+ return result;
+}
+
+void runSettings () {
+ Font oldFont = getSystemFont ();
+ saveResources ();
+// updateImages ();
+ sendEvent (SWT.Settings, null);
+ Font newFont = getSystemFont ();
+ boolean sameFont = oldFont.equals (newFont);
+ Shell [] shells = getShells ();
+ for (int i=0; i<shells.length; i++) {
+ Shell shell = shells [i];
+ if (!shell.isDisposed ()) {
+ if (!sameFont) {
+ shell.updateFont (oldFont, newFont);
+ }
+ /* This code is intentionally commented */
+ //shell.redraw (true);
+ shell.layout (true, true);
+ }
+ }
+}
+
+void saveResources () {
+// int resourceCount = 0;
+// if (resources == null) {
+// resources = new Resource [RESOURCE_SIZE];
+// } else {
+// resourceCount = resources.length;
+// Resource [] newResources = new Resource [resourceCount + RESOURCE_SIZE];
+// System.arraycopy (resources, 0, newResources, 0, resourceCount);
+// resources = newResources;
+// }
+// if (systemFont != null) {
+// if (!OS.IsWinCE) {
+// NONCLIENTMETRICS info = OS.IsUnicode ? (NONCLIENTMETRICS) new NONCLIENTMETRICSW () : new NONCLIENTMETRICSA ();
+// info.cbSize = NONCLIENTMETRICS.sizeof;
+// if (OS.SystemParametersInfo (OS.SPI_GETNONCLIENTMETRICS, 0, info, 0)) {
+// LOGFONT logFont = OS.IsUnicode ? (LOGFONT) ((NONCLIENTMETRICSW)info).lfMessageFont : ((NONCLIENTMETRICSA)info).lfMessageFont;
+// if (lfSystemFont == null ||
+// logFont.lfCharSet != lfSystemFont.lfCharSet ||
+// logFont.lfHeight != lfSystemFont.lfHeight ||
+// logFont.lfWidth != lfSystemFont.lfWidth ||
+// logFont.lfEscapement != lfSystemFont.lfEscapement ||
+// logFont.lfOrientation != lfSystemFont.lfOrientation ||
+// logFont.lfWeight != lfSystemFont.lfWeight ||
+// logFont.lfItalic != lfSystemFont.lfItalic ||
+// logFont.lfUnderline != lfSystemFont.lfUnderline ||
+// logFont.lfStrikeOut != lfSystemFont.lfStrikeOut ||
+// logFont.lfCharSet != lfSystemFont.lfCharSet ||
+// logFont.lfOutPrecision != lfSystemFont.lfOutPrecision ||
+// logFont.lfClipPrecision != lfSystemFont.lfClipPrecision ||
+// logFont.lfQuality != lfSystemFont.lfQuality ||
+// logFont.lfPitchAndFamily != lfSystemFont.lfPitchAndFamily ||
+// !getFontName (logFont).equals (getFontName (lfSystemFont))) {
+// resources [resourceCount++] = systemFont;
+// lfSystemFont = logFont;
+// systemFont = null;
+// }
+// }
+// }
+// }
+// if (errorImage != null) resources [resourceCount++] = errorImage;
+// if (infoImage != null) resources [resourceCount++] = infoImage;
+// if (questionImage != null) resources [resourceCount++] = questionImage;
+// if (warningIcon != null) resources [resourceCount++] = warningIcon;
+// errorImage = infoImage = questionImage = warningIcon = null;
+// for (int i=0; i<cursors.length; i++) {
+// if (cursors [i] != null) resources [resourceCount++] = cursors [i];
+// cursors [i] = null;
+// }
+// if (resourceCount < RESOURCE_SIZE) {
+// Resource [] newResources = new Resource [resourceCount];
+// System.arraycopy (resources, 0, newResources, 0, resourceCount);
+// resources = newResources;
+// }
+}
+
+void sendEvent (int eventType, Event event) {
+ if (eventTable == null && filterTable == null) {
+ return;
+ }
+ if (event == null) event = new Event ();
+ event.display = this;
+ event.type = eventType;
+ if (event.time == 0) event.time = getLastEventTime ();
+ if (!filterEvent (event)) {
+ if (eventTable != null) eventTable.sendEvent (event);
+ }
+}
+
+/**
+ * Sets the location of the on-screen pointer relative to the top left corner
+ * of the screen. <b>Note: It is typically considered bad practice for a
+ * program to move the on-screen pointer location.</b>
+ *
+ * @param x the new x coordinate for the cursor
+ * @param y the new y coordinate for the cursor
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.1
+ */
+public void setCursorLocation (int x, int y) {
+ checkDevice ();
+ OS.SetCursorPos (x, y);
+}
+
+/**
+ * Sets the location of the on-screen pointer relative to the top left corner
+ * of the screen. <b>Note: It is typically considered bad practice for a
+ * program to move the on-screen pointer location.</b>
+ *
+ * @param point new position
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_NULL_ARGUMENT - if the point is null
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @since 2.0
+ */
+public void setCursorLocation (Point point) {
+ checkDevice ();
+ if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
+ setCursorLocation (point.x, point.y);
+}
+
+/**
+ * Sets the application defined property of the receiver
+ * with the specified name to the given argument.
+ * <p>
+ * Applications may have associated arbitrary objects with the
+ * receiver in this fashion. If the objects stored in the
+ * properties need to be notified when the display is disposed
+ * of, it is the application's responsibility provide a
+ * <code>disposeExec()</code> handler which does so.
+ * </p>
+ *
+ * @param key the name of the property
+ * @param value the new value for the property
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the key is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see #getData(String)
+ * @see #disposeExec(Runnable)
+ */
+public void setData (String key, Object value) {
+ checkDevice ();
+ if (key == null) error (SWT.ERROR_NULL_ARGUMENT);
+
+// if (key.equals (RUN_MESSAGES_IN_IDLE_KEY)) {
+// Boolean data = (Boolean) value;
+// runMessagesInIdle = data != null && data.booleanValue ();
+// return;
+// }
+
+ /* Remove the key/value pair */
+ if (value == null) {
+ if (keys == null) return;
+ int index = 0;
+ while (index < keys.length && !keys [index].equals (key)) index++;
+ if (index == keys.length) return;
+ if (keys.length == 1) {
+ keys = null;
+ values = null;
+ } else {
+ String [] newKeys = new String [keys.length - 1];
+ Object [] newValues = new Object [values.length - 1];
+ System.arraycopy (keys, 0, newKeys, 0, index);
+ System.arraycopy (keys, index + 1, newKeys, index, newKeys.length - index);
+ System.arraycopy (values, 0, newValues, 0, index);
+ System.arraycopy (values, index + 1, newValues, index, newValues.length - index);
+ keys = newKeys;
+ values = newValues;
+ }
+ return;
+ }
+
+ /* Add the key/value pair */
+ if (keys == null) {
+ keys = new String [] {key};
+ values = new Object [] {value};
+ return;
+ }
+ for (int i=0; i<keys.length; i++) {
+ if (keys [i].equals (key)) {
+ values [i] = value;
+ return;
+ }
+ }
+ String [] newKeys = new String [keys.length + 1];
+ Object [] newValues = new Object [values.length + 1];
+ System.arraycopy (keys, 0, newKeys, 0, keys.length);
+ System.arraycopy (values, 0, newValues, 0, values.length);
+ newKeys [keys.length] = key;
+ newValues [values.length] = value;
+ keys = newKeys;
+ values = newValues;
+}
+
+/**
+ * Sets the application defined, display specific data
+ * associated with the receiver, to the argument.
+ * The <em>display specific data</em> is a single,
+ * unnamed field that is stored with every display.
+ * <p>
+ * Applications may put arbitrary objects in this field. If
+ * the object stored in the display specific data needs to
+ * be notified when the display is disposed of, it is the
+ * application's responsibility provide a
+ * <code>disposeExec()</code> handler which does so.
+ * </p>
+ *
+ * @param data the new display specific data
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see #getData()
+ * @see #disposeExec(Runnable)
+ */
+public void setData (Object data) {
+ checkDevice ();
+ this.data = data;
+}
+
+/**
+ * On platforms which support it, sets the application name
+ * to be the argument. On Motif, for example, this can be used
+ * to set the name used for resource lookup. Specifying
+ * <code>null</code> for the name clears it.
+ *
+ * @param name the new app name or <code>null</code>
+ */
+public static void setAppName (String name) {
+ /* Do nothing */
+}
+
+void setModalDialogShell (Shell modalDailog) {
+// if (modalDialogShell != null && modalDialogShell.isDisposed ()) modalDialogShell = null;
+// this.modalDialogShell = modalDailog;
+// Shell [] shells = getShells ();
+// for (int i=0; i<shells.length; i++) shells [i].updateModal ();
+}
+
+void setModalShell (Shell shell) {
+// if (modalShells == null) modalShells = new Shell [4];
+// int index = 0, length = modalShells.length;
+// while (index < length) {
+// if (modalShells [index] == shell) return;
+// if (modalShells [index] == null) break;
+// index++;
+// }
+// if (index == length) {
+// Shell [] newModalShells = new Shell [length + 4];
+// System.arraycopy (modalShells, 0, newModalShells, 0, length);
+// modalShells = newModalShells;
+// }
+// modalShells [index] = shell;
+// Shell [] shells = getShells ();
+// for (int i=0; i<shells.length; i++) shells [i].updateModal ();
+}
+
+/**
+ * Sets the synchronizer used by the display to be
+ * the argument, which can not be null.
+ *
+ * @param synchronizer the new synchronizer for the display (must not be null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the synchronizer is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_FAILED_EXEC - if an exception occurred while running an inter-thread message</li>
+ * </ul>
+ */
+public void setSynchronizer (Synchronizer synchronizer) {
+ checkDevice ();
+ if (synchronizer == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (this.synchronizer != null) {
+ this.synchronizer.runAsyncMessages(true);
+ }
+ this.synchronizer = synchronizer;
+}
+
+/**
+ * Causes the user-interface thread to <em>sleep</em> (that is,
+ * to be put in a state where it does not consume CPU cycles)
+ * until an event is received or it is otherwise awakened.
+ *
+ * @return <code>true</code> if an event requiring dispatching was placed on the queue.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see #wake
+ */
+public boolean sleep () {
+ checkDevice ();
+//System.out.print("<");
+//try {
+// if (getMessageCount () != 0) return true;
+// sleep = 0;
+// OS.DispatcherFrame_Continue(frame, true);
+// OS.Dispatcher_PushFrame(frame);
+// sleep = -1;
+ return true;
+//} finally {
+// System.out.println(">");
+//}
+}
+
+/**
+ * Causes the <code>run()</code> method of the runnable to
+ * be invoked by the user-interface thread at the next
+ * reasonable opportunity. The thread which calls this method
+ * is suspended until the runnable completes. Specifying <code>null</code>
+ * as the runnable simply wakes the user-interface thread.
+ * <p>
+ * Note that at the time the runnable is invoked, widgets
+ * that have the receiver as their display may have been
+ * disposed. Therefore, it is necessary to check for this
+ * case inside the runnable before accessing the widget.
+ * </p>
+ *
+ * @param runnable code to run on the user-interface thread or <code>null</code>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_FAILED_EXEC - if an exception occured when executing the runnable</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see #asyncExec
+ */
+public void syncExec (Runnable runnable) {
+ if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
+ synchronizer.syncExec (runnable);
+}
+
+/**
+ * Causes the <code>run()</code> method of the runnable to
+ * be invoked by the user-interface thread after the specified
+ * number of milliseconds have elapsed. If milliseconds is less
+ * than zero, the runnable is not executed.
+ * <p>
+ * Note that at the time the runnable is invoked, widgets
+ * that have the receiver as their display may have been
+ * disposed. Therefore, it is necessary to check for this
+ * case inside the runnable before accessing the widget.
+ * </p>
+ *
+ * @param milliseconds the delay before running the runnable
+ * @param runnable code to run on the user-interface thread
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the runnable is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see #asyncExec
+ */
+public void timerExec (int milliseconds, Runnable runnable) {
+ checkDevice ();
+ if (runnable == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (timerList == null) timerList = new Runnable [4];
+ if (timerHandles == null) timerHandles = new int [4];
+ int index = 0;
+ while (index < timerList.length) {
+ if (timerList [index] == runnable) break;
+ index++;
+ }
+ if (index != timerList.length) {
+ int timer = timerHandles [index];
+ if (milliseconds < 0) {
+ OS.DispatcherTimer_Stop (timer);
+ timerList [index] = null;
+ timerHandles [index] = 0;
+ OS.GCHandle_Free (timer);
+ return;
+ }
+ } else {
+ if (milliseconds < 0) return;
+ index = 0;
+ while (index < timerList.length) {
+ if (timerList [index] == null) break;
+ index++;
+ }
+ if (index == timerList.length) {
+ Runnable [] newTimerList = new Runnable [timerList.length + 4];
+ System.arraycopy (timerList, 0, newTimerList, 0, timerList.length);
+ timerList = newTimerList;
+ int [] newTimerHandles = new int [timerHandles.length + 4];
+ System.arraycopy (timerHandles, 0, newTimerHandles, 0, timerHandles.length);
+ timerHandles = newTimerHandles;
+ }
+ }
+ int timer = OS.gcnew_DispatcherTimer();
+ if (timer != 0) {
+ OS.DispatcherTimer_Tag(timer, index);
+ int timeSpan = OS.TimeSpan_FromMilliseconds(milliseconds);
+ OS.DispatcherTimer_Interval(timer, timeSpan);
+ OS.DispatcherTimer_Tick(timer, timerHandler);
+ OS.DispatcherTimer_Start(timer);
+ timerList [index] = runnable;
+ timerHandles [index] = timer;
+ OS.GCHandle_Free(timeSpan);
+ }
+}
+
+void timerProc (int index, int e) {
+ if (0 <= index && index < timerHandles.length) {
+ int timer = timerHandles [index];
+ if (timer != 0) {
+ OS.DispatcherTimer_Stop (timer);
+ OS.GCHandle_Free (timer);
+ timerHandles [index] = 0;
+ Runnable runnable = timerList [index];
+ timerList [index] = null;
+ runnable.run ();
+ }
+ }
+}
+
+static int translateKey (int key) {
+ for (int i=0; i<KeyTable.length; i++) {
+ if (KeyTable [i] [0] == key) return KeyTable [i] [1];
+ }
+ return 0;
+}
+
+static int untranslateKey (int key) {
+ for (int i=0; i<KeyTable.length; i++) {
+ if (KeyTable [i] [1] == key) return KeyTable [i] [0];
+ }
+ return 0;
+}
+
+/**
+ * Forces all outstanding paint requests for the display
+ * to be processed before this method returns.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see Control#update()
+ */
+public void update() {
+ checkDevice ();
+ Shell[] shells = getShells ();
+ for (int i=0; i<shells.length; i++) {
+ Shell shell = shells [i];
+ if (!shell.isDisposed ()) shell.update (true);
+ }
+}
+
+/**
+ * If the receiver's user-interface thread was <code>sleep</code>ing,
+ * causes it to be awakened and start running again. Note that this
+ * method may be called from any thread.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see #sleep
+ */
+public void wake () {
+ if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
+ if (thread == Thread.currentThread ()) return;
+ wakeThread ();
+}
+
+void wakeThread () {
+ int handler = OS.gcnew_NoArgsDelegate ();
+ OS.Dispatcher_BeginInvoke (dispatcher, OS.DispatcherPriority_Send, handler);
+ OS.GCHandle_Free (handler);
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ExpandBar.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ExpandBar.java
new file mode 100644
index 0000000000..e0d685f402
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ExpandBar.java
@@ -0,0 +1,425 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.events.*;
+
+/**
+ * Instances of this class support the layout of selectable
+ * expand bar items.
+ * <p>
+ * The item children that may be added to instances of this class
+ * must be of type <code>ExpandItem</code>.
+ * </p><p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>V_SCROLL</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Expand, Collapse</dd>
+ * </dl>
+ * </p><p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ *
+ * @see ExpandItem
+ * @see ExpandEvent
+ * @see ExpandListener
+ * @see ExpandAdapter
+ *
+ * @since 3.2
+ */
+public class ExpandBar extends Composite {
+ int parentingHandle;
+ ExpandItem [] items;
+ Control [] children;
+ int itemCount, childCount;
+ int spacing;
+
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public ExpandBar (Composite parent, int style) {
+ super (parent, checkStyle (style));
+}
+
+Control [] _getChildren () {
+ // return children in reverse order.
+ Control[] result = new Control [childCount];
+ for (int i = 0; i < childCount; i++) {
+ result [childCount - i - 1] = children [i];
+ }
+ return result;
+}
+
+void addChild (Control control) {
+ super.addChild (control);
+ if (childCount == children.length) {
+ Control [] newChildren = new Control [childCount + 4];
+ System.arraycopy (children, 0, newChildren, 0, childCount);
+ children = newChildren;
+ }
+ children [childCount++] = control;
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when an item in the receiver is expanded or collapsed
+ * by sending it one of the messages defined in the <code>ExpandListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ExpandListener
+ * @see #removeExpandListener
+ */
+public void addExpandListener (ExpandListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Expand, typedListener);
+ addListener (SWT.Collapse, typedListener);
+}
+
+protected void checkSubclass () {
+ if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
+}
+
+static int checkStyle (int style) {
+ style &= ~SWT.H_SCROLL;
+ //TODO implement scrollbar for this widget
+ style &= ~SWT.V_SCROLL;
+ return style | SWT.NO_BACKGROUND;
+}
+
+public Point computeSize (int wHint, int hHint, boolean changed) {
+ checkWidget ();
+ return super.computeSize(handle, wHint, hHint, changed);
+}
+
+void createHandle () {
+ state |= THEME_BACKGROUND;
+ parentingHandle = OS.gcnew_Canvas ();
+ if (parentingHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ handle = OS.gcnew_StackPanel ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ int children = OS.Panel_Children (parentingHandle);
+ OS.UIElementCollection_Add (children, handle);
+ OS.GCHandle_Free (children);
+}
+
+void createItem (ExpandItem item, int style, int index) {
+ if (!(0 <= index && index <= itemCount)) error (SWT.ERROR_INVALID_RANGE);
+ if (itemCount == items.length) {
+ ExpandItem [] newItems = new ExpandItem [itemCount + 4];
+ System.arraycopy (items, 0, newItems, 0, items.length);
+ items = newItems;
+ }
+ System.arraycopy (items, index, items, index + 1, itemCount - index);
+ item.createWidget();
+ int uiElementCollectinon = OS.Panel_Children(handle);
+ OS.UIElementCollection_Insert(uiElementCollectinon, index, item.handle);
+ OS.GCHandle_Free(uiElementCollectinon);
+ int thickness = OS.gcnew_Thickness (spacing, spacing, spacing, spacing);
+ OS.FrameworkElement_Margin (item.handle, thickness);
+ OS.GCHandle_Free (thickness);
+ items [index] = item;
+ itemCount++;
+}
+
+void createWidget () {
+ super.createWidget ();
+ items = new ExpandItem [4];
+ itemCount = 0;
+ children = new Control [4];
+ childCount = 0;
+}
+
+int defaultBackground () {
+ return OS.SystemColors_ControlColor;
+}
+
+void deregister () {
+ super.deregister ();
+ display.removeWidget (parentingHandle);
+}
+
+void destroyItem (ExpandItem item) {
+ int index = 0;
+ while (index < itemCount) {
+ if (items [index] == item) break;
+ index++;
+ }
+ if (index == itemCount) return;
+ System.arraycopy (items, index + 1, items, index, --itemCount - index);
+ items [itemCount] = null;
+}
+
+Point getLocation (Control child) {
+ int topHandle = child.topHandle ();
+ int point = OS.gcnew_Point (0, 0);
+ if (point == 0) error (SWT.ERROR_NO_HANDLES);
+ int location = OS.UIElement_TranslatePoint (topHandle, point, handle);
+ int x = (int) OS.Point_X (location);
+ int y = (int) OS.Point_Y (location);
+ OS.GCHandle_Free (point);
+ OS.GCHandle_Free (location);
+ return new Point (x, y);
+}
+
+/**
+ * Returns the item at the given, zero-relative index in the
+ * receiver. Throws an exception if the index is out of range.
+ *
+ * @param index the index of the item to return
+ * @return the item at the given index
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public ExpandItem getItem (int index) {
+ checkWidget ();
+ if (!(0 <= index && index < itemCount)) error (SWT.ERROR_INVALID_RANGE);
+ return items [index];
+}
+
+/**
+ * Returns the number of items contained in the receiver.
+ *
+ * @return the number of items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getItemCount () {
+ checkWidget ();
+ return itemCount;
+}
+
+/**
+ * Returns an array of <code>ExpandItem</code>s which are the items
+ * in the receiver.
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its list of items, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ *
+ * @return the items in the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public ExpandItem [] getItems () {
+ checkWidget ();
+ ExpandItem [] result = new ExpandItem [itemCount];
+ System.arraycopy (items, 0, result, 0, itemCount);
+ return result;
+}
+
+/**
+ * Returns the receiver's spacing.
+ *
+ * @return the spacing
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getSpacing () {
+ checkWidget ();
+ return spacing;
+}
+
+boolean hasItems () {
+ return true;
+}
+
+/**
+ * Searches the receiver's list starting at the first item
+ * (index 0) until an item is found that is equal to the
+ * argument, and returns the index of that item. If no item
+ * is found, returns -1.
+ *
+ * @param item the search item
+ * @return the index of the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the item is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int indexOf (ExpandItem item) {
+ checkWidget ();
+ if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
+ for (int i = 0; i < itemCount; i++) {
+ if (items [i] == item) return i;
+ }
+ return -1;
+}
+
+int parentingHandle() {
+ return parentingHandle;
+}
+
+void register () {
+ super.register ();
+ display.addWidget (parentingHandle, this);
+}
+
+void releaseChildren (boolean destroy) {
+ if (items != null) {
+ for (int i=0; i<items.length; i++) {
+ ExpandItem item = items [i];
+ if (item != null && !item.isDisposed ()) {
+ item.release (false);
+ }
+ }
+ items = null;
+ }
+ super.releaseChildren (destroy);
+}
+
+void releaseHandle () {
+ super.releaseHandle ();
+ if (parentingHandle != 0) OS.GCHandle_Free (parentingHandle);
+ parentingHandle = 0;
+}
+
+void removeChild (Control control) {
+ super.removeChild (control);//TODO MAKE SURE removeControl gets called first
+ int index = 0;
+ while (index < childCount) {
+ if (children [index] == control) break;
+ index++;
+ }
+ if (index == childCount) return;
+ System.arraycopy(children, index+1, children, index, --childCount - index);
+ children [childCount] = null;
+}
+
+void removeControl (Control control) {
+ super.removeControl (control);
+ for (int i=0; i<itemCount; i++) {
+ ExpandItem item = items [i];
+ if (item.control == control) item.setControl (null);
+ }
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when items in the receiver are expanded or collapsed.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ExpandListener
+ * @see #addExpandListener
+ */
+public void removeExpandListener (ExpandListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Expand, listener);
+ eventTable.unhook (SWT.Collapse, listener);
+}
+
+int setBounds (int x, int y, int width, int height, int flags) {
+ int result = super.setBounds (x, y, width, height, flags);
+ if ((result & RESIZED) != 0) {
+ OS.FrameworkElement_Height (handle, height);
+ OS.FrameworkElement_Width (handle, width);
+ }
+ return result;
+}
+
+/**
+ * Sets the receiver's spacing. Spacing specifies the number of pixels allocated around
+ * each item.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSpacing (int spacing) {
+ checkWidget ();
+ if (spacing < 0) return;
+ if (spacing == this.spacing) return;
+ this.spacing = spacing;
+ int thickness = OS.gcnew_Thickness (spacing, spacing, spacing, spacing);
+ for (int i = 0; i < itemCount; i++) {
+ ExpandItem item = items[i];
+ OS.FrameworkElement_Margin (item.handle, thickness);
+ }
+ OS.GCHandle_Free (thickness);
+}
+
+int topHandle () {
+ return parentingHandle;
+}
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ExpandItem.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ExpandItem.java
new file mode 100644
index 0000000000..bcf11a6138
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ExpandItem.java
@@ -0,0 +1,391 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+
+/**
+ * Instances of this class represent a selectable user interface object
+ * that represents a expandable item in a expand bar.
+ * <p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>(none)</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * </p><p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ *
+ * @see ExpandBar
+ *
+ * @since 3.2
+ */
+public class ExpandItem extends Item {
+ ExpandBar parent;
+ Control control;
+ int imageHandle, textHandle, contentHandle;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public ExpandItem (ExpandBar parent, int style) {
+ this (parent, style, checkNull (parent).getItemCount ());
+}
+
+/**
+ * Constructs a new instance of this class given its parent, a
+ * style value describing its behavior and appearance, and the index
+ * at which to place it in the items maintained by its parent.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ * @param index the zero-relative index to store the receiver in its parent
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public ExpandItem (ExpandBar parent, int style, int index) {
+ super (parent, style);
+ this.parent = parent;
+ parent.createItem (this, style, index);
+}
+
+static ExpandBar checkNull (ExpandBar control) {
+ if (control == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+ return control;
+}
+
+void createHandle () {
+ handle = OS.gcnew_Expander ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ imageHandle = OS.gcnew_Image ();
+ if (imageHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.Image_Stretch (imageHandle, OS.Stretch_None);
+ OS.UIElement_Visibility (imageHandle, OS.Visibility_Collapsed);
+ textHandle = OS.gcnew_TextBlock ();
+ if (textHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ int panel = OS.gcnew_StackPanel ();
+ if (panel == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.StackPanel_Orientation (panel, OS.Orientation_Horizontal);
+ int thickness = OS.gcnew_Thickness (1, 1, 1, 1);
+ if (thickness == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.FrameworkElement_Margin (panel, thickness);
+ OS.GCHandle_Free (thickness);
+ int children = OS.Panel_Children (panel);
+ OS.UIElementCollection_Add (children, imageHandle);
+ OS.UIElementCollection_Add (children, textHandle);
+ OS.GCHandle_Free (children);
+ OS.HeaderedContentControl_Header (handle, panel);
+ OS.GCHandle_Free (panel);
+ contentHandle = OS.gcnew_Canvas ();
+ if (contentHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.ContentControl_Content (handle, contentHandle);
+}
+
+void deregister () {
+ display.removeWidget (handle);
+}
+
+void destroyWidget () {
+ parent.destroyItem (this);
+ releaseHandle ();
+}
+
+/**
+ * Returns the control that is shown when the item is expanded.
+ * If no control has been set, return <code>null</code>.
+ *
+ * @return the control
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Control getControl () {
+ checkWidget ();
+ return control;
+}
+
+/**
+ * Returns <code>true</code> if the receiver is expanded,
+ * and false otherwise.
+ *
+ * @return the expanded state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getExpanded () {
+ checkWidget ();
+ return OS.Expander_IsExpanded (handle);
+}
+
+/**
+ * Returns the height of the receiver's header
+ *
+ * @return the height of the header
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getHeaderHeight () {
+ checkWidget ();
+ int panel = OS.HeaderedContentControl_Header (handle);
+ return (int) OS.FrameworkElement_ActualHeight (panel);
+}
+
+/**
+ * Gets the height of the receiver.
+ *
+ * @return the height
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getHeight () {
+ checkWidget ();
+ return (int) OS.FrameworkElement_Height (contentHandle);
+}
+
+/**
+ * Returns the receiver's parent, which must be a <code>ExpandBar</code>.
+ *
+ * @return the receiver's parent
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public ExpandBar getParent () {
+ checkWidget ();
+ return parent;
+}
+
+Control getWidgetControl () {
+ return parent;
+}
+
+void HandleExpanded (int sender, int e) {
+ if (!checkEvent (e)) return;
+ Event event = new Event ();
+ event.item = this;
+ parent.notifyListeners (SWT.Expand, event);
+}
+
+void HandleCollapsed (int sender, int e) {
+ if (!checkEvent (e)) return;
+ Event event = new Event ();
+ event.item = this;
+ parent.notifyListeners (SWT.Collapse, event);
+}
+
+void HandleSizeChanged (int sender, int e) {
+ if (!checkEvent (e)) return;
+ resizeControl ();
+}
+
+void hookEvents () {
+ super.hookEvents ();
+ int handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleExpanded");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.Expander_Expanded (handle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleCollapsed");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.Expander_Collapsed (handle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_SizeChangedEventHandler (jniRef, "HandleSizeChanged");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.FrameworkElement_SizeChanged (contentHandle, handler);
+ OS.GCHandle_Free (handler);
+}
+
+void register () {
+ display.addWidget (handle, this);
+}
+
+void releaseHandle () {
+ super.releaseHandle ();
+ if (handle != 0) OS.GCHandle_Free (handle);
+ handle = 0;
+ parent = null;
+ if (textHandle != 0) OS.GCHandle_Free (textHandle);
+ textHandle = 0;
+ if (imageHandle !=0 )OS.GCHandle_Free (imageHandle);
+ imageHandle = 0;
+ if (contentHandle != 0) OS.GCHandle_Free (contentHandle);
+ contentHandle = 0;
+}
+
+void resizeControl () {
+ if (control != null) {
+ int width = (int) OS.FrameworkElement_ActualWidth (contentHandle);
+ int height = (int) OS.FrameworkElement_Height (contentHandle);
+ control.setSize (width, height);
+ }
+}
+
+/**
+ * Sets the control that is shown when the item is expanded.
+ *
+ * @param control the new control (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li>
+ * <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setControl (Control control) {
+ checkWidget ();
+ if (control != null) {
+ if (control.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (control.parent != parent) error (SWT.ERROR_INVALID_PARENT);
+ }
+ Control oldControl = this.control, newControl = control;
+ this.control = control;
+ int children = OS.Panel_Children (contentHandle);
+ int parentHandle = parent.parentingHandle ();
+ int parentChildren = OS.Panel_Children (parentHandle);
+ if (newControl != null) {
+ int topHandle = newControl.topHandle ();
+ OS.UIElementCollection_Remove (parentChildren, topHandle);
+ OS.UIElementCollection_Add (children, topHandle);
+ }
+ if (oldControl != null) {
+ int topHandle = oldControl.topHandle ();
+ OS.UIElementCollection_Remove (children, topHandle);
+ OS.UIElementCollection_Add (parentChildren, topHandle);
+ }
+ OS.GCHandle_Free (children);
+ OS.GCHandle_Free (parentChildren);
+}
+
+/**
+ * Sets the expanded state of the receiver.
+ *
+ * @param expanded the new expanded state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setExpanded (boolean expanded) {
+ checkWidget ();
+ OS.Expander_IsExpanded(handle, expanded);
+}
+
+/**
+ * Sets the height of the receiver. This is height of the item when it is expanded,
+ * excluding the height of the header.
+ *
+ * @param height the new height
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setHeight (int height) {
+ checkWidget ();
+ if (height < 0) return;
+ OS.FrameworkElement_Height (contentHandle, height);
+}
+
+public void setImage (Image image) {
+ super.setImage (image);
+ if (image != null && image.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
+ this.image = image;
+ OS.Image_Source (imageHandle, image != null ? image.handle : 0);
+ OS.UIElement_Visibility (imageHandle, image != null ? OS.Visibility_Visible : OS.Visibility_Collapsed);
+ OS.UIElement_Visibility (textHandle, image != null && text.length () == 0 ? OS.Visibility_Collapsed : OS.Visibility_Visible);
+ int spacing = image != null && text.length () != 0 ? 3 : 0;
+ int margin = OS.gcnew_Thickness (0, 0, spacing, 0);
+ if (margin == 0) error(SWT.ERROR_NO_HANDLES);
+ OS.FrameworkElement_Margin (imageHandle, margin);
+ OS.GCHandle_Free (margin);
+}
+
+public void setText (String string) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (string.equals (text)) return;
+ text = string;
+ int ptr = createDotNetString (text, false);
+ if (ptr == 0) error(SWT.ERROR_NO_HANDLES);
+ OS.TextBlock_Text (textHandle, ptr);
+ OS.GCHandle_Free (ptr);
+ OS.UIElement_Visibility (textHandle, text.length() == 0 && image != null ? OS.Visibility_Collapsed : OS.Visibility_Visible);
+ int spacing = image != null && text.length () != 0 ? 3 : 0;
+ int margin = OS.gcnew_Thickness (0, 0, spacing, 0);
+ if (margin == 0) error(SWT.ERROR_NO_HANDLES);
+ OS.FrameworkElement_Margin (imageHandle, margin);
+ OS.GCHandle_Free (margin);
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/FileDialog.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/FileDialog.java
new file mode 100644
index 0000000000..a831c774e7
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/FileDialog.java
@@ -0,0 +1,316 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+
+/**
+ * Instances of this class allow the user to navigate
+ * the file system and select or enter a file name.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>SAVE, OPEN, MULTI</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * <p>
+ * Note: Only one of the styles SAVE and OPEN may be specified.
+ * </p><p>
+ * IMPORTANT: This class is intended to be subclassed <em>only</em>
+ * within the SWT implementation.
+ * </p>
+ */
+public class FileDialog extends Dialog {
+ String [] filterNames = new String [0];
+ String [] filterExtensions = new String [0];
+ String [] fileNames = new String [0];
+ String filterPath = "", fileName = "";
+
+/**
+ * Constructs a new instance of this class given only its parent.
+ *
+ * @param parent a shell which will be the parent of the new instance
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ */
+public FileDialog (Shell parent) {
+ this (parent, SWT.PRIMARY_MODAL);
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a shell which will be the parent of the new instance
+ * @param style the style of dialog to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ */
+public FileDialog (Shell parent, int style) {
+ super (parent, style);
+ checkSubclass ();
+}
+
+String createJavaString (int ptr) {
+ int charArray = OS.String_ToCharArray (ptr);
+ char [] chars = new char[OS.String_Length (ptr)];
+ OS.memmove (chars, charArray, chars.length * 2);
+ return new String (chars);
+}
+
+/**
+ * Returns the path of the first file that was
+ * selected in the dialog relative to the filter path, or an
+ * empty string if no such file has been selected.
+ *
+ * @return the relative path of the file
+ */
+public String getFileName () {
+ return fileName;
+}
+
+/**
+ * Returns a (possibly empty) array with the paths of all files
+ * that were selected in the dialog relative to the filter path.
+ *
+ * @return the relative paths of the files
+ */
+public String [] getFileNames () {
+ return fileNames;
+}
+
+/**
+ * Returns the file extensions which the dialog will
+ * use to filter the files it shows.
+ *
+ * @return the file extensions filter
+ */
+public String [] getFilterExtensions () {
+ return filterExtensions;
+}
+
+/**
+ * Returns the names that describe the filter extensions
+ * which the dialog will use to filter the files it shows.
+ *
+ * @return the list of filter names
+ */
+public String [] getFilterNames () {
+ return filterNames;
+}
+
+/**
+ * Returns the directory path that the dialog will use, or an empty
+ * string if this is not set. File names in this path will appear
+ * in the dialog, filtered according to the filter extensions.
+ *
+ * @return the directory path string
+ *
+ * @see #setFilterExtensions
+ */
+public String getFilterPath () {
+ return filterPath;
+}
+
+/**
+ * Makes the dialog visible and brings it to the front
+ * of the display.
+ *
+ * @return a string describing the absolute path of the first selected file,
+ * or null if the dialog was cancelled or an error occurred
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the dialog has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the dialog</li>
+ * </ul>
+ */
+public String open () {
+ int dialog;
+ if ((style & SWT.OPEN) != 0) {
+ dialog = OS.gcnew_OpenFileDialog ();
+ if ((style & SWT.MULTI) != 0) OS.OpenFileDialog_Multiselect (dialog, true);
+ } else {
+ dialog = OS.gcnew_SaveFileDialog ();
+ }
+ if (title != null) {
+ int length = title.length ();
+ char [] buffer = new char [length + 1];
+ title.getChars (0, length, buffer, 0);
+ int titlePtr = OS.gcnew_String (buffer);
+ OS.FileDialog_Title (dialog, titlePtr);
+ OS.GCHandle_Free (titlePtr);
+ }
+
+ if (fileName != null) {
+ int length = fileName.length ();
+ char [] buffer = new char [length + 1];
+ fileName.getChars (0, length, buffer, 0);
+ int fileNamePtr = OS.gcnew_String (buffer);
+ OS.FileDialog_FileName (dialog, fileNamePtr);
+ OS.GCHandle_Free (fileNamePtr);
+ }
+
+ if (filterExtensions != null && filterExtensions.length > 0) {
+ StringBuffer strFilter = new StringBuffer();
+ for (int i=0; i<filterExtensions.length; i++) {
+ if (i > 0) strFilter.append("|");
+ if (filterNames != null && i < filterNames.length) {
+ strFilter.append(filterNames [i]);
+ } else {
+ strFilter.append(filterExtensions [i]);
+ }
+ strFilter.append("|");
+ strFilter.append(filterExtensions [i]);
+ }
+ int length = strFilter.length ();
+ char [] buffer = new char [length + 1];
+ strFilter.getChars (0, length, buffer, 0);
+ int filterPtr = OS.gcnew_String (buffer);
+ OS.FileDialog_Filter (dialog, filterPtr);
+ OS.GCHandle_Free (filterPtr);
+ }
+
+ if (filterPath != null) {
+ int length = filterPath.length ();
+ char [] buffer = new char [length + 1];
+ filterPath.getChars (0, length, buffer, 0);
+ int filterPathPtr = OS.gcnew_String (buffer);
+ OS.FileDialog_InitialDirectory (dialog, filterPathPtr);
+ OS.GCHandle_Free (filterPathPtr);
+ }
+
+ boolean success = OS.CommonDialog_ShowDialog(dialog, parent.shellHandle);
+
+ /* Set the new path, file name and filter */
+ String fullPath = null;
+ if (success) {
+ int strings = OS.FileDialog_FileNames (dialog);
+ int length = OS.ICollection_Count (strings);
+ fileNames = new String [length];
+ for (int i = 0; i < length; i++) {
+ int str = OS.IList_default (strings, i);
+ int fileInfo = OS.gcnew_FileInfo (str);
+ int name = OS.FileInfo_Name (fileInfo);
+ fileNames [i] = createJavaString (name);
+ if (i == 0) {
+ int dir = OS.FileInfo_DirectoryName (fileInfo);
+ filterPath = createJavaString (dir);
+ OS.GCHandle_Free (dir);
+ }
+ OS.GCHandle_Free (name);
+ OS.GCHandle_Free (fileInfo);
+ OS.GCHandle_Free (str);
+ }
+ OS.GCHandle_Free (strings);
+ fullPath = filterPath + "\\" + fileNames [0];
+ } else {
+ fileNames = new String [0];
+ }
+
+ OS.GCHandle_Free (dialog);
+ /* Answer the full path or null */
+ return fullPath;
+}
+
+/**
+ * Set the initial filename which the dialog will
+ * select by default when opened to the argument,
+ * which may be null. The name will be prefixed with
+ * the filter path when one is supplied.
+ *
+ * @param string the file name
+ */
+public void setFileName (String string) {
+ fileName = string;
+}
+
+/**
+ * Set the file extensions which the dialog will
+ * use to filter the files it shows to the argument,
+ * which may be null.
+ * <p>
+ * The strings are platform specific. For example, on
+ * Windows, an extension filter string is typically of
+ * the form "*.extension", where "*.*" matches all files.
+ * </p>
+ *
+ * @param extensions the file extension filter
+ *
+ * @see #setFilterNames to specify the user-friendly
+ * names corresponding to the extensions
+ */
+public void setFilterExtensions (String [] extensions) {
+ filterExtensions = extensions;
+}
+
+/**
+ * Sets the the names that describe the filter extensions
+ * which the dialog will use to filter the files it shows
+ * to the argument, which may be null.
+ * <p>
+ * Each name is a user-friendly short description shown for
+ * its corresponding filter. The <code>names</code> array must
+ * be the same length as the <code>extensions</code> array.
+ * </p>
+ *
+ * @param names the list of filter names, or null for no filter names
+ *
+ * @see #setFilterExtensions
+ */
+public void setFilterNames (String [] names) {
+ filterNames = names;
+}
+
+/**
+ * Sets the directory path that the dialog will use
+ * to the argument, which may be null. File names in this
+ * path will appear in the dialog, filtered according
+ * to the filter extensions. If the string is null,
+ * then the operating system's default filter path
+ * will be used.
+ * <p>
+ * Note that the path string is platform dependent.
+ * For convenience, either '/' or '\' can be used
+ * as a path separator.
+ * </p>
+ *
+ * @param string the directory path
+ *
+ * @see #setFilterExtensions
+ */
+public void setFilterPath (String string) {
+ filterPath = string;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/FontDialog.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/FontDialog.java
new file mode 100644
index 0000000000..b35ff5467e
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/FontDialog.java
@@ -0,0 +1,286 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Instances of this class allow the user to select a font
+ * from all available fonts in the system.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>(none)</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * <p>
+ * IMPORTANT: This class is intended to be subclassed <em>only</em>
+ * within the SWT implementation.
+ * </p>
+ */
+public class FontDialog extends Dialog {
+ FontData fontData;
+ RGB rgb;
+
+/**
+ * Constructs a new instance of this class given only its parent.
+ *
+ * @param parent a shell which will be the parent of the new instance
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ */
+public FontDialog (Shell parent) {
+ this (parent, SWT.PRIMARY_MODAL);
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a shell which will be the parent of the new instance
+ * @param style the style of dialog to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ */
+public FontDialog (Shell parent, int style) {
+ super (parent, style);
+ checkSubclass ();
+}
+
+/**
+ * Returns a FontData object describing the font that was
+ * selected in the dialog, or null if none is available.
+ *
+ * @return the FontData for the selected font, or null
+ * @deprecated use #getFontList ()
+ */
+public FontData getFontData () {
+ return fontData;
+}
+
+/**
+ * Returns a FontData set describing the font that was
+ * selected in the dialog, or null if none is available.
+ *
+ * @return the FontData for the selected font, or null
+ * @since 2.1.1
+ */
+public FontData [] getFontList () {
+ if (fontData == null) return null;
+ FontData [] result = new FontData [1];
+ result [0] = fontData;
+ return result;
+}
+
+/**
+ * Returns an RGB describing the color that was selected
+ * in the dialog, or null if none is available.
+ *
+ * @return the RGB value for the selected color, or null
+ *
+ * @see PaletteData#getRGBs
+ *
+ * @since 2.1
+ */
+public RGB getRGB () {
+ return rgb;
+}
+
+/**
+ * Makes the dialog visible and brings it to the front
+ * of the display.
+ *
+ * @return a FontData object describing the font that was selected,
+ * or null if the dialog was cancelled or an error occurred
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the dialog has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the dialog</li>
+ * </ul>
+ */
+public FontData open () {
+// if (OS.IsWinCE) SWT.error (SWT.ERROR_NOT_IMPLEMENTED);
+//
+// /* Get the owner HWND for the dialog */
+// int hwndOwner = 0;
+// if (parent != null) hwndOwner = parent.handle;
+//
+// /* Open the dialog */
+// int hHeap = OS.GetProcessHeap ();
+// CHOOSEFONT lpcf = new CHOOSEFONT ();
+// lpcf.lStructSize = CHOOSEFONT.sizeof;
+// lpcf.hwndOwner = hwndOwner;
+// lpcf.Flags = OS.CF_SCREENFONTS | OS.CF_EFFECTS;
+// int lpLogFont = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, LOGFONT.sizeof);
+// if (fontData != null && fontData.data != null) {
+// LOGFONT logFont = fontData.data;
+// int lfHeight = logFont.lfHeight;
+// int hDC = OS.GetDC (0);
+// int pixels = -Compatibility.round (fontData.height * OS.GetDeviceCaps(hDC, OS.LOGPIXELSY), 72);
+// OS.ReleaseDC (0, hDC);
+// logFont.lfHeight = pixels;
+// lpcf.Flags |= OS.CF_INITTOLOGFONTSTRUCT;
+// OS.MoveMemory (lpLogFont, logFont, LOGFONT.sizeof);
+// logFont.lfHeight = lfHeight;
+// }
+// lpcf.lpLogFont = lpLogFont;
+// if (rgb != null) {
+// int red = rgb.red & 0xFF;
+// int green = (rgb.green << 8) & 0xFF00;
+// int blue = (rgb.blue << 16) & 0xFF0000;
+// lpcf.rgbColors = red | green | blue;
+// }
+//
+// /* Make the parent shell be temporary modal */
+// Shell oldModal = null;
+// Display display = null;
+// if ((style & (SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) != 0) {
+// display = parent.getDisplay ();
+// oldModal = display.getModalDialogShell ();
+// display.setModalDialogShell (parent);
+// }
+//
+// /* Open the dialog */
+// boolean success = OS.ChooseFont (lpcf);
+//
+// /* Clear the temporary dialog modal parent */
+// if ((style & (SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) != 0) {
+// display.setModalDialogShell (oldModal);
+// }
+//
+// /* Compute the result */
+// if (success) {
+// LOGFONT logFont = OS.IsUnicode ? (LOGFONT) new LOGFONTW () : new LOGFONTA ();
+// OS.MoveMemory (logFont, lpLogFont, LOGFONT.sizeof);
+//
+// /*
+// * This will not work on multiple screens or
+// * for printing. Should use DC for the proper device.
+// */
+// int hDC = OS.GetDC(0);
+// int logPixelsY = OS.GetDeviceCaps(hDC, OS.LOGPIXELSY);
+// int pixels = 0;
+// if (logFont.lfHeight > 0) {
+// /*
+// * Feature in Windows. If the lfHeight of the LOGFONT structure
+// * is positive, the lfHeight measures the height of the entire
+// * cell, including internal leading, in logical units. Since the
+// * height of a font in points does not include the internal leading,
+// * we must subtract the internal leading, which requires a TEXTMETRIC,
+// * which in turn requires font creation.
+// */
+// int hFont = OS.CreateFontIndirect(logFont);
+// int oldFont = OS.SelectObject(hDC, hFont);
+// TEXTMETRIC lptm = OS.IsUnicode ? (TEXTMETRIC) new TEXTMETRICW () : new TEXTMETRICA ();
+// OS.GetTextMetrics(hDC, lptm);
+// OS.SelectObject(hDC, oldFont);
+// OS.DeleteObject(hFont);
+// pixels = logFont.lfHeight - lptm.tmInternalLeading;
+// } else {
+// pixels = -logFont.lfHeight;
+// }
+// OS.ReleaseDC(0, hDC);
+//
+// int points = Compatibility.round(pixels * 72, logPixelsY);
+// fontData = FontData.win32_new (logFont, points);
+// int red = lpcf.rgbColors & 0xFF;
+// int green = (lpcf.rgbColors >> 8) & 0xFF;
+// int blue = (lpcf.rgbColors >> 16) & 0xFF;
+// rgb = new RGB (red, green, blue);
+// }
+//
+// /* Free the OS memory */
+// if (lpLogFont != 0) OS.HeapFree (hHeap, 0, lpLogFont);
+//
+// /*
+// * This code is intentionally commented. On some
+// * platforms, the owner window is repainted right
+// * away when a dialog window exits. This behavior
+// * is currently unspecified.
+// */
+//// if (hwndOwner != 0) OS.UpdateWindow (hwndOwner);
+//
+// if (!success) return null;
+// return fontData;
+ return null;
+}
+
+/**
+ * Sets a FontData object describing the font to be
+ * selected by default in the dialog, or null to let
+ * the platform choose one.
+ *
+ * @param fontData the FontData to use initially, or null
+ * @deprecated use #setFontList (FontData [])
+ */
+public void setFontData (FontData fontData) {
+ this.fontData = fontData;
+}
+
+/**
+ * Sets the set of FontData objects describing the font to
+ * be selected by default in the dialog, or null to let
+ * the platform choose one.
+ *
+ * @param fontData the set of FontData objects to use initially, or null
+ * to let the platform select a default when open() is called
+ *
+ * @see Font#getFontData
+ *
+ * @since 2.1.1
+ */
+public void setFontList (FontData [] fontData) {
+ if (fontData != null && fontData.length > 0) {
+ this.fontData = fontData [0];
+ } else {
+ this.fontData = null;
+ }
+}
+
+/**
+ * Sets the RGB describing the color to be selected by default
+ * in the dialog, or null to let the platform choose one.
+ *
+ * @param rgb the RGB value to use initially, or null to let
+ * the platform select a default when open() is called
+ *
+ * @see PaletteData#getRGBs
+ *
+ * @since 2.1
+ */
+public void setRGB (RGB rgb) {
+ this.rgb = rgb;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Group.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Group.java
new file mode 100644
index 0000000000..d3c1fdf201
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Group.java
@@ -0,0 +1,232 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+
+/**
+ * Instances of this class provide an etched border
+ * with an optional title.
+ * <p>
+ * Shadow styles are hints and may not be honoured
+ * by the platform. To create a group with the
+ * default shadow style for the platform, do not
+ * specify a shadow style.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>SHADOW_ETCHED_IN, SHADOW_ETCHED_OUT, SHADOW_IN, SHADOW_OUT, SHADOW_NONE</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * <p>
+ * Note: Only one of the above styles may be specified.
+ * </p><p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ */
+
+public class Group extends Composite {
+ int parentingHandle;
+ String text;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#SHADOW_ETCHED_IN
+ * @see SWT#SHADOW_ETCHED_OUT
+ * @see SWT#SHADOW_IN
+ * @see SWT#SHADOW_OUT
+ * @see SWT#SHADOW_NONE
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Group (Composite parent, int style) {
+ super (parent, checkStyle (style));
+}
+
+static int checkStyle (int style) {
+ style |= SWT.NO_FOCUS;
+ /*
+ * Even though it is legal to create this widget
+ * with scroll bars, they serve no useful purpose
+ * because they do not automatically scroll the
+ * widget's client area. The fix is to clear
+ * the SWT style.
+ */
+ return style & ~(SWT.H_SCROLL | SWT.V_SCROLL);
+}
+
+protected void checkSubclass () {
+ if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
+}
+
+int backgroundProperty () {
+ return OS.Control_BackgroundProperty ();
+}
+
+int clientHandle () {
+ return parentingHandle;
+}
+
+void createHandle () {
+ state |= THEME_BACKGROUND;
+ handle = OS.gcnew_GroupBox ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ parentingHandle = OS.gcnew_Canvas ();
+ if (parentingHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.ContentControl_Content (handle, parentingHandle);
+}
+
+public Rectangle computeTrim (int x, int y, int width, int height) {
+ int topHandle = topHandle ();
+ int clientHandle = clientHandle();
+ if (clientHandle != topHandle) {
+ double currentWidth = OS.FrameworkElement_Width (topHandle);
+ double currentHeight = OS.FrameworkElement_Height (topHandle);
+ OS.FrameworkElement_Width (topHandle, 100);
+ OS.FrameworkElement_Height (topHandle, 100);
+ OS.UIElement_UpdateLayout (topHandle);
+ int w = (int) OS.FrameworkElement_ActualWidth (topHandle);
+ int h = (int) OS.FrameworkElement_ActualHeight (topHandle);
+ int clientWidth = (int) OS.FrameworkElement_ActualWidth (clientHandle);
+ int clientHeight = (int) OS.FrameworkElement_ActualHeight (clientHandle);
+ int point = OS.gcnew_Point (0, 0);
+ int result = OS.UIElement_TranslatePoint (clientHandle, point, topHandle);
+ x -= (int) OS.Point_X (result);
+ y -= (int) OS.Point_Y (result);
+ width += (w - clientWidth);
+ height += (h - clientHeight);
+ OS.GCHandle_Free (point);
+ OS.GCHandle_Free (result);
+ OS.FrameworkElement_Width (topHandle, currentWidth);
+ OS.FrameworkElement_Height (topHandle, currentHeight);
+ }
+ return new Rectangle (x, y, width, height);
+}
+
+int defaultBackground () {
+ return OS.SystemColors_ControlColor;
+}
+
+String getNameText () {
+ return getText ();
+}
+
+/**
+ * Returns the receiver's text, which is the string that the
+ * is used as the <em>title</em>. If the text has not previously
+ * been set, returns an empty string.
+ *
+ * @return the text
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String getText () {
+ checkWidget ();
+ return text;
+}
+
+boolean mnemonicHit (char key) {
+ return false;
+}
+
+boolean mnemonicMatch (char key) {
+ int accessText = OS.HeaderedContentControl_Header (handle);
+ boolean result = super.mnemonicMatch (accessText, key);
+ OS.GCHandle_Free (accessText);
+ return result;
+}
+
+void releaseHandle () {
+ super.releaseHandle ();
+ OS.GCHandle_Free (parentingHandle);
+ parentingHandle = 0;
+}
+
+void setForegroundBrush (int brush) {
+ if (brush != 0) {
+ OS.Control_Foreground (handle, brush);
+ } else {
+ int property = OS.Control_ForegroundProperty ();
+ OS.DependencyObject_ClearValue (handle, property);
+ OS.GCHandle_Free (property);
+ }
+}
+
+/**
+ * Sets the receiver's text, which is the string that will
+ * be displayed as the receiver's <em>title</em>, to the argument,
+ * which may not be null. The string may include the mnemonic character.
+ * </p>
+ * Mnemonics are indicated by an '&amp;' that causes the next
+ * character to be the mnemonic. When the user presses a
+ * key sequence that matches the mnemonic, focus is assigned
+ * to the first child of the group. On most platforms, the
+ * mnemonic appears underlined but may be emphasised in a
+ * platform specific manner. The mnemonic indicator character
+ * '&amp;' can be escaped by doubling it in the string, causing
+ * a single '&amp;' to be displayed.
+ * </p>
+ * @param string the new text
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setText (String string) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (string.equals (text)) return;
+ text = string;
+ int ptr = createDotNetString (text, true);
+ int accessText = OS.gcnew_AccessText ();
+ if (ptr != 0) OS.AccessText_Text (accessText, ptr);
+ OS.HeaderedContentControl_Header (handle, accessText);
+ if (ptr != 0) OS.GCHandle_Free (ptr);
+ OS.GCHandle_Free (accessText);
+}
+
+int parentingHandle () {
+ return parentingHandle;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Label.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Label.java
new file mode 100644
index 0000000000..9ee422b612
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Label.java
@@ -0,0 +1,284 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Instances of this class represent a non-selectable
+ * user interface object that displays a string or image.
+ * When SEPARATOR is specified, displays a single
+ * vertical or horizontal line.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>SEPARATOR, HORIZONTAL, VERTICAL</dd>
+ * <dd>SHADOW_IN, SHADOW_OUT, SHADOW_NONE</dd>
+ * <dd>CENTER, LEFT, RIGHT, WRAP</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * <p>
+ * Note: Only one of SHADOW_IN, SHADOW_OUT and SHADOW_NONE may be specified.
+ * SHADOW_NONE is a HINT. Only one of HORIZONTAL and VERTICAL may be specified.
+ * Only one of CENTER, LEFT and RIGHT may be specified.
+ * </p><p>
+ * IMPORTANT: This class is intended to be subclassed <em>only</em>
+ * within the SWT implementation.
+ * </p>
+ */
+public class Label extends Control {
+ String text = "";
+ Image image;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#SEPARATOR
+ * @see SWT#HORIZONTAL
+ * @see SWT#VERTICAL
+ * @see SWT#SHADOW_IN
+ * @see SWT#SHADOW_OUT
+ * @see SWT#SHADOW_NONE
+ * @see SWT#CENTER
+ * @see SWT#LEFT
+ * @see SWT#RIGHT
+ * @see SWT#WRAP
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Label (Composite parent, int style) {
+ super (parent, checkStyle (style));
+}
+
+static int checkStyle (int style) {
+ style |= SWT.NO_FOCUS;
+ if ((style & SWT.SEPARATOR) != 0) {
+ style = checkBits (style, SWT.VERTICAL, SWT.HORIZONTAL, 0, 0, 0, 0);
+ return checkBits (style, SWT.SHADOW_OUT, SWT.SHADOW_IN, SWT.SHADOW_NONE, 0, 0, 0);
+ }
+ return checkBits (style, SWT.LEFT, SWT.CENTER, SWT.RIGHT, 0, 0, 0);
+}
+
+void createHandle () {
+ state |= THEME_BACKGROUND;
+ if ((style & SWT.SEPARATOR) != 0) {
+ handle = OS.gcnew_Separator ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ } else {
+ handle = OS.gcnew_Label ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ int value = OS.HorizontalAlignment_Left;
+ if ((style & SWT.CENTER) != 0) value = OS.HorizontalAlignment_Center;
+ if ((style & SWT.RIGHT) != 0) value = OS.HorizontalAlignment_Right;
+ OS.Control_HorizontalContentAlignment (handle, value);
+ }
+}
+
+int defaultBackground () {
+ return OS.SystemColors_ControlColor;
+}
+
+/**
+ * Returns a value which describes the position of the
+ * text or image in the receiver. The value will be one of
+ * <code>LEFT</code>, <code>RIGHT</code> or <code>CENTER</code>
+ * unless the receiver is a <code>SEPARATOR</code> label, in
+ * which case, <code>NONE</code> is returned.
+ *
+ * @return the alignment
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getAlignment () {
+ checkWidget ();
+ if ((style & SWT.SEPARATOR) != 0) return 0;
+ if ((style & SWT.LEFT) != 0) return SWT.LEFT;
+ if ((style & SWT.CENTER) != 0) return SWT.CENTER;
+ if ((style & SWT.RIGHT) != 0) return SWT.RIGHT;
+ return SWT.LEFT;
+}
+
+/**
+ * Returns the receiver's image if it has one, or null
+ * if it does not.
+ *
+ * @return the receiver's image
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Image getImage () {
+ checkWidget ();
+ return image;
+}
+
+String getNameText () {
+ return getText ();
+}
+
+/**
+ * Returns the receiver's text, which will be an empty
+ * string if it has never been set or if the receiver is
+ * a <code>SEPARATOR</code> label.
+ *
+ * @return the receiver's text
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String getText () {
+ checkWidget ();
+ if ((style & SWT.SEPARATOR) != 0) return "";
+ return text;
+}
+
+boolean mnemonicHit (char key) {
+ //TODO
+ return false;
+}
+
+boolean mnemonicMatch (char key) {
+ int accessText = OS.ContentControl_Content (handle);
+ boolean result = super.mnemonicMatch (accessText, key);
+ OS.GCHandle_Free (accessText);
+ return result;
+}
+
+void releaseWidget () {
+ super.releaseWidget ();
+ text = null;
+ image = null;
+}
+
+/**
+ * Controls how text and images will be displayed in the receiver.
+ * The argument should be one of <code>LEFT</code>, <code>RIGHT</code>
+ * or <code>CENTER</code>. If the receiver is a <code>SEPARATOR</code>
+ * label, the argument is ignored and the alignment is not changed.
+ *
+ * @param alignment the new alignment
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setAlignment (int alignment) {
+ checkWidget ();
+ if ((style & SWT.SEPARATOR) != 0) return;
+ if ((alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER)) == 0) return;
+ style &= ~(SWT.LEFT | SWT.RIGHT | SWT.CENTER);
+ style |= alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER);
+ int value = OS.HorizontalAlignment_Left;
+ if ((style & SWT.CENTER) != 0) value = OS.HorizontalAlignment_Center;
+ if ((style & SWT.RIGHT) != 0) value = OS.HorizontalAlignment_Right;
+ OS.Control_HorizontalContentAlignment (handle, value);
+}
+
+/**
+ * Sets the receiver's image to the argument, which may be
+ * null indicating that no image should be displayed.
+ *
+ * @param image the image to display on the receiver (may be null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setImage (Image image) {
+ checkWidget ();
+ if ((style & SWT.SEPARATOR) != 0) return;
+ if (image != null && image.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ this.image = image;
+ int imageHandle = OS.gcnew_Image ();
+ OS.Image_Stretch (imageHandle, OS.Stretch_None);
+ OS.Image_Source (imageHandle, image != null ? image.handle : 0);
+ OS.ContentControl_Content (handle, imageHandle);
+ OS.GCHandle_Free (imageHandle);
+}
+
+/**
+ * Sets the receiver's text.
+ * <p>
+ * This method sets the widget label. The label may include
+ * the mnemonic character and line delimiters.
+ * </p>
+ * <p>
+ * Mnemonics are indicated by an '&amp;' that causes the next
+ * character to be the mnemonic. When the user presses a
+ * key sequence that matches the mnemonic, focus is assigned
+ * to the control that follows the label. On most platforms,
+ * the mnemonic appears underlined but may be emphasised in a
+ * platform specific manner. The mnemonic indicator character
+ * '&amp;' can be escaped by doubling it in the string, causing
+ * a single '&amp;' to be displayed.
+ * </p>
+ *
+ * @param string the new text
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setText (String string) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if ((style & SWT.SEPARATOR) != 0) return;
+ if (string.equals (text)) return;
+ text = string;
+ int ptr = createDotNetString (text, true);
+ int accessText = OS.gcnew_AccessText ();
+ OS.AccessText_Text (accessText, ptr);
+ OS.ContentControl_Content (handle, accessText);
+ OS.GCHandle_Free (ptr);
+ OS.GCHandle_Free (accessText);
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Link.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Link.java
new file mode 100644
index 0000000000..acf09c31f9
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Link.java
@@ -0,0 +1,455 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.events.*;
+
+/**
+ * Instances of this class represent a selectable
+ * user interface object that displays a text with
+ * links.
+ * <p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>(none)</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Selection</dd>
+ * </dl>
+ * <p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ *
+ * @since 3.1
+ */
+public class Link extends Control {
+ Point [] offsets;
+ Point selection;
+ String [] ids;
+ String text;
+ private int[] mnemonics;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Link (Composite parent, int style) {
+ super (parent, style);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the control is selected, by sending
+ * it one of the messages defined in the <code>SelectionListener</code>
+ * interface.
+ * <p>
+ * <code>widgetSelected</code> is called when the control is selected.
+ * <code>widgetDefaultSelected</code> is not called.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #removeSelectionListener
+ * @see SelectionEvent
+ */
+public void addSelectionListener (SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Selection, typedListener);
+ addListener (SWT.DefaultSelection, typedListener);
+}
+
+int backgroundProperty () {
+ return OS.TextBlock_BackgroundProperty ();
+}
+
+void createHandle () {
+ state |= THEME_BACKGROUND;
+ handle = OS.gcnew_TextBlock ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+}
+
+int defaultBackground () {
+ return OS.SystemColors_ControlColor;
+}
+
+String getNameText () {
+ return getText ();
+}
+
+/**
+ * Returns the receiver's text, which will be an empty
+ * string if it has never been set.
+ *
+ * @return the receiver's text
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String getText () {
+ checkWidget ();
+ return text;
+}
+
+void HandleClick (int sender, int e) {
+ if (!checkEvent (e)) return;
+ int source = OS.RoutedEventArgs_Source (e);
+ int i = OS.FrameworkContentElement_Tag (source);
+ OS.GCHandle_Free (source);
+ Event event = new Event ();
+ event.text = ids [i];
+ sendEvent (SWT.Selection, event);
+}
+
+String parse (String string) {
+ int length = string.length ();
+ offsets = new Point [length / 4];
+ ids = new String [length / 4];
+ mnemonics = new int [length / 4 + 1];
+ StringBuffer result = new StringBuffer ();
+ char [] buffer = new char [length];
+ string.getChars (0, string.length (), buffer, 0);
+ int index = 0, state = 0, linkIndex = 0;
+ int start = 0, tagStart = 0, linkStart = 0, endtagStart = 0, refStart = 0;
+ while (index < length) {
+ char c = Character.toLowerCase (buffer [index]);
+ switch (state) {
+ case 0:
+ if (c == '<') {
+ tagStart = index;
+ state++;
+ }
+ break;
+ case 1:
+ if (c == 'a') state++;
+ break;
+ case 2:
+ switch (c) {
+ case 'h':
+ state = 7;
+ break;
+ case '>':
+ linkStart = index + 1;
+ state++;
+ break;
+ default:
+ if (Character.isWhitespace(c)) break;
+ else state = 13;
+ }
+ break;
+ case 3:
+ if (c == '<') {
+ endtagStart = index;
+ state++;
+ }
+ break;
+ case 4:
+ state = c == '/' ? state + 1 : 3;
+ break;
+ case 5:
+ state = c == 'a' ? state + 1 : 3;
+ break;
+ case 6:
+ if (c == '>') {
+ mnemonics [linkIndex] = parseMnemonics (buffer, start, tagStart, result);
+ int offset = result.length ();
+ parseMnemonics (buffer, linkStart, endtagStart, result);
+ offsets [linkIndex] = new Point (offset, result.length () - 1);
+ if (ids [linkIndex] == null) {
+ ids [linkIndex] = new String (buffer, linkStart, endtagStart - linkStart);
+ }
+ linkIndex++;
+ start = tagStart = linkStart = endtagStart = refStart = index + 1;
+ state = 0;
+ } else {
+ state = 3;
+ }
+ break;
+ case 7:
+ state = c == 'r' ? state + 1 : 0;
+ break;
+ case 8:
+ state = c == 'e' ? state + 1 : 0;
+ break;
+ case 9:
+ state = c == 'f' ? state + 1 : 0;
+ break;
+ case 10:
+ state = c == '=' ? state + 1 : 0;
+ break;
+ case 11:
+ if (c == '"') {
+ state++;
+ refStart = index + 1;
+ } else {
+ state = 0;
+ }
+ break;
+ case 12:
+ if (c == '"') {
+ ids[linkIndex] = new String (buffer, refStart, index - refStart);
+ state = 2;
+ }
+ break;
+ case 13:
+ if (Character.isWhitespace (c)) {
+ state = 0;
+ } else if (c == '='){
+ state++;
+ }
+ break;
+ case 14:
+ state = c == '"' ? state + 1 : 0;
+ break;
+ case 15:
+ if (c == '"') state = 2;
+ break;
+ default:
+ state = 0;
+ break;
+ }
+ index++;
+ }
+ if (start < length) {
+ int tmp = parseMnemonics (buffer, start, tagStart, result);
+ int mnemonic = parseMnemonics (buffer, linkStart, index, result);
+ if (mnemonic == -1) mnemonic = tmp;
+ mnemonics [linkIndex] = mnemonic;
+ } else {
+ mnemonics [linkIndex] = -1;
+ }
+ if (offsets.length != linkIndex) {
+ Point [] newOffsets = new Point [linkIndex];
+ System.arraycopy (offsets, 0, newOffsets, 0, linkIndex);
+ offsets = newOffsets;
+ String [] newIDs = new String [linkIndex];
+ System.arraycopy (ids, 0, newIDs, 0, linkIndex);
+ ids = newIDs;
+ int [] newMnemonics = new int [linkIndex + 1];
+ System.arraycopy (mnemonics, 0, newMnemonics, 0, linkIndex + 1);
+ mnemonics = newMnemonics;
+ }
+ return result.toString ();
+}
+
+int parseMnemonics (char [] buffer, int start, int end, StringBuffer result) {
+ int mnemonic = -1, index = start;
+ while (index < end) {
+ if (buffer [index] == '&') {
+ if (index + 1 < end && buffer [index + 1] == '&') {
+ result.append (buffer [index]);
+ index++;
+ } else {
+ mnemonic = result.length();
+ }
+ } else {
+ result.append (buffer [index]);
+ }
+ index++;
+ }
+ return mnemonic;
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the control is selected.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #addSelectionListener
+ */
+public void removeSelectionListener (SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Selection, listener);
+ eventTable.unhook (SWT.DefaultSelection, listener);
+}
+
+void setFont (int font, double size) {
+ if (font != 0) {
+ int fontFamily = OS.Typeface_FontFamily( font);
+ int style = OS.Typeface_Style (font);
+ int weight = OS.Typeface_Weight (font);
+ int stretch = OS.Typeface_Stretch (font);
+ OS.TextBlock_FontFamily (handle, fontFamily);
+ OS.TextBlock_FontStyle (handle, style);
+ OS.TextBlock_FontWeight (handle, weight);
+ OS.TextBlock_FontStretch (handle, stretch);
+ OS.TextBlock_FontSize (handle, size);
+ OS.GCHandle_Free (fontFamily);
+ OS.GCHandle_Free (style);
+ OS.GCHandle_Free (weight);
+ OS.GCHandle_Free (stretch);
+ } else {
+ int property = OS.TextBlock_FontFamilyProperty ();
+ OS.DependencyObject_ClearValue (handle, property);
+ OS.GCHandle_Free (property);
+ property = OS.TextBlock_FontStyleProperty ();
+ OS.DependencyObject_ClearValue (handle, property);
+ OS.GCHandle_Free (property);
+ property = OS.TextBlock_FontWeightProperty ();
+ OS.DependencyObject_ClearValue (handle, property);
+ OS.GCHandle_Free (property);
+ property = OS.TextBlock_FontStretchProperty ();
+ OS.DependencyObject_ClearValue (handle, property);
+ OS.GCHandle_Free (property);
+ property = OS.TextBlock_FontSizeProperty ();
+ OS.DependencyObject_ClearValue (handle, property);
+ OS.GCHandle_Free (property);
+ }
+}
+
+void setForegroundBrush (int brush) {
+//TODO
+}
+
+/**
+ * Sets the receiver's text.
+ * <p>
+ * The string can contain both regular text and hyperlinks. A hyperlink
+ * is delimited by an anchor tag, &lt;A&gt; and &lt;/A&gt;. Within an
+ * anchor, a single HREF attribute is supported. When a hyperlink is
+ * selected, the text field of the selection event contains either the
+ * text of the hyperlink or the value of its HREF, if one was specified.
+ * In the rare case of identical hyperlinks within the same string, the
+ * HREF tag can be used to distinguish between them. The string may
+ * include the mnemonic character and line delimiters.
+ * </p>
+ *
+ * @param string the new text
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setText (String string) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (string.equals (text)) return;
+ text = string;
+ String parsed = parse (string);
+ int inlines = OS.TextBlock_Inlines (handle);
+ OS.InlineCollection_Clear (inlines);
+ int start = 0, end = parsed.length ();
+ int offsetIndex = 0;
+ while (start < end) {
+ Point point = offsetIndex < offsets.length ? offsets [offsetIndex] : null;
+ if (point == null) {
+ String substring = parsed.substring (start, end);
+ int stringPtr = createDotNetString (substring, false);
+ if (stringPtr == 0) error(SWT.ERROR_NO_HANDLES);
+ int run = OS.gcnew_Run ();
+ if (run == 0) error(SWT.ERROR_NO_HANDLES);
+ OS.Run_Text (run, stringPtr);
+ OS.InlineCollection_Add (inlines, run);
+ OS.GCHandle_Free (stringPtr);
+ OS.GCHandle_Free (run);
+ start = end;
+ } else {
+ if (start < point.x) {
+ String substring = parsed.substring (start, point.x);
+ int stringPtr = createDotNetString (substring, false);
+ if (stringPtr == 0) error(SWT.ERROR_NO_HANDLES);
+ int run = OS.gcnew_Run ();
+ if (run == 0) error(SWT.ERROR_NO_HANDLES);
+ OS.Run_Text (run, stringPtr);
+ OS.InlineCollection_Add (inlines, run);
+ OS.GCHandle_Free (stringPtr);
+ OS.GCHandle_Free (run);
+ start = point.x;
+ } else {
+ String substring = parsed.substring (point.x, point.y+1);
+ int stringPtr = createDotNetString (substring, false);
+ if (stringPtr == 0) error(SWT.ERROR_NO_HANDLES);
+ int run = OS.gcnew_Run ();
+ if (run == 0) error(SWT.ERROR_NO_HANDLES);
+ OS.Run_Text (run, stringPtr);
+ int hyperlink = OS.gcnew_Hyperlink (run);
+ OS.FrameworkContentElement_Tag (hyperlink, offsetIndex);
+ OS.InlineCollection_Add (inlines, hyperlink);
+ int handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleClick");
+ OS.Hyperlink_Click (hyperlink, handler);
+ OS.GCHandle_Free (handler);
+ OS.GCHandle_Free (stringPtr);
+ OS.GCHandle_Free (run);
+ OS.GCHandle_Free (hyperlink);
+ start = point.y+1;
+ offsetIndex++;
+ }
+ }
+ }
+ OS.GCHandle_Free (inlines);
+}
+
+int traversalCode (int key, int event) {
+// if (offsets.length == 0) return 0;
+ int bits = super.traversalCode (key, event);
+// if (key == OS.Key_Tab && focusIndex < offsets.length - 1) {
+// return bits & ~SWT.TRAVERSE_TAB_NEXT;
+// }
+// if (key == OS.GDK_ISO_Left_Tab && focusIndex > 0) {
+// return bits & ~SWT.TRAVERSE_TAB_PREVIOUS;
+// }
+ //TODO
+ return bits;
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/List.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/List.java
new file mode 100644
index 0000000000..4c7c20c488
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/List.java
@@ -0,0 +1,1162 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.events.*;
+
+/**
+ * Instances of this class represent a selectable user interface
+ * object that displays a list of strings and issues notification
+ * when a string is selected. A list may be single or multi select.
+ * <p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>SINGLE, MULTI</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Selection, DefaultSelection</dd>
+ * </dl>
+ * <p>
+ * Note: Only one of SINGLE and MULTI may be specified.
+ * </p><p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ */
+
+public class List extends Scrollable {
+ boolean ignoreSelection;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#SINGLE
+ * @see SWT#MULTI
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public List (Composite parent, int style) {
+ super (parent, checkStyle (style));
+}
+
+/**
+ * Adds the argument to the end of the receiver's list.
+ *
+ * @param string the new item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #add(String,int)
+ */
+public void add (String string) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int item = OS.gcnew_ListBoxItem ();
+ int strPtr = createDotNetString (string, false);
+ OS.ContentControl_Content (item, strPtr);
+ OS.GCHandle_Free (strPtr);
+ int items = OS.ItemsControl_Items (handle);
+ OS.ItemCollection_Add (items, item);
+ OS.GCHandle_Free (items);
+ OS.GCHandle_Free (item);
+}
+
+/**
+ * Adds the argument to the receiver's list at the given
+ * zero-relative index.
+ * <p>
+ * Note: To add an item at the end of the list, use the
+ * result of calling <code>getItemCount()</code> as the
+ * index or use <code>add(String)</code>.
+ * </p>
+ *
+ * @param string the new item
+ * @param index the index for the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #add(String)
+ */
+public void add (String string, int index) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (index < 0 || index > getItemCount ()) error (SWT.ERROR_INVALID_RANGE);
+ int item = OS.gcnew_ListBoxItem ();
+ int strPtr = createDotNetString (string, false);
+ OS.ContentControl_Content (item, strPtr);
+ OS.GCHandle_Free (strPtr);
+ int items = OS.ItemsControl_Items (handle);
+ OS.ItemCollection_Insert (items, index, item);
+ OS.GCHandle_Free (items);
+ OS.GCHandle_Free (item);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the receiver's selection changes, by sending
+ * it one of the messages defined in the <code>SelectionListener</code>
+ * interface.
+ * <p>
+ * <code>widgetSelected</code> is called when the selection changes.
+ * <code>widgetDefaultSelected</code> is typically called when an item is double-clicked.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #removeSelectionListener
+ * @see SelectionEvent
+ */
+public void addSelectionListener(SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Selection,typedListener);
+ addListener (SWT.DefaultSelection,typedListener);
+}
+
+static int checkStyle (int style) {
+ return checkBits (style, SWT.SINGLE, SWT.MULTI, 0, 0, 0, 0);
+}
+
+void createHandle () {
+ handle = OS.gcnew_ListBox ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.Selector_IsSynchronizedWithCurrentItem (handle, true);
+ if ((style & SWT.MULTI) != 0) OS.ListBox_SelectionMode (handle, OS.SelectionMode_Extended);
+}
+
+/**
+ * Deselects the items at the given zero-relative indices in the receiver.
+ * If the item at the given zero-relative index in the receiver
+ * is selected, it is deselected. If the item at the index
+ * was not selected, it remains deselected. Indices that are out
+ * of range and duplicate indices are ignored.
+ *
+ * @param indices the array of indices for the items to deselect
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the set of indices is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void deselect (int [] indices) {
+ checkWidget ();
+ if (indices == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (indices.length == 0) return;
+ int count = getItemCount ();
+ int items = OS.ItemsControl_Items (handle);
+ ignoreSelection = true;
+ for (int i = 0; i < indices.length; i++) {
+ int index = indices [i];
+ if (0 <= index && index < count) {
+ int item = OS.ItemCollection_GetItemAt (items, index);
+ OS.ListBoxItem_IsSelected (item, false);
+ OS.GCHandle_Free (item);
+ }
+ }
+ ignoreSelection = false;
+ OS.GCHandle_Free (items);
+}
+
+/**
+ * Deselects the item at the given zero-relative index in the receiver.
+ * If the item at the index was already deselected, it remains
+ * deselected. Indices that are out of range are ignored.
+ *
+ * @param index the index of the item to deselect
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void deselect (int index) {
+ checkWidget ();
+ if (index == -1) return;
+ if (0 <= index && index < getItemCount ()) {
+ int items = OS.ItemsControl_Items (handle);
+ int item = OS.ItemCollection_GetItemAt (items, index);
+ OS.GCHandle_Free (items);
+ ignoreSelection = true;
+ OS.ListBoxItem_IsSelected (item, false);
+ ignoreSelection = false;
+ OS.GCHandle_Free (item);
+ }
+}
+
+/**
+ * Deselects the items at the given zero-relative indices in the receiver.
+ * If the item at the given zero-relative index in the receiver
+ * is selected, it is deselected. If the item at the index
+ * was not selected, it remains deselected. The range of the
+ * indices is inclusive. Indices that are out of range are ignored.
+ *
+ * @param start the start index of the items to deselect
+ * @param end the end index of the items to deselect
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void deselect (int start, int end) {
+ checkWidget ();
+ if (start > end) return;
+ int count = getItemCount ();
+ int items = OS.ItemsControl_Items (handle);
+ ignoreSelection = true;
+ for (int i = end; i >= start; i--) {
+ if (0 <= i && i < count) {
+ int item = OS.ItemCollection_GetItemAt (items, i);
+ OS.ListBoxItem_IsSelected (item, false);
+ OS.GCHandle_Free (item);
+ }
+ }
+ ignoreSelection = false;
+ OS.GCHandle_Free (items);
+}
+
+/**
+ * Deselects all selected items in the receiver.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void deselectAll () {
+ checkWidget ();
+ OS.ListBox_UnselectAll (handle);
+}
+
+/**
+ * Returns the zero-relative index of the item which currently
+ * has the focus in the receiver, or -1 if no item has focus.
+ *
+ * @return the index of the selected item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getFocusIndex () {
+ checkWidget ();
+ int items = OS.ItemsControl_Items (handle);
+ int index = OS.ItemCollection_CurrentPosition (items);
+ OS.GCHandle_Free (items);
+ return index;
+}
+
+/**
+ * Returns the item at the given, zero-relative index in the
+ * receiver. Throws an exception if the index is out of range.
+ *
+ * @param index the index of the item to return
+ * @return the item at the given index
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String getItem (int index) {
+ checkWidget ();
+ int count = getItemCount ();
+ if (index < 0 || index >= count) error (SWT.ERROR_INVALID_RANGE);
+ int items = OS.ItemsControl_Items (handle);
+ int item = OS.ItemCollection_GetItemAt (items, index);
+ OS.GCHandle_Free (items);
+ int content = OS.ContentControl_Content (item);
+ OS.GCHandle_Free (item);
+ String string = createJavaString (content);
+ OS.GCHandle_Free (content);
+ return string;
+}
+
+/**
+ * Returns the number of items contained in the receiver.
+ *
+ * @return the number of items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getItemCount () {
+ checkWidget ();
+ int items = OS.ItemsControl_Items (handle);
+ int count = OS.ItemCollection_Count (items);
+ OS.GCHandle_Free (items);
+ return count;
+}
+
+/**
+ * Returns the height of the area which would be used to
+ * display <em>one</em> of the items in the list.
+ *
+ * @return the height of one item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getItemHeight () {
+ checkWidget ();
+ //FIXME: should not return 0 when there are no items
+ int result = 0;
+ if (OS.ItemsControl_HasItems (handle)) {
+ int items = OS.ItemsControl_Items (handle);
+ int item = OS.ItemCollection_GetItemAt (items, 0);
+ OS.GCHandle_Free (items);
+ result = (int) OS.FrameworkElement_ActualHeight (item);
+ OS.GCHandle_Free (item);
+ }
+ return result;
+}
+
+/**
+ * Returns a (possibly empty) array of <code>String</code>s which
+ * are the items in the receiver.
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its list of items, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ *
+ * @return the items in the receiver's list
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String [] getItems () {
+ checkWidget ();
+ int count = getItemCount ();
+ String [] result = new String [count];
+ for (int i=0; i<count; i++) result [i] = getItem (i);
+ return result;
+}
+
+/**
+ * Returns an array of <code>String</code>s that are currently
+ * selected in the receiver. The order of the items is unspecified.
+ * An empty array indicates that no items are selected.
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its selection, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ * @return an array representing the selection
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String [] getSelection () {
+ checkWidget ();
+ int [] indices = getSelectionIndices ();
+ String [] result = new String [indices.length];
+ for (int i=0; i<indices.length; i++) {
+ result [i] = getItem (indices [i]);
+ }
+ return result;
+}
+
+/**
+ * Returns the number of selected items contained in the receiver.
+ *
+ * @return the number of selected items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getSelectionCount () {
+ checkWidget ();
+ int selectedItems = OS.ListBox_SelectedItems (handle);
+ int result = OS.ICollection_Count (selectedItems);
+ OS.GCHandle_Free (selectedItems);
+ return result;
+}
+
+/**
+ * Returns the zero-relative index of the item which is currently
+ * selected in the receiver, or -1 if no item is selected.
+ *
+ * @return the index of the selected item or -1
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getSelectionIndex () {
+ checkWidget ();
+ return OS.Selector_SelectedIndex (handle);
+}
+
+/**
+ * Returns the zero-relative indices of the items which are currently
+ * selected in the receiver. The order of the indices is unspecified.
+ * The array is empty if no items are selected.
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its selection, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ * @return the array of indices of the selected items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int [] getSelectionIndices () {
+ checkWidget ();
+ int items = OS.ItemsControl_Items (handle);
+ int list = OS.ListBox_SelectedItems (handle);
+ int enumerator = OS.IList_GetEnumerator (list);
+ int count = OS.ICollection_Count (list);
+ int [] indices = new int [count];
+ int index = 0;
+ while (OS.IEnumerator_MoveNext (enumerator)) {
+ int item = OS.IEnumerator_Current (enumerator);
+ indices [index++] = OS.ItemCollection_IndexOf (items, item);
+ OS.GCHandle_Free (item);
+ }
+ OS.GCHandle_Free (enumerator);
+ OS.GCHandle_Free (list);
+ OS.GCHandle_Free (items);
+ return indices;
+}
+
+/**
+ * Returns the zero-relative index of the item which is currently
+ * at the top of the receiver. This index can change when items are
+ * scrolled or new items are added or removed.
+ *
+ * @return the index of the top item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getTopIndex () {
+ checkWidget ();
+ int topIndex = 0;
+ if (OS.ItemsControl_HasItems (handle)) {
+ int items = OS.ItemsControl_Items (handle);
+ int item = OS.ItemCollection_GetItemAt (items, 0);
+ OS.GCHandle_Free (items);
+ int virtualizingStackPanel = OS.VisualTreeHelper_GetParent (item);
+ OS.GCHandle_Free (item);
+ if (virtualizingStackPanel != 0) {
+ topIndex = (int) OS.VirtualizingStackPanel_VerticalOffset (virtualizingStackPanel);
+ OS.GCHandle_Free (virtualizingStackPanel);
+ }
+ }
+ return topIndex;
+}
+
+void HandleSelectionChanged (int sender, int e) {
+ //FIXME: double click should send DefaultSelection
+ if (!checkEvent (e)) return;
+ if (!ignoreSelection) postEvent(SWT.Selection);
+}
+
+void hookEvents () {
+ super.hookEvents ();
+ int handler = OS.gcnew_SelectionChangedEventHandler (jniRef, "HandleSelectionChanged");
+ OS.Selector_SelectionChanged (handle, handler);
+ OS.GCHandle_Free (handler);
+}
+
+/**
+ * Gets the index of an item.
+ * <p>
+ * The list is searched starting at 0 until an
+ * item is found that is equal to the search item.
+ * If no item is found, -1 is returned. Indexing
+ * is zero based.
+ *
+ * @param string the search item
+ * @return the index of the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int indexOf (String string) {
+ return indexOf (string, 0);
+}
+
+/**
+ * Searches the receiver's list starting at the given,
+ * zero-relative index until an item is found that is equal
+ * to the argument, and returns the index of that item. If
+ * no item is found or the starting index is out of range,
+ * returns -1.
+ *
+ * @param string the search item
+ * @param start the zero-relative index at which to start the search
+ * @return the index of the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int indexOf (String string, int start) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int count = getItemCount ();
+ if (start >= count) return -1;
+ start = Math.max (start, 0);
+ int strPtr = createDotNetString (string, false);
+ int items = OS.ItemsControl_Items (handle);
+ int index = -1;
+ while (start < count && index == -1) {
+ int item = OS.ItemCollection_GetItemAt (items, start);
+ int content = OS.ContentControl_Content (item);
+ OS.GCHandle_Free (item);
+ if (content != 0) {
+ if (OS.Object_Equals (content, strPtr)) index = start;
+ OS.GCHandle_Free (content);
+ }
+ start++;
+ }
+ OS.GCHandle_Free (strPtr);
+ OS.GCHandle_Free (items);
+ return index;
+}
+
+/**
+ * Returns <code>true</code> if the item is selected,
+ * and <code>false</code> otherwise. Indices out of
+ * range are ignored.
+ *
+ * @param index the index of the item
+ * @return the visibility state of the item at the index
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean isSelected (int index) {
+ checkWidget ();
+ boolean selected = false;
+ if (index >= 0 && index < getItemCount ()) {
+ int items = OS.ItemsControl_Items (handle);
+ int item = OS.ItemCollection_GetItemAt (items, index);
+ selected = OS.ListBoxItem_IsSelected (item);
+ OS.GCHandle_Free (items);
+ OS.GCHandle_Free (item);
+ }
+ return selected;
+}
+
+/**
+ * Removes the items from the receiver at the given
+ * zero-relative indices.
+ *
+ * @param indices the array of indices of the items
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * <li>ERROR_NULL_ARGUMENT - if the indices array is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void remove (int [] indices) {
+ checkWidget ();
+ if (indices == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (indices.length == 0) return;
+ int [] newIndices = new int [indices.length];
+ System.arraycopy (indices, 0, newIndices, 0, indices.length);
+ sort (newIndices);
+ int start = newIndices [newIndices.length - 1], end = newIndices [0];
+ int count = getItemCount ();
+ if (!(0 <= start && start <= end && end < count)) {
+ error (SWT.ERROR_INVALID_RANGE);
+ }
+ int items = OS.ItemsControl_Items (handle);
+ for (int i = newIndices.length-1; i >= 0; i--) {
+ OS.ItemCollection_RemoveAt (items, indices [i]);
+ }
+ OS.GCHandle_Free (items);
+}
+
+/**
+ * Removes the item from the receiver at the given
+ * zero-relative index.
+ *
+ * @param index the index for the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void remove (int index) {
+ checkWidget ();
+ if (index < 0 || index >= getItemCount ()) error (SWT.ERROR_INVALID_RANGE);
+ int items = OS.ItemsControl_Items (handle);
+ OS.ItemCollection_RemoveAt (items, index);
+ OS.GCHandle_Free (items);
+}
+
+/**
+ * Removes the items from the receiver which are
+ * between the given zero-relative start and end
+ * indices (inclusive).
+ *
+ * @param start the start of the range
+ * @param end the end of the range
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if either the start or end are not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void remove (int start, int end) {
+ checkWidget ();
+ if (start > end) return;
+ int count = getItemCount ();
+ if (!(0 <= start && start <= end && end < count)) error (SWT.ERROR_INVALID_RANGE);
+ if (start == 0 && end == count - 1) {
+ removeAll ();
+ return;
+ }
+ int items = OS.ItemsControl_Items (handle);
+ for (int i = end; i >= start; i--) {
+ OS.ItemCollection_RemoveAt (items, i);
+ }
+ OS.GCHandle_Free (items);
+}
+
+/**
+ * Searches the receiver's list starting at the first item
+ * until an item is found that is equal to the argument,
+ * and removes that item from the list.
+ *
+ * @param string the item to remove
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the string is not found in the list</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void remove (String string) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int index = indexOf (string, 0);
+ if (index == -1) error (SWT.ERROR_INVALID_ARGUMENT);
+ remove (index);
+}
+
+/**
+ * Removes all of the items from the receiver.
+ * <p>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void removeAll () {
+ checkWidget ();
+ int items = OS.ItemsControl_Items (handle);
+ OS.ItemCollection_Clear (items);
+ OS.GCHandle_Free (items);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the receiver's selection changes.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #addSelectionListener
+ */
+public void removeSelectionListener(SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Selection, listener);
+ eventTable.unhook (SWT.DefaultSelection,listener);
+}
+
+/**
+ * Selects the items at the given zero-relative indices in the receiver.
+ * The current selection is not cleared before the new items are selected.
+ * <p>
+ * If the item at a given index is not selected, it is selected.
+ * If the item at a given index was already selected, it remains selected.
+ * Indices that are out of range and duplicate indices are ignored.
+ * If the receiver is single-select and multiple indices are specified,
+ * then all indices are ignored.
+ *
+ * @param indices the array of indices for the items to select
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the array of indices is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see List#setSelection(int[])
+ */
+public void select (int [] indices) {
+ checkWidget ();
+ if (indices == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int length = indices.length;
+ if (length == 0 || ((style & SWT.SINGLE) != 0 && length > 1)) return;
+ select (indices, false);
+}
+
+void select (int [] indices, boolean scroll) {
+ int i = 0;
+ while (i < indices.length) {
+ int index = indices [i];
+ if (index != -1) {
+ select (index, false);
+ }
+ i++;
+ }
+ if (scroll) showSelection ();
+}
+
+/**
+ * Selects the item at the given zero-relative index in the receiver's
+ * list. If the item at the index was already selected, it remains
+ * selected. Indices that are out of range are ignored.
+ *
+ * @param index the index of the item to select
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void select (int index) {
+ checkWidget ();
+ select (index, false);
+}
+
+void select (int index, boolean scroll) {
+ if (index < 0) return;
+ int count = getItemCount ();
+ if (index >= count) return;
+ int items = OS.ItemsControl_Items (handle);
+ int item = OS.ItemCollection_GetItemAt (items, index);
+ OS.GCHandle_Free (items);
+ ignoreSelection = true;
+ OS.ListBoxItem_IsSelected (item, true);
+ ignoreSelection = false;
+ if (scroll) OS.FrameworkElement_BringIntoView (item);
+ OS.GCHandle_Free (item);
+}
+
+/**
+ * Selects the items in the range specified by the given zero-relative
+ * indices in the receiver. The range of indices is inclusive.
+ * The current selection is not cleared before the new items are selected.
+ * <p>
+ * If an item in the given range is not selected, it is selected.
+ * If an item in the given range was already selected, it remains selected.
+ * Indices that are out of range are ignored and no items will be selected
+ * if start is greater than end.
+ * If the receiver is single-select and there is more than one item in the
+ * given range, then all indices are ignored.
+ *
+ * @param start the start of the range
+ * @param end the end of the range
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see List#setSelection(int,int)
+ */
+public void select (int start, int end) {
+ checkWidget ();
+ if (end < 0 || start > end || ((style & SWT.SINGLE) != 0 && start != end)) return;
+ int count = getItemCount ();
+ if (count == 0 || start >= count) return;
+ start = Math.max (0, start);
+ end = Math.min (end, count - 1);
+ ignoreSelection = true;
+ if ((style & SWT.SINGLE) != 0) {
+ select (start, false);
+ } else {
+ select (start, end, false);
+ }
+ ignoreSelection = false;
+}
+
+void select (int start, int end, boolean scroll) {
+ int items = OS.ItemsControl_Items (handle);
+ ignoreSelection = true;
+ for (int i = start; i<=end; i++) {
+ int item = OS.ItemCollection_GetItemAt (items, i);
+ OS.ListBoxItem_IsSelected (item, true);
+ OS.GCHandle_Free (item);
+ }
+ ignoreSelection = false;
+ OS.GCHandle_Free (items);
+ if (scroll) showSelection ();
+}
+
+/**
+ * Selects all of the items in the receiver.
+ * <p>
+ * If the receiver is single-select, do nothing.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void selectAll () {
+ checkWidget ();
+ if ((style & SWT.SINGLE) != 0) return;
+ ignoreSelection = true;
+ OS.ListBox_SelectAll (handle);
+ ignoreSelection = false;
+}
+
+/**
+ * Sets the text of the item in the receiver's list at the given
+ * zero-relative index to the string argument. This is equivalent
+ * to <code>remove</code>'ing the old item at the index, and then
+ * <code>add</code>'ing the new item at that index.
+ *
+ * @param index the index for the item
+ * @param string the new text for the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setItem (int index, String string) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int topIndex = getTopIndex ();
+ boolean isSelected = isSelected (index);
+ remove (index);
+ add (string, index);
+ if (isSelected) select (index, false);
+ setTopIndex (topIndex);
+}
+
+/**
+ * Sets the receiver's items to be the given array of items.
+ *
+ * @param items the array of items
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the items array is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if an item in the items array is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setItems (String [] items) {
+ checkWidget ();
+ if (items == null) error (SWT.ERROR_NULL_ARGUMENT);
+ for (int i=0; i<items.length; i++) {
+ if (items [i] == null) error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+ int itemCollection = OS.ItemsControl_Items (handle);
+ OS.ItemCollection_Clear (itemCollection);
+ for (int i = 0; i < items.length; i++) {
+ String string = items [i];
+ int item = OS.gcnew_ListBoxItem ();
+ int strPtr = createDotNetString (string, false);
+ OS.ContentControl_Content (item, strPtr);
+ OS.GCHandle_Free (strPtr);
+ OS.ItemCollection_Add (itemCollection, item);
+ OS.GCHandle_Free (item);
+ }
+ OS.GCHandle_Free (itemCollection);
+}
+
+/**
+ * Selects the items at the given zero-relative indices in the receiver.
+ * The current selection is cleared before the new items are selected.
+ * <p>
+ * Indices that are out of range and duplicate indices are ignored.
+ * If the receiver is single-select and multiple indices are specified,
+ * then all indices are ignored.
+ *
+ * @param indices the indices of the items to select
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the array of indices is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see List#deselectAll()
+ * @see List#select(int[])
+ */
+public void setSelection (int [] indices) {
+ checkWidget ();
+ if (indices == null) error (SWT.ERROR_NULL_ARGUMENT);
+ deselectAll ();
+ int length = indices.length;
+ if (length == 0 || ((style & SWT.SINGLE) != 0 && length > 1)) return;
+ select (indices, true);
+}
+
+/**
+ * Sets the receiver's selection to be the given array of items.
+ * The current selection is cleared before the new items are selected.
+ * <p>
+ * Items that are not in the receiver are ignored.
+ * If the receiver is single-select and multiple items are specified,
+ * then all items are ignored.
+ *
+ * @param items the array of items
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the array of items is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see List#deselectAll()
+ * @see List#select(int[])
+ * @see List#setSelection(int[])
+ */
+public void setSelection (String [] items) {
+ checkWidget ();
+ if (items == null) error (SWT.ERROR_NULL_ARGUMENT);
+ deselectAll ();
+ int length = items.length;
+ if (length == 0 || ((style & SWT.SINGLE) != 0 && length > 1)) return;
+ for (int i=length-1; i>=0; --i) {
+ String string = items [i];
+ int index = 0;
+ if (string != null) {
+ while ((index = indexOf (string, index)) != -1) {
+ select (index, false);
+ if ((style & SWT.SINGLE) != 0 && isSelected (index)) {
+ showSelection ();
+ return;
+ }
+ index++;
+ }
+ }
+ }
+}
+
+/**
+ * Selects the item at the given zero-relative index in the receiver.
+ * If the item at the index was already selected, it remains selected.
+ * The current selection is first cleared, then the new item is selected.
+ * Indices that are out of range are ignored.
+ *
+ * @param index the index of the item to select
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ * @see List#deselectAll()
+ * @see List#select(int)
+ */
+public void setSelection (int index) {
+ checkWidget ();
+ deselectAll ();
+ select (index, true);
+}
+
+/**
+ * Selects the items in the range specified by the given zero-relative
+ * indices in the receiver. The range of indices is inclusive.
+ * The current selection is cleared before the new items are selected.
+ * <p>
+ * Indices that are out of range are ignored and no items will be selected
+ * if start is greater than end.
+ * If the receiver is single-select and there is more than one item in the
+ * given range, then all indices are ignored.
+ *
+ * @param start the start index of the items to select
+ * @param end the end index of the items to select
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see List#deselectAll()
+ * @see List#select(int,int)
+ */
+public void setSelection (int start, int end) {
+ checkWidget ();
+ deselectAll ();
+ if (end < 0 || start > end || ((style & SWT.SINGLE) != 0 && start != end)) return;
+ int count = getItemCount ();
+ if (count == 0 || start >= count) return;
+ start = Math.max (0, start);
+ end = Math.min (end, count - 1);
+ if ((style & SWT.SINGLE) != 0) {
+ select (start, true);
+ } else {
+ select (start, end, true);
+ }
+}
+
+/**
+ * Sets the zero-relative index of the item which is currently
+ * at the top of the receiver. This index can change when items
+ * are scrolled or new items are added and removed.
+ *
+ * @param index the index of the top item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setTopIndex (int index) {
+ checkWidget ();
+ //FIXME: VirtualizingStackPanel.VerticalIndex cannot be set.
+}
+
+/**
+ * Shows the selection. If the selection is already showing in the receiver,
+ * this method simply returns. Otherwise, the items are scrolled until
+ * the selection is visible.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void showSelection () {
+ //TODO: does this scroll the first selected item into view if
+ // part of the selection is visible already???
+ checkWidget ();
+ int items = OS.ItemsControl_Items (handle);
+ int selectedItems = OS.ListBox_SelectedItems (handle);
+ int enumerator = OS.IList_GetEnumerator (selectedItems);
+ if (OS.IEnumerator_MoveNext (enumerator)) {
+ int item = OS.IEnumerator_Current (enumerator);
+ OS.ListBox_ScrollIntoView (handle, item);
+ OS.GCHandle_Free (item);
+ }
+ OS.GCHandle_Free (enumerator);
+ OS.GCHandle_Free (selectedItems);
+ OS.GCHandle_Free (items);
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Menu.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Menu.java
new file mode 100644
index 0000000000..a6b5460b5e
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Menu.java
@@ -0,0 +1,872 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.events.*;
+
+/**
+ * Instances of this class are user interface objects that contain
+ * menu items.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>BAR, DROP_DOWN, POP_UP, NO_RADIO_GROUP</dd>
+ * <dd>LEFT_TO_RIGHT, RIGHT_TO_LEFT</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Help, Hide, Show </dd>
+ * </dl>
+ * <p>
+ * Note: Only one of BAR, DROP_DOWN and POP_UP may be specified.
+ * Only one of LEFT_TO_RIGHT or RIGHT_TO_LEFT may be specified.
+ * </p><p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ */
+
+public class Menu extends Widget {
+ int itemCount;
+ MenuItem cascade, selected;
+ MenuItem [] items;
+ Decorations parent;
+
+/**
+ * Constructs a new instance of this class given its parent,
+ * and sets the style for the instance so that the instance
+ * will be a popup menu on the given parent's shell.
+ *
+ * @param parent a control which will be the parent of the new instance (cannot be null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#POP_UP
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Menu (Control parent) {
+ this (checkNull (parent).menuShell (), SWT.POP_UP);
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * (which must be a <code>Decorations</code>) and a style value
+ * describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a decorations control which will be the parent of the new instance (cannot be null)
+ * @param style the style of menu to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#BAR
+ * @see SWT#DROP_DOWN
+ * @see SWT#POP_UP
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Menu (Decorations parent, int style) {
+ this (parent, checkStyle (style), 0);
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * (which must be a <code>Menu</code>) and sets the style
+ * for the instance so that the instance will be a drop-down
+ * menu on the given parent's parent.
+ *
+ * @param parentMenu a menu which will be the parent of the new instance (cannot be null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#DROP_DOWN
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Menu (Menu parentMenu) {
+ this (checkNull (parentMenu).parent, SWT.DROP_DOWN);
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * (which must be a <code>MenuItem</code>) and sets the style
+ * for the instance so that the instance will be a drop-down
+ * menu on the given parent's parent menu.
+ *
+ * @param parentItem a menu item which will be the parent of the new instance (cannot be null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#DROP_DOWN
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Menu (MenuItem parentItem) {
+ this (checkNull (parentItem).parent);
+}
+
+Menu (Decorations parent, int style, int handle) {
+ super (parent, checkStyle (style));
+ this.parent = parent;
+ this.handle = handle;
+ createWidget ();
+}
+
+void _setVisible (boolean visible) {
+ if ((style & (SWT.BAR | SWT.DROP_DOWN)) != 0) return;
+ OS.ContextMenu_IsOpen (handle, visible);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when help events are generated for the control,
+ * by sending it one of the messages defined in the
+ * <code>HelpListener</code> interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see HelpListener
+ * @see #removeHelpListener
+ */
+public void addHelpListener (HelpListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Help, typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when menus are hidden or shown, by sending it
+ * one of the messages defined in the <code>MenuListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see MenuListener
+ * @see #removeMenuListener
+ */
+public void addMenuListener (MenuListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Hide,typedListener);
+ addListener (SWT.Show,typedListener);
+}
+
+static Control checkNull (Control control) {
+ if (control == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+ return control;
+}
+
+static Menu checkNull (Menu menu) {
+ if (menu == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+ return menu;
+}
+
+static MenuItem checkNull (MenuItem item) {
+ if (item == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+ return item;
+}
+
+static int checkStyle (int style) {
+ return checkBits (style, SWT.POP_UP, SWT.BAR, SWT.DROP_DOWN, 0, 0, 0);
+}
+
+void createHandle () {
+ int bits = SWT.BAR | SWT.DROP_DOWN | SWT.POP_UP;
+ switch (style & bits) {
+ case SWT.BAR:
+ handle = OS.gcnew_Menu ();
+ if (handle == 0) SWT.error (SWT.ERROR_NO_HANDLES);
+ break;
+ case SWT.POP_UP:
+ handle = OS.gcnew_ContextMenu ();
+ if (handle == 0) SWT.error (SWT.ERROR_NO_HANDLES);
+ OS.ContextMenu_Placement (handle, OS.PlacementMode_MousePoint);
+ break;
+ case SWT.DROP_DOWN:
+ handle = OS.gcnew_CompositeCollection ();
+ if (handle == 0) SWT.error (SWT.ERROR_NO_HANDLES);
+ break;
+ }
+}
+
+void createItem (MenuItem item, int index) {
+ if (!(0 <= index && index <= itemCount)) error (SWT.ERROR_INVALID_RANGE);
+ item.createWidget ();
+ if ((style & SWT.DROP_DOWN) != 0) {
+ OS.CompositeCollection_Insert (handle, index, item.handle);
+ } else {
+ int itemCollection = OS.ItemsControl_Items (handle);
+ OS.ItemCollection_Insert (itemCollection, index, item.handle);
+ OS.GCHandle_Free (itemCollection);
+ }
+ if (itemCount == items.length) {
+ MenuItem [] newItems = new MenuItem [items.length + 4];
+ System.arraycopy (items, 0, newItems, 0, items.length);
+ items = newItems;
+ }
+ System.arraycopy (items, index, items, index+1, items.length-index-1);
+ items [index] = item;
+ itemCount++;
+}
+
+void createWidget () {
+ jniRef = OS.NewGlobalRef (this);
+ if (jniRef == 0) error (SWT.ERROR_NO_HANDLES);
+ checkOrientation (parent);
+ createHandle ();
+ parent.addMenu (this);
+ hookEvents ();
+ itemCount = 0;
+ items = new MenuItem [4];
+}
+
+void deregister () {
+ if ((style & SWT.DROP_DOWN) != 0) return;
+ display.removeWidget (handle);
+}
+
+void destroyItem (MenuItem item) {
+ int index = 0;
+ if ((style & SWT.DROP_DOWN) != 0) {
+ index = OS.CompositeCollection_IndexOf (handle, item.handle);
+ OS.CompositeCollection_Remove (handle, item.handle);
+ } else {
+ int itemCollection = OS.ItemsControl_Items (handle);
+ index = OS.ItemCollection_IndexOf (itemCollection, item.handle);
+ OS.ItemCollection_Remove (itemCollection, item.handle);
+ }
+ if (index < itemCount) {
+ System.arraycopy (items, index+1, items, index, items.length-index-1);
+ items [items.length-1] = null;
+ itemCount--;
+ }
+}
+
+void fixMenus (Decorations newParent) {
+ MenuItem [] items = getItems ();
+ for (int i=0; i<items.length; i++) {
+ items [i].fixMenus (newParent);
+ }
+ parent.removeMenu (this);
+ newParent.addMenu (this);
+ this.parent = newParent;
+}
+
+/**
+ * Returns a rectangle describing the receiver's size and location
+ * relative to its parent (or its display if its parent is null),
+ * unless the receiver is a menu or a shell. In this case, the
+ * location is relative to the display.
+ * <p>
+ * Note that the bounds of a menu or menu item are undefined when
+ * the menu is not visible. This is because most platforms compute
+ * the bounds of a menu dynamically just before it is displayed.
+ * </p>
+ *
+ * @return the receiver's bounding rectangle
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+/*public*/ Rectangle getBounds () {
+ checkWidget ();
+ if ((style & SWT.DROP_DOWN) != 0) return new Rectangle (0, 0, 0, 0);
+ if (!OS.UIElement_IsVisible (handle)) return new Rectangle (0, 0, 0, 0);
+ int point = OS.gcnew_Point (0, 0);
+ int location = OS.UIElement_TranslatePoint (handle, point, parent.handle);
+ int x = (int) OS.Point_X (location);
+ int y = (int) OS.Point_Y (location);
+ OS.GCHandle_Free (point);
+ OS.GCHandle_Free (location);
+ int width = (int) OS.FrameworkElement_ActualWidth (handle);
+ int height = (int) OS.FrameworkElement_ActualHeight (handle);
+ return new Rectangle (x, y, width, height);
+}
+
+/**
+ * Returns the default menu item or null if none has
+ * been previously set.
+ *
+ * @return the default menu item.
+ *
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public MenuItem getDefaultItem () {
+ checkWidget ();
+ return null;
+}
+
+/**
+ * Returns <code>true</code> if the receiver is enabled, and
+ * <code>false</code> otherwise. A disabled menu is typically
+ * not selectable from the user interface and draws with an
+ * inactive or "grayed" look.
+ *
+ * @return the receiver's enabled state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #isEnabled
+ */
+public boolean getEnabled () {
+ checkWidget ();
+ return (state & DISABLED) == 0;
+}
+
+/**
+ * Returns the item at the given, zero-relative index in the
+ * receiver. Throws an exception if the index is out of range.
+ *
+ * @param index the index of the item to return
+ * @return the item at the given index
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public MenuItem getItem (int index) {
+ checkWidget ();
+ if (index < 0 || index >= itemCount) error(SWT.ERROR_INVALID_RANGE);
+ return items [index];
+}
+
+/**
+ * Returns the number of items contained in the receiver.
+ *
+ * @return the number of items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getItemCount () {
+ checkWidget ();
+ return itemCount;
+}
+
+/**
+ * Returns a (possibly empty) array of <code>MenuItem</code>s which
+ * are the items in the receiver.
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its list of items, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ *
+ * @return the items in the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public MenuItem [] getItems () {
+ checkWidget ();
+ MenuItem [] result = new MenuItem [itemCount];
+ System.arraycopy(items, 0, result, 0, itemCount);
+ return result;
+}
+
+String getNameText () {
+ String result = "";
+ MenuItem [] items = getItems ();
+ int length = items.length;
+ if (length > 0) {
+ for (int i=0; i<length-1; i++) {
+ result = result + items [i].getNameText() + ", ";
+ }
+ result = result + items [length-1].getNameText ();
+ }
+ return result;
+}
+
+/**
+ * Returns the receiver's parent, which must be a <code>Decorations</code>.
+ *
+ * @return the receiver's parent
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Decorations getParent () {
+ checkWidget ();
+ return parent;
+}
+
+/**
+ * Returns the receiver's parent item, which must be a
+ * <code>MenuItem</code> or null when the receiver is a
+ * root.
+ *
+ * @return the receiver's parent item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public MenuItem getParentItem () {
+ checkWidget ();
+ return cascade;
+}
+
+/**
+ * Returns the receiver's parent item, which must be a
+ * <code>Menu</code> or null when the receiver is a
+ * root.
+ *
+ * @return the receiver's parent item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Menu getParentMenu () {
+ checkWidget ();
+ if (cascade != null) return cascade.parent;
+ return null;
+}
+
+/**
+ * Returns the receiver's shell. For all controls other than
+ * shells, this simply returns the control's nearest ancestor
+ * shell. Shells return themselves, even if they are children
+ * of other shells.
+ *
+ * @return the receiver's shell
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #getParent
+ */
+public Shell getShell () {
+ checkWidget ();
+ return parent.getShell ();
+}
+
+/**
+ * Returns <code>true</code> if the receiver is visible, and
+ * <code>false</code> otherwise.
+ * <p>
+ * If one of the receiver's ancestors is not visible or some
+ * other condition makes the receiver not visible, this method
+ * may still indicate that it is considered visible even though
+ * it may not actually be showing.
+ * </p>
+ *
+ * @return the receiver's visibility state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getVisible () {
+ checkWidget ();
+ if ((style & SWT.BAR) != 0) {
+ return this == parent.menuShell ().menuBar;
+ }
+ if ((style & SWT.POP_UP) != 0) {
+ Menu [] popups = display.popups;
+ if (popups == null) return false;
+ for (int i=0; i<popups.length; i++) {
+ if (popups [i] == this) return true;
+ }
+ }
+// Shell shell = getShell ();
+// Menu menu = shell.activeMenu;
+// while (menu != null && menu != this) {
+// menu = menu.getParentMenu ();
+// }
+// return this == menu;
+ return OS.UIElement_Visibility (handle) == OS.Visibility_Visible;
+}
+
+void HandleClosed (int sender, int e) {
+ if (!checkEvent (e)) return;
+ sendEvent (SWT.Hide);
+}
+
+void HandleOpened (int sender, int e) {
+ if (!checkEvent (e)) return;
+ sendEvent (SWT.Show);
+}
+
+void hookEvents() {
+ super.hookEvents ();
+ if ((style & SWT.POP_UP) != 0) {
+ int handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleClosed");
+ OS.ContextMenu_Closed (handle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleOpened");
+ OS.ContextMenu_Opened (handle, handler);
+ OS.GCHandle_Free (handler);
+ }
+}
+
+/**
+ * Searches the receiver's list starting at the first item
+ * (index 0) until an item is found that is equal to the
+ * argument, and returns the index of that item. If no item
+ * is found, returns -1.
+ *
+ * @param item the search item
+ * @return the index of the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int indexOf (MenuItem item) {
+ checkWidget ();
+ for (int i = 0; i < itemCount; i++) {
+ if (items[i] == item) return i;
+ }
+ return -1;
+}
+
+/**
+ * Returns <code>true</code> if the receiver is enabled and all
+ * of the receiver's ancestors are enabled, and <code>false</code>
+ * otherwise. A disabled menu is typically not selectable from the
+ * user interface and draws with an inactive or "grayed" look.
+ *
+ * @return the receiver's enabled state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #getEnabled
+ */
+public boolean isEnabled () {
+ checkWidget ();
+ Menu parentMenu = getParentMenu ();
+ if (parentMenu == null) return getEnabled ();
+ return getEnabled () && parentMenu.isEnabled ();
+}
+
+/**
+ * Returns <code>true</code> if the receiver is visible and all
+ * of the receiver's ancestors are visible and <code>false</code>
+ * otherwise.
+ *
+ * @return the receiver's visibility state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #getVisible
+ */
+public boolean isVisible () {
+ checkWidget ();
+ return getVisible ();
+}
+
+void register() {
+ if ((style & SWT.DROP_DOWN) != 0) return;
+ display.addWidget (handle, this);
+}
+
+void releaseChildren (boolean destroy) {
+ MenuItem [] items = getItems ();
+ for (int i=0; i<items.length; i++) {
+ MenuItem item = items [i];
+ if (item != null && !item.isDisposed ()) {
+ item.release (false);
+ }
+ }
+ super.releaseChildren (destroy);
+}
+
+void releaseHandle () {
+ super.releaseHandle ();
+ if (handle != 0) OS.GCHandle_Free (handle);
+ handle = 0;
+ parent = null;
+}
+
+void releaseParent () {
+ super.releaseParent ();
+ if (cascade != null) cascade.releaseMenu ();
+ if ((style & SWT.BAR) != 0) {
+// display.removeBar (this);
+ if (this == parent.menuBar) {
+ parent.setMenuBar (null);
+ }
+ } else {
+ if ((style & SWT.POP_UP) != 0) {
+ display.removePopup (this);
+ }
+ }
+}
+
+void releaseWidget () {
+ super.releaseWidget ();
+ if (parent != null) parent.removeMenu (this);
+ parent = null;
+ cascade = null;
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the help events are generated for the control.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see HelpListener
+ * @see #addHelpListener
+ */
+public void removeHelpListener (HelpListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Help, listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the menu events are generated for the control.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see MenuListener
+ * @see #addMenuListener
+ */
+public void removeMenuListener (MenuListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Hide, listener);
+ eventTable.unhook (SWT.Show, listener);
+}
+
+/**
+ * Sets the default menu item to the argument or removes
+ * the default emphasis when the argument is <code>null</code>.
+ *
+ * @param item the default menu item or null
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the menu item has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setDefaultItem (MenuItem item) {
+ checkWidget ();
+}
+
+/**
+ * Enables the receiver if the argument is <code>true</code>,
+ * and disables it otherwise. A disabled menu is typically
+ * not selectable from the user interface and draws with an
+ * inactive or "grayed" look.
+ *
+ * @param enabled the new enabled state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setEnabled (boolean enabled) {
+ checkWidget ();
+ state &= ~DISABLED;
+ if (!enabled) state |= DISABLED;
+}
+
+/**
+ * Sets the location of the receiver, which must be a popup,
+ * to the point specified by the arguments which are relative
+ * to the display.
+ * <p>
+ * Note that this is different from most widgets where the
+ * location of the widget is relative to the parent.
+ * </p><p>
+ * Note that the platform window manager ultimately has control
+ * over the location of popup menus.
+ * </p>
+ *
+ * @param x the new x coordinate for the receiver
+ * @param y the new y coordinate for the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setLocation (int x, int y) {
+ checkWidget ();
+ if ((style & (SWT.BAR | SWT.DROP_DOWN)) != 0) return;
+ OS.ContextMenu_Placement (handle, OS.PlacementMode_AbsolutePoint);
+ OS.ContextMenu_HorizontalOffset (handle, x);
+ OS.ContextMenu_VerticalOffset (handle, y);
+}
+
+/**
+ * Sets the location of the receiver, which must be a popup,
+ * to the point specified by the argument which is relative
+ * to the display.
+ * <p>
+ * Note that this is different from most widgets where the
+ * location of the widget is relative to the parent.
+ * </p><p>
+ * Note that the platform window manager ultimately has control
+ * over the location of popup menus.
+ * </p>
+ *
+ * @param location the new location for the receiver
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.1
+ */
+public void setLocation (Point location) {
+ checkWidget ();
+ if (location == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+ setLocation (location.x, location.y);
+}
+
+/**
+ * Marks the receiver as visible if the argument is <code>true</code>,
+ * and marks it invisible otherwise.
+ * <p>
+ * If one of the receiver's ancestors is not visible or some
+ * other condition makes the receiver not visible, marking
+ * it visible may not actually cause it to be displayed.
+ * </p>
+ *
+ * @param visible the new visibility state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setVisible (boolean visible) {
+ checkWidget ();
+ if ((style & (SWT.BAR | SWT.DROP_DOWN)) != 0) return;
+ if (visible) {
+ display.addPopup (this);
+ } else {
+ display.removePopup (this);
+ _setVisible (false);
+ }
+}
+
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/MenuItem.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/MenuItem.java
new file mode 100644
index 0000000000..e697ce7969
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/MenuItem.java
@@ -0,0 +1,727 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.events.*;
+
+/**
+ * Instances of this class represent a selectable user interface object
+ * that issues notification when pressed and released.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>CHECK, CASCADE, PUSH, RADIO, SEPARATOR</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Arm, Help, Selection</dd>
+ * </dl>
+ * <p>
+ * Note: Only one of the styles CHECK, CASCADE, PUSH, RADIO and SEPARATOR
+ * may be specified.
+ * </p><p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ */
+
+public class MenuItem extends Item {
+ Menu parent, menu;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * (which must be a <code>Menu</code>) and a style value
+ * describing its behavior and appearance. The item is added
+ * to the end of the items maintained by its parent.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a menu control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#CHECK
+ * @see SWT#CASCADE
+ * @see SWT#PUSH
+ * @see SWT#RADIO
+ * @see SWT#SEPARATOR
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public MenuItem (Menu parent, int style) {
+ super (parent, checkStyle (style));
+ this.parent = parent;
+ parent.createItem (this, parent.getItemCount ());
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * (which must be a <code>Menu</code>), a style value
+ * describing its behavior and appearance, and the index
+ * at which to place it in the items maintained by its parent.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a menu control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ * @param index the zero-relative index to store the receiver in its parent
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#CHECK
+ * @see SWT#CASCADE
+ * @see SWT#PUSH
+ * @see SWT#RADIO
+ * @see SWT#SEPARATOR
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public MenuItem (Menu parent, int style, int index) {
+ super (parent, checkStyle (style));
+ this.parent = parent;
+ parent.createItem (this, index);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the arm events are generated for the control, by sending
+ * it one of the messages defined in the <code>ArmListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ArmListener
+ * @see #removeArmListener
+ */
+public void addArmListener (ArmListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Arm, typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the help events are generated for the control, by sending
+ * it one of the messages defined in the <code>HelpListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see HelpListener
+ * @see #removeHelpListener
+ */
+public void addHelpListener (HelpListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Help, typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the menu item is selected, by sending
+ * it one of the messages defined in the <code>SelectionListener</code>
+ * interface.
+ * <p>
+ * When <code>widgetSelected</code> is called, the stateMask field of the event object is valid.
+ * <code>widgetDefaultSelected</code> is not called.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #removeSelectionListener
+ * @see SelectionEvent
+ */
+public void addSelectionListener (SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener(listener);
+ addListener (SWT.Selection,typedListener);
+ addListener (SWT.DefaultSelection,typedListener);
+}
+
+protected void checkSubclass () {
+ if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
+}
+
+static int checkStyle (int style) {
+ return checkBits (style, SWT.PUSH, SWT.CHECK, SWT.RADIO, SWT.SEPARATOR, SWT.CASCADE, 0);
+}
+
+void createHandle () {
+ if ((style & SWT.SEPARATOR) != 0) {
+ handle = OS.gcnew_Separator ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ } else {
+ handle = OS.gcnew_MenuItem ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ if ((style & (SWT.CHECK | SWT.RADIO)) != 0) OS.MenuItem_IsCheckable (handle, true);
+ }
+}
+
+void deregister () {
+ display.removeWidget (handle);
+}
+
+void destroyWidget () {
+ parent.destroyItem (this);
+ super.destroyWidget ();
+}
+
+void fixMenus (Decorations newParent) {
+ if (menu != null) menu.fixMenus (newParent);
+}
+
+/**
+ * Returns the widget accelerator. An accelerator is the bit-wise
+ * OR of zero or more modifier masks and a key. Examples:
+ * <code>SWT.CONTROL | SWT.SHIFT | 'T', SWT.ALT | SWT.F2</code>.
+ * The default value is zero, indicating that the menu item does
+ * not have an accelerator.
+ *
+ * @return the accelerator or 0
+ *
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getAccelerator () {
+ checkWidget ();
+ //FIXME
+ return 0;
+}
+
+/**
+ * Returns a rectangle describing the receiver's size and location
+ * relative to its parent (or its display if its parent is null).
+ *
+ * @return the receiver's bounding rectangle
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+/*public*/ Rectangle getBounds () {
+ checkWidget ();
+ if (!OS.UIElement_IsVisible(handle)) return new Rectangle (0, 0, 0, 0);
+ int point = OS.gcnew_Point (0, 0);
+ if (point == 0) error(SWT.ERROR_NO_HANDLES);
+ int location = OS.UIElement_TranslatePoint (handle, point, parent.handle);
+ int x = (int) OS.Point_X (location);
+ int y = (int) OS.Point_Y (location);
+ OS.GCHandle_Free (point);
+ OS.GCHandle_Free (location);
+ int width = (int) OS.FrameworkElement_ActualWidth (handle);
+ int height = (int) OS.FrameworkElement_ActualHeight (handle);
+ return new Rectangle (x, y, width, height);
+}
+
+/**
+ * Returns <code>true</code> if the receiver is enabled, and
+ * <code>false</code> otherwise. A disabled menu item is typically
+ * not selectable from the user interface and draws with an
+ * inactive or "grayed" look.
+ *
+ * @return the receiver's enabled state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #isEnabled
+ */
+public boolean getEnabled () {
+ checkWidget ();
+ return OS.UIElement_IsEnabled (handle);
+
+}
+
+/**
+ * Returns the receiver's cascade menu if it has one or null
+ * if it does not. Only <code>CASCADE</code> menu items can have
+ * a pull down menu. The sequence of key strokes, button presses
+ * and/or button releases that are used to request a pull down
+ * menu is platform specific.
+ *
+ * @return the receiver's menu
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Menu getMenu () {
+ checkWidget ();
+ return menu;
+}
+
+String getNameText () {
+ if ((style & SWT.SEPARATOR) != 0) return "|";
+ return super.getNameText ();
+}
+
+/**
+ * Returns the receiver's parent, which must be a <code>Menu</code>.
+ *
+ * @return the receiver's parent
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Menu getParent () {
+ checkWidget ();
+ return parent;
+}
+
+/**
+ * Returns <code>true</code> if the receiver is selected,
+ * and false otherwise.
+ * <p>
+ * When the receiver is of type <code>CHECK</code> or <code>RADIO</code>,
+ * it is selected when it is checked.
+ *
+ * @return the selection state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getSelection () {
+ checkWidget ();
+ if ((style & (SWT.CHECK | SWT.RADIO)) == 0) return false;
+ return OS.MenuItem_IsChecked (handle);
+}
+
+void HandleClick (int sender, int e) {
+ if (!checkEvent (e)) return;
+ if ((style & SWT.RADIO) != 0 && (parent.style & SWT.NO_RADIO_GROUP) == 0) {
+ if (parent.selected != null) OS.MenuItem_IsChecked (parent.selected.handle, false);
+ parent.selected = this;
+ }
+ postEvent (SWT.Selection);
+}
+
+void HandleSubmenuOpened (int sender, int e) {
+ if (!checkEvent (e)) return;
+ if (menu != null) {
+ menu.sendEvent(SWT.Show);
+ }
+}
+
+void HandleSubmenuClosed (int sender, int e) {
+ if (!checkEvent (e)) return;
+ if (menu != null) {
+ menu.sendEvent(SWT.Hide);
+ }
+}
+
+void hookEvents() {
+ if ((style & SWT.SEPARATOR) != 0) return;
+ super.hookEvents();
+ if ((style & SWT.CASCADE) == 0) {
+ int handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleClick");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.MenuItem_Click (handle, handler);
+ OS.GCHandle_Free (handler);
+ } else {
+ int handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleSubmenuOpened");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.MenuItem_SubmenuOpened (handle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleSubmenuClosed");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.MenuItem_SubmenuClosed (handle, handler);
+ OS.GCHandle_Free (handler);
+ }
+}
+
+/**
+ * Returns <code>true</code> if the receiver is enabled and all
+ * of the receiver's ancestors are enabled, and <code>false</code>
+ * otherwise. A disabled menu item is typically not selectable from the
+ * user interface and draws with an inactive or "grayed" look.
+ *
+ * @return the receiver's enabled state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #getEnabled
+ */
+public boolean isEnabled () {
+ return getEnabled () && parent.isEnabled ();
+}
+
+void register() {
+ display.addWidget (handle, this);
+}
+
+void releaseChildren (boolean destroy) {
+ if (menu != null) {
+ menu.release (false);
+ menu = null;
+ }
+ super.releaseChildren (destroy);
+}
+
+void releaseHandle () {
+ super.releaseHandle ();
+ if (handle != 0) OS.GCHandle_Free (handle);
+ handle = 0;
+ parent = null;
+}
+
+void releaseMenu () {
+ setMenu (null);
+}
+
+void releaseParent () {
+ super.releaseParent ();
+ if (menu != null) menu.dispose ();
+ menu = null;
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the arm events are generated for the control.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ArmListener
+ * @see #addArmListener
+ */
+public void removeArmListener (ArmListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Arm, listener);
+}
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the help events are generated for the control.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see HelpListener
+ * @see #addHelpListener
+ */
+public void removeHelpListener (HelpListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Help, listener);
+}
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the control is selected.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #addSelectionListener
+ */
+public void removeSelectionListener (SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Selection, listener);
+ eventTable.unhook (SWT.DefaultSelection,listener);
+}
+
+/**
+ * Sets the widget accelerator. An accelerator is the bit-wise
+ * OR of zero or more modifier masks and a key. Examples:
+ * <code>SWT.MOD1 | SWT.MOD2 | 'T', SWT.MOD3 | SWT.F2</code>.
+ * <code>SWT.CONTROL | SWT.SHIFT | 'T', SWT.ALT | SWT.F2</code>.
+ * The default value is zero, indicating that the menu item does
+ * not have an accelerator.
+ *
+ * @param accelerator an integer that is the bit-wise OR of masks and a key
+ *
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setAccelerator (int accelerator) {
+ checkWidget ();
+ //FIXME
+}
+
+/**
+ * Enables the receiver if the argument is <code>true</code>,
+ * and disables it otherwise. A disabled menu item is typically
+ * not selectable from the user interface and draws with an
+ * inactive or "grayed" look.
+ *
+ * @param enabled the new enabled state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setEnabled (boolean enabled) {
+ checkWidget ();
+ OS.UIElement_IsEnabled (handle, enabled);
+}
+
+/**
+ * Sets the image the receiver will display to the argument.
+ * <p>
+ * Note: This operation is a hint and is not supported on
+ * platforms that do not have this concept (for example, Windows NT).
+ * </p>
+ *
+ * @param image the image to display
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setImage (Image image) {
+ checkWidget ();
+ if ((style & SWT.SEPARATOR) != 0) return;
+ if (image != null && image.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ this.image = image;
+ if (image != null) {
+ int img = OS.gcnew_Image ();
+ if (img == 0) error(SWT.ERROR_NO_HANDLES);
+ OS.Image_Source (img, image.handle);
+ OS.Image_Stretch (img, OS.Stretch_None);
+ OS.MenuItem_Icon (handle, img);
+ OS.GCHandle_Free (img);
+ } else {
+ OS.MenuItem_Icon (handle, 0);
+ }
+}
+
+/**
+ * Sets the receiver's pull down menu to the argument.
+ * Only <code>CASCADE</code> menu items can have a
+ * pull down menu. The sequence of key strokes, button presses
+ * and/or button releases that are used to request a pull down
+ * menu is platform specific.
+ * <p>
+ * Note: Disposing of a menu item that has a pull down menu
+ * will dispose of the menu. To avoid this behavior, set the
+ * menu to null before the menu item is disposed.
+ * </p>
+ *
+ * @param menu the new pull down menu
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_MENU_NOT_DROP_DOWN - if the menu is not a drop down menu</li>
+ * <li>ERROR_MENUITEM_NOT_CASCADE - if the menu item is not a <code>CASCADE</code></li>
+ * <li>ERROR_INVALID_ARGUMENT - if the menu has been disposed</li>
+ * <li>ERROR_INVALID_PARENT - if the menu is not in the same widget tree</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setMenu (Menu menu) {
+ checkWidget ();
+ if ((style & SWT.CASCADE) == 0) error (SWT.ERROR_MENUITEM_NOT_CASCADE);
+ if (menu != null) {
+ if (menu.cascade != null) {
+// FIXME: Change this error type, or fix the javadoc.
+ error (SWT.ERROR_INVALID_PARENT);
+ }
+ if (menu.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if ((menu.style & SWT.DROP_DOWN) == 0) {
+ error (SWT.ERROR_MENU_NOT_DROP_DOWN);
+ }
+ if (menu.parent != parent.parent) {
+ error (SWT.ERROR_INVALID_PARENT);
+ }
+ Menu oldMenu = this.menu;
+ if (oldMenu == menu) return;
+ if (oldMenu != null) oldMenu.cascade = null;
+ this.menu = menu;
+ OS.ItemsControl_ItemsSource (handle, menu.handle);
+ menu.cascade = this;
+ } else {
+ OS.ItemsControl_ItemsSource (handle, 0);
+ if (this.menu != null) this.menu.cascade = null;
+ }
+}
+
+/**
+ * Sets the selection state of the receiver.
+ * <p>
+ * When the receiver is of type <code>CHECK</code> or <code>RADIO</code>,
+ * it is selected when it is checked.
+ *
+ * @param selected the new selection state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSelection (boolean selected) {
+ checkWidget ();
+ if ((style & (SWT.CHECK | SWT.RADIO)) == 0) return;
+ OS.MenuItem_IsChecked (handle, selected);
+}
+/**
+ * Sets the receiver's text. The string may include
+ * the mnemonic character and accelerator text.
+ * <p>
+ * Mnemonics are indicated by an '&amp;' that causes the next
+ * character to be the mnemonic. When the user presses a
+ * key sequence that matches the mnemonic, a selection
+ * event occurs. On most platforms, the mnemonic appears
+ * underlined but may be emphasised in a platform specific
+ * manner. The mnemonic indicator character '&amp;' can be
+ * escaped by doubling it in the string, causing a single
+ * '&amp;' to be displayed.
+ * </p>
+ * <p>
+ * Accelerator text is indicated by the '\t' character.
+ * On platforms that support accelerator text, the text
+ * that follows the '\t' character is displayed to the user,
+ * typically indicating the key stroke that will cause
+ * the item to become selected. On most platforms, the
+ * accelerator text appears right aligned in the menu.
+ * Setting the accelerator text does not install the
+ * accelerator key sequence. The accelerator key sequence
+ * is installed using #setAccelerator.
+ * </p>
+ *
+ * @param string the new text
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #setAccelerator
+ */
+public void setText (String string) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if ((style & SWT.SEPARATOR) != 0) return;
+ if (text.equals (string)) return;
+ super.setText (string);
+ String accelString = null;
+ int index = string.indexOf ('\t');
+ if (index != -1) {
+ accelString = string.substring (index+1, string.length());
+ string = string.substring (0, index);
+ }
+ int ptr = createDotNetString (string, true);
+ OS.HeaderedItemsControl_Header (handle, ptr);
+ OS.GCHandle_Free (ptr);
+ if (accelString != null) {
+ ptr = createDotNetString (accelString, false);
+ OS.MenuItem_InputGestureText (handle, ptr);
+ OS.GCHandle_Free (ptr);
+ }
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/MessageBox.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/MessageBox.java
new file mode 100644
index 0000000000..c85f734214
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/MessageBox.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+
+/**
+ * Instances of this class are used to inform or warn the user.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>ICON_ERROR, ICON_INFORMATION, ICON_QUESTION, ICON_WARNING, ICON_WORKING</dd>
+ * <dd>OK, OK | CANCEL</dd>
+ * <dd>YES | NO, YES | NO | CANCEL</dd>
+ * <dd>RETRY | CANCEL</dd>
+ * <dd>ABORT | RETRY | IGNORE</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * <p>
+ * Note: Only one of the styles ICON_ERROR, ICON_INFORMATION, ICON_QUESTION,
+ * ICON_WARNING and ICON_WORKING may be specified.
+ * </p><p>
+ * IMPORTANT: This class is intended to be subclassed <em>only</em>
+ * within the SWT implementation.
+ * </p>
+ */
+public class MessageBox extends Dialog {
+ String message = "";
+
+/**
+ * Constructs a new instance of this class given only its parent.
+ *
+ * @param parent a shell which will be the parent of the new instance
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ */
+public MessageBox (Shell parent) {
+ this (parent, SWT.OK | SWT.ICON_INFORMATION | SWT.APPLICATION_MODAL);
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ *
+ * @param parent a shell which will be the parent of the new instance
+ * @param style the style of dialog to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ */
+public MessageBox (Shell parent, int style) {
+ super (parent, checkStyle (style));
+ checkSubclass ();
+}
+
+static int checkStyle (int style) {
+ if ((style & (SWT.PRIMARY_MODAL | SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) == 0) style |= SWT.APPLICATION_MODAL;
+ int mask = (SWT.YES | SWT.NO | SWT.OK | SWT.CANCEL | SWT.ABORT | SWT.RETRY | SWT.IGNORE);
+ int bits = style & mask;
+ if (bits == SWT.OK || bits == SWT.CANCEL || bits == (SWT.OK | SWT.CANCEL)) return style;
+ if (bits == SWT.YES || bits == SWT.NO || bits == (SWT.YES | SWT.NO) || bits == (SWT.YES | SWT.NO | SWT.CANCEL)) return style;
+ if (bits == (SWT.RETRY | SWT.CANCEL) || bits == (SWT.ABORT | SWT.RETRY | SWT.IGNORE)) return style;
+ style = (style & ~mask) | SWT.OK;
+ return style;
+}
+
+/**
+ * Returns the dialog's message, or an empty string if it does not have one.
+ * The message is a description of the purpose for which the dialog was opened.
+ * This message will be visible in the dialog while it is open.
+ *
+ * @return the message
+ */
+public String getMessage () {
+ return message;
+}
+
+/**
+ * Makes the dialog visible and brings it to the front
+ * of the display.
+ *
+ * @return the ID of the button that was selected to dismiss the
+ * message box (e.g. SWT.OK, SWT.CANCEL, etc...)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the dialog has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the dialog</li>
+ * </ul>
+ */
+public int open () {
+
+ /* Compute the MessageBox style */
+ int buttonBits = 0;
+ if ((style & SWT.OK) == SWT.OK) buttonBits = OS.MessageBoxButton_OK;
+ if ((style & (SWT.OK | SWT.CANCEL)) == (SWT.OK | SWT.CANCEL)) buttonBits = OS.MessageBoxButton_OKCancel;
+ if ((style & (SWT.YES | SWT.NO)) == (SWT.YES | SWT.NO)) buttonBits = OS.MessageBoxButton_YesNo;
+ if ((style & (SWT.YES | SWT.NO | SWT.CANCEL)) == (SWT.YES | SWT.NO | SWT.CANCEL)) buttonBits = OS.MessageBoxButton_YesNoCancel;
+ /*
+ * Feature in WPF. MessageBoxButton does not define Retry, Abort, or
+ * Ignore buttons. The work around is to use OK/Cancel instead and map
+ * OK to Retry for Retry/Cancel, and Abort for Abort/Retry/Cancel message
+ * boxes.
+ */
+ if ((style & (SWT.RETRY | SWT.CANCEL)) == (SWT.RETRY | SWT.CANCEL)) buttonBits = OS.MessageBoxButton_OKCancel;
+ if ((style & (SWT.ABORT | SWT.RETRY | SWT.IGNORE)) == (SWT.ABORT | SWT.RETRY | SWT.IGNORE)) buttonBits = OS.MessageBoxButton_OKCancel;
+ if (buttonBits == 0) buttonBits = OS.MessageBoxButton_OK;
+
+ int iconBits = 0;
+ if ((style & SWT.ICON_ERROR) != 0) iconBits = OS.MessageBoxImage_Error;
+ if ((style & SWT.ICON_INFORMATION) != 0) iconBits = OS.MessageBoxImage_Information;
+ if ((style & SWT.ICON_QUESTION) != 0) iconBits = OS.MessageBoxImage_Question;
+ if ((style & SWT.ICON_WARNING) != 0) iconBits = OS.MessageBoxImage_Warning;
+ if ((style & SWT.ICON_WORKING) != 0) iconBits = OS.MessageBoxImage_Information;
+
+ int length = message.length ();
+ char [] buffer = new char [length + 1];
+ message.getChars (0, length, buffer, 0);
+ int messagePtr = OS.gcnew_String(buffer);
+
+ length = title.length ();
+ buffer = new char [length + 1];
+ title.getChars (0, length, buffer, 0);
+ int titlePtr = OS.gcnew_String(buffer);
+
+ int code = OS.MessageBox_Show(messagePtr, titlePtr, buttonBits, iconBits, 0);
+
+ OS.GCHandle_Free (titlePtr);
+ OS.GCHandle_Free (messagePtr);
+
+ /* Compute and return the result */
+ switch (code) {
+ case OS.MessageBoxResult_No: return SWT.NO;
+ case OS.MessageBoxResult_OK:
+ if ((style & (SWT.RETRY | SWT.CANCEL)) == (SWT.RETRY | SWT.CANCEL)) return SWT.RETRY;
+ if ((style & (SWT.ABORT | SWT.RETRY | SWT.IGNORE)) == (SWT.ABORT | SWT.RETRY | SWT.IGNORE)) return SWT.ABORT;
+ return SWT.OK;
+ case OS.MessageBoxResult_Yes: return SWT.YES;
+ case OS.MessageBoxResult_Cancel:
+ default:
+ return SWT.CANCEL;
+ }
+}
+
+/**
+ * Sets the dialog's message, which is a description of
+ * the purpose for which it was opened. This message will be
+ * visible on the dialog while it is open.
+ *
+ * @param string the message
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ */
+public void setMessage (String string) {
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ message = string;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ProgressBar.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ProgressBar.java
new file mode 100644
index 0000000000..9cde148df5
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ProgressBar.java
@@ -0,0 +1,219 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.wpf.*;
+
+/**
+ * Instances of the receiver represent is an unselectable
+ * user interface object that is used to display progress,
+ * typically in the form of a bar.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>SMOOTH, HORIZONTAL, VERTICAL, INDETERMINATE</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * <p>
+ * Note: Only one of the styles HORIZONTAL and VERTICAL may be specified.
+ * </p><p>
+ * IMPORTANT: This class is intended to be subclassed <em>only</em>
+ * within the SWT implementation.
+ * </p>
+ */
+public class ProgressBar extends Control {
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#SMOOTH
+ * @see SWT#HORIZONTAL
+ * @see SWT#VERTICAL
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public ProgressBar (Composite parent, int style) {
+ super (parent, checkStyle (style));
+}
+
+static int checkStyle (int style) {
+ style |= SWT.NO_FOCUS;
+ return checkBits (style, SWT.HORIZONTAL, SWT.VERTICAL, 0, 0, 0, 0);
+}
+
+public Point computeSize (int wHint, int hHint, boolean changed) {
+ checkWidget ();
+ int border = getBorderWidth ();
+ int width = border * 2, height = border * 2;
+ if ((style & SWT.HORIZONTAL) != 0) {
+ width += OS.SystemParameters_HorizontalScrollBarButtonWidth () * 10;
+ height += OS.SystemParameters_HorizontalScrollBarHeight ();
+ } else {
+ width += OS.SystemParameters_VerticalScrollBarWidth ();
+ height += OS.SystemParameters_VerticalScrollBarButtonHeight () * 10;
+ }
+ if (wHint != SWT.DEFAULT) width = wHint + (border * 2);
+ if (hHint != SWT.DEFAULT) height = hHint + (border * 2);
+ return new Point (width, height);
+}
+
+void createHandle () {
+ handle = OS.gcnew_ProgressBar();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ if ((style & SWT.VERTICAL) != 0) OS.ProgressBar_Orientation(handle, OS.Orientation_Vertical);
+ if ((style & SWT.INDETERMINATE) != 0) {
+ OS.ProgressBar_IsIndeterminate (handle, true) ;
+// int duration = OS.gcnew_Duration();
+// int doubleAnimation = OS.gcnew_DoubleAnimation(100.0, duration);
+// OS.GCHandle_Free(duration);
+// OS.DoubleAnimation_RepeatBehavior(doubleAnimation, OS.RepeatBehavior_Forever);
+// FIXME: How to get the Marquee style like Winforms????
+// OS.DoubleAnimation_AutoReverse(doubleAnimation, true);
+// OS.UIElement_BeginAnimation(handle, doubleAnimation);
+// OS.GCHandle_Free(doubleAnimation);
+ }
+}
+
+/**
+ * Returns the maximum value which the receiver will allow.
+ *
+ * @return the maximum
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getMaximum () {
+ checkWidget ();
+ return (int) OS.RangeBase_Maximum (handle);
+}
+
+/**
+ * Returns the minimum value which the receiver will allow.
+ *
+ * @return the minimum
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li >ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getMinimum () {
+ checkWidget ();
+ return (int) OS.RangeBase_Minimum (handle);
+}
+
+/**
+ * Returns the single 'selection' that is the receiver's position.
+ *
+ * @return the selection
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getSelection () {
+ checkWidget ();
+ return (int) OS.RangeBase_Value(handle);
+}
+
+/**
+ * Sets the maximum value that the receiver will allow. This new
+ * value will be ignored if it is not greater than the receiver's current
+ * minimum value. If the new maximum is applied then the receiver's
+ * selection value will be adjusted if necessary to fall within its new range.
+ *
+ * @param value the new maximum, which must be greater than the current minimum
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setMaximum (int value) {
+ checkWidget ();
+ int minimum = (int) OS.RangeBase_Minimum (handle);
+ if (0 <= minimum && minimum < value) {
+ OS.RangeBase_Maximum (handle, value);
+ }
+
+ //FIXME - If the new maximum is applied then the receiver's
+ // selection value will be adjusted if necessary to fall within its new range.
+}
+
+/**
+ * Sets the minimum value that the receiver will allow. This new
+ * value will be ignored if it is negative or is not less than the receiver's
+ * current maximum value. If the new minimum is applied then the receiver's
+ * selection value will be adjusted if necessary to fall within its new range.
+ *
+ * @param value the new minimum, which must be nonnegative and less than the current maximum
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setMinimum (int value) {
+ checkWidget ();
+ int maximum = (int) OS.RangeBase_Maximum (handle);
+ if (0 <= maximum && value < maximum) {
+ OS.RangeBase_Minimum (handle, value);
+ }
+
+ //FIXME - If the new minimum is applied then the receiver's
+ //selection value will be adjusted if necessary to fall within its new range
+}
+
+/**
+ * Sets the single 'selection' that is the receiver's
+ * position to the argument which must be greater than or equal
+ * to zero.
+ *
+ * @param value the new selection (must be zero or greater)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSelection (int value) {
+ checkWidget ();
+ if (value < 0) return;
+ OS.RangeBase_Value(handle, value);
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Sash.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Sash.java
new file mode 100644
index 0000000000..7f28342da3
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Sash.java
@@ -0,0 +1,239 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.events.*;
+
+/**
+ * Instances of the receiver represent a selectable user interface object
+ * that allows the user to drag a rubber banded outline of the sash within
+ * the parent control.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>HORIZONTAL, VERTICAL, SMOOTH</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Selection</dd>
+ * </dl>
+ * <p>
+ * Note: Only one of the styles HORIZONTAL and VERTICAL may be specified.
+ * </p><p>
+ * IMPORTANT: This class is intended to be subclassed <em>only</em>
+ * within the SWT implementation.
+ * </p>
+ */
+public class Sash extends Control {
+ boolean dragging;
+ int startX, startY, lastX, lastY;
+ final static int INCREMENT = 1;
+ final static int PAGE_INCREMENT = 9;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#HORIZONTAL
+ * @see SWT#VERTICAL
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Sash (Composite parent, int style) {
+ super (parent, checkStyle (style));
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the control is selected, by sending
+ * it one of the messages defined in the <code>SelectionListener</code>
+ * interface.
+ * <p>
+ * When <code>widgetSelected</code> is called, the x, y, width, and height fields of the event object are valid.
+ * If the receiver is being dragged, the event object detail field contains the value <code>SWT.DRAG</code>.
+ * <code>widgetDefaultSelected</code> is not called.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #removeSelectionListener
+ * @see SelectionEvent
+ */
+public void addSelectionListener (SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Selection,typedListener);
+ addListener (SWT.DefaultSelection,typedListener);
+}
+
+static int checkStyle (int style) {
+ return checkBits (style, SWT.HORIZONTAL, SWT.VERTICAL, 0, 0, 0, 0);
+}
+
+void createHandle () {
+ state |= THEME_BACKGROUND;
+ handle = OS.gcnew_Canvas ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ int newCursor = (style & SWT.VERTICAL)!= 0 ? OS.Cursors_SizeWE () : OS.Cursors_SizeNS ();
+ OS.FrameworkElement_Cursor (handle, newCursor);
+ OS.GCHandle_Free (newCursor);
+}
+
+int defaultBackground () {
+ return OS.SystemColors_ControlColor;
+}
+
+void HandleKeyDown (int sender, int e) {
+ super.HandleKeyDown (sender, e);
+ //TODO
+}
+
+void HandleKeyUp (int sender, int e) {
+ super.HandleKeyUp (sender, e);
+ //TODO
+}
+
+void HandlePreviewMouseDown (int sender, int e) {
+ super.HandlePreviewMouseDown (sender, e);
+ int eventPos = OS.MouseEventArgs_GetPosition (e, handle);
+ startX = (int) OS.Point_X (eventPos);
+ startY = (int) OS.Point_Y (eventPos);
+ OS.GCHandle_Free (eventPos);
+ Point location = parent.getLocation (this);
+ int x = location.x;
+ int y = location.y;
+ int width = (int) OS.FrameworkElement_ActualWidth (handle);
+ int height = (int) OS.FrameworkElement_ActualHeight (handle);
+ lastX = x;
+ lastY = y;
+ Event event = new Event ();
+ event.x = lastX;
+ event.y = lastY;
+ event.width = width;
+ event.height = height;
+ sendEvent (SWT.Selection, event);
+ if (event.doit) {
+ dragging = true;
+ lastX = event.x;
+ lastY = event.y;
+ OS.UIElement_CaptureMouse (handle);
+ }
+}
+
+void HandlePreviewMouseUp (int sender, int e) {
+ super.HandlePreviewMouseUp (sender, e);
+ if (!dragging) return;
+ OS.UIElement_ReleaseMouseCapture (handle);
+ dragging = false;
+ int width = (int) OS.FrameworkElement_ActualWidth (handle);
+ int height = (int) OS.FrameworkElement_ActualHeight (handle);
+ Event event = new Event ();
+ event.x = lastX;
+ event.y = lastY;
+ event.width = width;
+ event.height = height;
+ sendEvent (SWT.Selection, event);
+}
+
+void HandlePreviewMouseMove (int sender, int e) {
+ super.HandlePreviewMouseMove (sender, e);
+ if (!dragging) return;
+ int eventPos = OS.MouseEventArgs_GetPosition (e, handle);
+ int eventX = (int) OS.Point_X (eventPos);
+ int eventY = (int) OS.Point_Y (eventPos);
+ OS.GCHandle_Free (eventPos);
+ Point location = parent.getLocation (this);
+ int x = location.x;
+ int y = location.y;
+ int width = (int) OS.FrameworkElement_ActualWidth (handle);
+ int height = (int) OS.FrameworkElement_ActualHeight (handle);
+ int parentWidth = (int) OS.FrameworkElement_ActualWidth (parent.handle);
+ int parentHeight = (int) OS.FrameworkElement_ActualHeight (parent.handle);
+ int newX = lastX, newY = lastY;
+ if ((style & SWT.VERTICAL) != 0) {
+ newX = Math.min (Math.max (0, eventX + x - startX), parentWidth - width);
+ } else {
+ newY = Math.min (Math.max (0, eventY + y - startY), parentHeight - height);
+ }
+ if (newX == lastX && newY == lastY) return;
+ Event event = new Event ();
+ event.x = newX;
+ event.y = newY;
+ event.width = width;
+ event.height = height;
+ sendEvent (SWT.Selection, event);
+ if (isDisposed ()) return;
+ if (event.doit) {
+ lastX = event.x;
+ lastY = event.y;
+ }
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the control is selected.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #addSelectionListener
+ */
+public void removeSelectionListener(SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Selection, listener);
+ eventTable.unhook (SWT.DefaultSelection,listener);
+}
+
+int traversalCode (int key, int event) {
+ return 0;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Scale.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Scale.java
new file mode 100644
index 0000000000..089e4d11bb
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Scale.java
@@ -0,0 +1,356 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.events.*;
+
+/**
+ * Instances of the receiver represent a selectable user
+ * interface object that present a range of continuous
+ * numeric values.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>HORIZONTAL, VERTICAL</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Selection</dd>
+ * </dl>
+ * <p>
+ * Note: Only one of the styles HORIZONTAL and VERTICAL may be specified.
+ * </p><p>
+ * <p>
+ * IMPORTANT: This class is intended to be subclassed <em>only</em>
+ * within the SWT implementation.
+ * </p>
+ */
+
+public class Scale extends Control {
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#HORIZONTAL
+ * @see SWT#VERTICAL
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Scale (Composite parent, int style) {
+ super (parent, checkStyle (style));
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the receiver's value changes, by sending
+ * it one of the messages defined in the <code>SelectionListener</code>
+ * interface.
+ * <p>
+ * <code>widgetSelected</code> is called when the control's value changes.
+ * <code>widgetDefaultSelected</code> is not called.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #removeSelectionListener
+ */
+public void addSelectionListener(SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Selection,typedListener);
+ addListener (SWT.DefaultSelection,typedListener);
+}
+
+static int checkStyle (int style) {
+ return checkBits (style, SWT.HORIZONTAL, SWT.VERTICAL, 0, 0, 0, 0);
+}
+
+public Point computeSize (int wHint, int hHint, boolean changed) {
+ checkWidget ();
+ int border = getBorderWidth ();
+ int width = border * 2, height = border * 2;
+ if ((style & SWT.HORIZONTAL) != 0) {
+ width += OS.SystemParameters_HorizontalScrollBarButtonWidth () * 10;
+ height += OS.SystemParameters_HorizontalScrollBarHeight () * 2;
+ } else {
+ width += OS.SystemParameters_VerticalScrollBarWidth () * 2;
+ height += OS.SystemParameters_VerticalScrollBarButtonHeight () * 10;
+ }
+ if (wHint != SWT.DEFAULT) width = wHint + (border * 2);
+ if (hHint != SWT.DEFAULT) height = hHint + (border * 2);
+ return new Point (width, height);
+}
+
+void createHandle () {
+ state |= THEME_BACKGROUND;
+ handle = OS.gcnew_Slider ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ if ((style & SWT.VERTICAL) != 0) OS.Slider_Orientation (handle, OS.Orientation_Vertical);
+ OS.RangeBase_Maximum (handle, 100);
+ OS.RangeBase_LargeChange (handle, 10);
+ OS.RangeBase_SmallChange (handle, 1);
+ OS.Slider_TickFrequency (handle, 10);
+ OS.Slider_TickPlacement (handle, OS.TickPlacement_Both);
+}
+
+int defaultBackground () {
+ return OS.SystemColors_ControlColor;
+}
+
+/**
+ * Returns the amount that the receiver's value will be
+ * modified by when the up/down (or right/left) arrows
+ * are pressed.
+ *
+ * @return the increment
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getIncrement () {
+ checkWidget ();
+ return (int) OS.RangeBase_SmallChange (handle);
+}
+
+/**
+ * Returns the maximum value which the receiver will allow.
+ *
+ * @return the maximum
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getMaximum () {
+ checkWidget ();
+ return (int) OS.RangeBase_Maximum (handle);
+}
+
+/**
+ * Returns the minimum value which the receiver will allow.
+ *
+ * @return the minimum
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getMinimum () {
+ checkWidget ();
+ return (int) OS.RangeBase_Minimum (handle);
+}
+
+/**
+ * Returns the amount that the receiver's value will be
+ * modified by when the page increment/decrement areas
+ * are selected.
+ *
+ * @return the page increment
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getPageIncrement () {
+ checkWidget ();
+ return (int) OS.RangeBase_LargeChange(handle);
+}
+
+/**
+ * Returns the 'selection', which is the receiver's position.
+ *
+ * @return the selection
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getSelection () {
+ checkWidget ();
+ return (int) OS.RangeBase_Value (handle);
+}
+
+void HandleValueChanged (int sender, int e) {
+ if (!checkEvent (e)) return;
+ postEvent (SWT.Selection);
+}
+
+void hookEvents() {
+ super.hookEvents ();
+ int handler = OS.gcnew_RoutedPropertyChangedEventHandler (jniRef, "HandleValueChanged");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.RangeBase_ValueChanged (handle, handler);
+ OS.GCHandle_Free (handler);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the receiver's value changes.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #addSelectionListener
+ */
+public void removeSelectionListener(SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Selection, listener);
+ eventTable.unhook (SWT.DefaultSelection,listener);
+}
+
+/**
+ * Sets the amount that the receiver's value will be
+ * modified by when the up/down (or right/left) arrows
+ * are pressed to the argument, which must be at least
+ * one.
+ *
+ * @param increment the new increment (must be greater than zero)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setIncrement (int increment) {
+ checkWidget ();
+ if (increment < 1) return;
+ int minimum = (int) OS.RangeBase_Minimum(handle);
+ int maximum = (int) OS.RangeBase_Maximum(handle);
+ if (increment > maximum - minimum) return;
+ OS.RangeBase_SmallChange(handle, increment);
+}
+
+/**
+ * Sets the maximum value that the receiver will allow. This new
+ * value will be ignored if it is not greater than the receiver's current
+ * minimum value. If the new maximum is applied then the receiver's
+ * selection value will be adjusted if necessary to fall within its new range.
+ *
+ * @param value the new maximum, which must be greater than the current minimum
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setMaximum (int value) {
+ checkWidget ();
+ int minimum = (int) OS.RangeBase_Minimum (handle);
+ if (0 <= minimum && minimum < value) OS.RangeBase_Maximum (handle, value);
+}
+
+/**
+ * Sets the minimum value that the receiver will allow. This new
+ * value will be ignored if it is negative or is not less than the receiver's
+ * current maximum value. If the new minimum is applied then the receiver's
+ * selection value will be adjusted if necessary to fall within its new range.
+ *
+ * @param value the new minimum, which must be nonnegative and less than the current maximum
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setMinimum (int value) {
+ checkWidget ();
+ int maximum = (int) OS.RangeBase_Maximum (handle);
+ if (0 <= value && value < maximum) OS.RangeBase_Minimum (handle, value);
+}
+
+/**
+ * Sets the amount that the receiver's value will be
+ * modified by when the page increment/decrement areas
+ * are selected to the argument, which must be at least
+ * one.
+ *
+ * @param pageIncrement the page increment (must be greater than zero)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setPageIncrement (int pageIncrement) {
+ checkWidget ();
+ if (pageIncrement < 1) return;
+ int minimum = (int) OS.RangeBase_Minimum(handle);
+ int maximum = (int) OS.RangeBase_Maximum(handle);
+ if (pageIncrement > maximum - minimum) return;
+ OS.RangeBase_LargeChange(handle, pageIncrement);
+ OS.Slider_TickFrequency(handle, pageIncrement);
+}
+
+/**
+ * Sets the 'selection', which is the receiver's value,
+ * to the argument which must be greater than or equal to zero.
+ *
+ * @param value the new selection (must be zero or greater)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSelection (int value) {
+ checkWidget ();
+ OS.RangeBase_Value (handle, value);
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ScrollBar.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ScrollBar.java
new file mode 100644
index 0000000000..f39bc6de2d
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ScrollBar.java
@@ -0,0 +1,687 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.events.*;
+
+/**
+ * Instances of this class are selectable user interface
+ * objects that represent a range of positive, numeric values.
+ * <p>
+ * At any given moment, a given scroll bar will have a
+ * single 'selection' that is considered to be its
+ * value, which is constrained to be within the range of
+ * values the scroll bar represents (that is, between its
+ * <em>minimum</em> and <em>maximum</em> values).
+ * </p><p>
+ * Typically, scroll bars will be made up of five areas:
+ * <ol>
+ * <li>an arrow button for decrementing the value</li>
+ * <li>a page decrement area for decrementing the value by a larger amount</li>
+ * <li>a <em>thumb</em> for modifying the value by mouse dragging</li>
+ * <li>a page increment area for incrementing the value by a larger amount</li>
+ * <li>an arrow button for incrementing the value</li>
+ * </ol>
+ * Based on their style, scroll bars are either <code>HORIZONTAL</code>
+ * (which have a left facing button for decrementing the value and a
+ * right facing button for incrementing it) or <code>VERTICAL</code>
+ * (which have an upward facing button for decrementing the value
+ * and a downward facing buttons for incrementing it).
+ * </p><p>
+ * On some platforms, the size of the scroll bar's thumb can be
+ * varied relative to the magnitude of the range of values it
+ * represents (that is, relative to the difference between its
+ * maximum and minimum values). Typically, this is used to
+ * indicate some proportional value such as the ratio of the
+ * visible area of a document to the total amount of space that
+ * it would take to display it. SWT supports setting the thumb
+ * size even if the underlying platform does not, but in this
+ * case the appearance of the scroll bar will not change.
+ * </p><p>
+ * Scroll bars are created by specifying either <code>H_SCROLL</code>,
+ * <code>V_SCROLL</code> or both when creating a <code>Scrollable</code>.
+ * They are accessed from the <code>Scrollable</code> using
+ * <code>getHorizontalBar</code> and <code>getVerticalBar</code>.
+ * </p><p>
+ * Note: Scroll bars are not Controls. On some platforms, scroll bars
+ * that appear as part of some standard controls such as a text or list
+ * have no operating system resources and are not children of the control.
+ * For this reason, scroll bars are treated specially. To create a control
+ * that looks like a scroll bar but has operating system resources, use
+ * <code>Slider</code>.
+ * </p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>HORIZONTAL, VERTICAL</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Selection</dd>
+ * </dl>
+ * <p>
+ * Note: Only one of the styles HORIZONTAL and VERTICAL may be specified.
+ * </p><p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ *
+ * @see Slider
+ * @see Scrollable
+ * @see Scrollable#getHorizontalBar
+ * @see Scrollable#getVerticalBar
+ */
+
+public class ScrollBar extends Widget {
+ Scrollable parent;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#HORIZONTAL
+ * @see SWT#VERTICAL
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+ScrollBar (Scrollable parent, int style) {
+ super (parent, checkStyle (style));
+ this.parent = parent;
+ createWidget ();
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the receiver's value changes, by sending
+ * it one of the messages defined in the <code>SelectionListener</code>
+ * interface.
+ * <p>
+ * When <code>widgetSelected</code> is called, the event object detail field contains one of the following values:
+ * <code>SWT.NONE</code> - for the end of a drag.
+ * <code>SWT.DRAG</code>.
+ * <code>SWT.HOME</code>.
+ * <code>SWT.END</code>.
+ * <code>SWT.ARROW_DOWN</code>.
+ * <code>SWT.ARROW_UP</code>.
+ * <code>SWT.PAGE_DOWN</code>.
+ * <code>SWT.PAGE_UP</code>.
+ * <code>widgetDefaultSelected</code> is not called.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #removeSelectionListener
+ * @see SelectionEvent
+ */
+public void addSelectionListener (SelectionListener listener) {
+ checkWidget();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener(listener);
+ addListener (SWT.Selection,typedListener);
+ addListener (SWT.DefaultSelection,typedListener);
+}
+
+static int checkStyle (int style) {
+ return checkBits (style, SWT.HORIZONTAL, SWT.VERTICAL, 0, 0, 0, 0);
+}
+
+void createHandle () {
+ handle = parent.getScrollBarHandle (style);
+}
+
+void deregister () {
+ display.removeWidget (handle);
+}
+
+void destroyWidget () {
+ int topHandle = topHandle ();
+ int parentHandle = parent.handle;
+ int children = OS.Panel_Children (parentHandle);
+ OS.UIElementCollection_Remove (children, topHandle);
+ releaseHandle ();
+}
+
+/**
+ * Returns <code>true</code> if the receiver is enabled, and
+ * <code>false</code> otherwise. A disabled control is typically
+ * not selectable from the user interface and draws with an
+ * inactive or "grayed" look.
+ *
+ * @return the receiver's enabled state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #isEnabled
+ */
+public boolean getEnabled () {
+ checkWidget();
+ return OS.UIElement_IsEnabled (topHandle ());
+}
+
+/**
+ * Returns the amount that the receiver's value will be
+ * modified by when the up/down (or right/left) arrows
+ * are pressed.
+ *
+ * @return the increment
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getIncrement () {
+ checkWidget();
+ return (int) OS.RangeBase_SmallChange (handle);
+}
+
+/**
+ * Returns the maximum value which the receiver will allow.
+ *
+ * @return the maximum
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getMaximum () {
+ checkWidget();
+ int maximum = (int) OS.RangeBase_Maximum (handle);
+ int viewSize = (int) OS.ScrollBar_ViewportSize (handle);
+ return maximum + viewSize;
+}
+
+/**
+ * Returns the minimum value which the receiver will allow.
+ *
+ * @return the minimum
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getMinimum () {
+ checkWidget();
+ return (int) OS.RangeBase_Minimum (handle);
+}
+
+/**
+ * Returns the amount that the receiver's value will be
+ * modified by when the page increment/decrement areas
+ * are selected.
+ *
+ * @return the page increment
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getPageIncrement () {
+ checkWidget();
+ return (int) OS.RangeBase_LargeChange (handle);
+}
+
+/**
+ * Returns the receiver's parent, which must be a Scrollable.
+ *
+ * @return the receiver's parent
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Scrollable getParent () {
+ checkWidget();
+ return parent;
+}
+
+/**
+ * Returns the single 'selection' that is the receiver's value.
+ *
+ * @return the selection
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getSelection () {
+ checkWidget();
+ return (int) OS.RangeBase_Value (handle);
+}
+
+/**
+ * Returns a point describing the receiver's size. The
+ * x coordinate of the result is the width of the receiver.
+ * The y coordinate of the result is the height of the
+ * receiver.
+ *
+ * @return the receiver's size
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Point getSize () {
+ checkWidget();
+ int topHandle = topHandle ();
+ int width = (int) OS.FrameworkElement_ActualWidth (topHandle);
+ int height = (int) OS.FrameworkElement_ActualHeight (topHandle);
+ return new Point (width, height);
+}
+
+/**
+ * Returns the size of the receiver's thumb relative to the
+ * difference between its maximum and minimum values.
+ *
+ * @return the thumb value
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ScrollBar
+ */
+public int getThumb () {
+ checkWidget();
+ return (int) OS.ScrollBar_ViewportSize (handle);
+}
+
+/**
+ * Returns <code>true</code> if the receiver is visible, and
+ * <code>false</code> otherwise.
+ * <p>
+ * If one of the receiver's ancestors is not visible or some
+ * other condition makes the receiver not visible, this method
+ * may still indicate that it is considered visible even though
+ * it may not actually be showing.
+ * </p>
+ *
+ * @return the receiver's visibility state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getVisible () {
+ checkWidget();
+ return OS.UIElement_Visibility (handle) == OS.Visibility_Visible;
+}
+
+void HandleScroll (int sender, int e) {
+ if (!checkEvent (e)) return;
+ Event event = new Event ();
+ switch (OS.ScrollEventArgs_ScrollEventType (e)) {
+ case OS.ScrollEventType_EndScroll: return;
+ case OS.ScrollEventType_ThumbPosition: event.detail = SWT.NONE; break;
+ case OS.ScrollEventType_ThumbTrack: event.detail = SWT.DRAG; break;
+ case OS.ScrollEventType_First: event.detail = SWT.HOME; break;
+ case OS.ScrollEventType_Last: event.detail = SWT.END; break;
+ case OS.ScrollEventType_LargeIncrement: event.detail = SWT.PAGE_DOWN; break;
+ case OS.ScrollEventType_LargeDecrement: event.detail = SWT.PAGE_UP; break;
+ case OS.ScrollEventType_SmallIncrement: event.detail = SWT.ARROW_DOWN; break;
+ case OS.ScrollEventType_SmallDecrement: event.detail = SWT.ARROW_UP; break;
+ }
+ postEvent (SWT.Selection, event);
+}
+
+void hookEvents () {
+ super.hookEvents ();
+ int handler = OS.gcnew_ScrollEventHandler (jniRef, "HandleScroll");
+ OS.ScrollBar_Scroll (handle, handler);
+ OS.GCHandle_Free (handler);
+}
+
+/**
+ * Returns <code>true</code> if the receiver is enabled and all
+ * of the receiver's ancestors are enabled, and <code>false</code>
+ * otherwise. A disabled control is typically not selectable from the
+ * user interface and draws with an inactive or "grayed" look.
+ *
+ * @return the receiver's enabled state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #getEnabled
+ */
+public boolean isEnabled () {
+ checkWidget();
+ return getEnabled () && parent.isEnabled ();
+}
+
+/**
+ * Returns <code>true</code> if the receiver is visible and all
+ * of the receiver's ancestors are visible and <code>false</code>
+ * otherwise.
+ *
+ * @return the receiver's visibility state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #getVisible
+ */
+public boolean isVisible () {
+ checkWidget();
+ return getVisible () && parent.isVisible ();
+}
+
+void register () {
+ display.addWidget (handle, this);
+}
+
+void releaseHandle () {
+ super.releaseHandle ();
+ if (handle != 0) OS.GCHandle_Free (handle);
+ handle = 0;
+ parent = null;
+}
+
+void releaseParent () {
+ super.releaseParent ();
+ if (parent.horizontalBar == this) parent.horizontalBar = null;
+ if (parent.verticalBar == this) parent.verticalBar = null;
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the receiver's value changes.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #addSelectionListener
+ */
+public void removeSelectionListener (SelectionListener listener) {
+ checkWidget();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Selection, listener);
+ eventTable.unhook (SWT.DefaultSelection,listener);
+}
+
+/**
+ * Enables the receiver if the argument is <code>true</code>,
+ * and disables it otherwise. A disabled control is typically
+ * not selectable from the user interface and draws with an
+ * inactive or "grayed" look.
+ *
+ * @param enabled the new enabled state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setEnabled (boolean enabled) {
+ checkWidget();
+ OS.UIElement_IsEnabled (topHandle (), enabled);
+}
+
+/**
+ * Sets the amount that the receiver's value will be
+ * modified by when the up/down (or right/left) arrows
+ * are pressed to the argument, which must be at least
+ * one.
+ *
+ * @param value the new increment (must be greater than zero)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setIncrement (int value) {
+ checkWidget();
+ if (value < 1) return;
+ OS.RangeBase_SmallChange (handle, value);
+}
+
+/**
+ * Sets the maximum. If this value is negative or less than or
+ * equal to the minimum, the value is ignored. If necessary, first
+ * the thumb and then the selection are adjusted to fit within the
+ * new range.
+ *
+ * @param value the new maximum
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setMaximum (int value) {
+ checkWidget();
+ if (value < 0) return;
+ int minimum = (int) OS.RangeBase_Minimum (handle);
+ if (value <= minimum) return;
+ int viewSize = (int) OS.ScrollBar_ViewportSize (handle);
+ if (value - minimum < viewSize) {
+ viewSize = value - minimum;
+ OS.ScrollBar_ViewportSize (handle, viewSize);
+ }
+ OS.RangeBase_Maximum (handle, value - viewSize);
+}
+
+/**
+ * Sets the minimum value. If this value is negative or greater
+ * than or equal to the maximum, the value is ignored. If necessary,
+ * first the thumb and then the selection are adjusted to fit within
+ * the new range.
+ *
+ * @param value the new minimum
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setMinimum (int value) {
+ checkWidget();
+ if (value < 0) return;
+ int viewSize = (int) OS.ScrollBar_ViewportSize (handle);
+ int maximum = (int) OS.RangeBase_Maximum (handle) + viewSize;
+ if (value >= maximum) return;
+ if (maximum - value < viewSize) {
+ viewSize = maximum - value;
+ OS.RangeBase_Maximum (handle, maximum - viewSize);
+ OS.ScrollBar_ViewportSize (handle, viewSize);
+ }
+ OS.RangeBase_Minimum (handle, value);
+}
+
+/**
+ * Sets the amount that the receiver's value will be
+ * modified by when the page increment/decrement areas
+ * are selected to the argument, which must be at least
+ * one.
+ *
+ * @param value the page increment (must be greater than zero)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setPageIncrement (int value) {
+ checkWidget();
+ if (value < 1) return;
+ OS.RangeBase_LargeChange (handle, value);
+}
+
+/**
+ * Sets the single <em>selection</em> that is the receiver's
+ * value to the argument which must be greater than or equal
+ * to zero.
+ *
+ * @param selection the new selection (must be zero or greater)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSelection (int selection) {
+ checkWidget();
+ OS.RangeBase_Value (handle, selection);
+}
+
+/**
+ * Sets the size of the receiver's thumb relative to the
+ * difference between its maximum and minimum values. This new
+ * value will be ignored if it is less than one, and will be
+ * clamped if it exceeds the receiver's current range.
+ *
+ * @param value the new thumb value, which must be at least one and not
+ * larger than the size of the current range
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setThumb (int value) {
+ checkWidget();
+ if (value < 1) return;
+ int minimum = (int) OS.RangeBase_Minimum (handle);
+ int viewSize = (int) OS.ScrollBar_ViewportSize (handle);
+ int maximum = (int) OS.RangeBase_Maximum (handle) + viewSize;
+ value = Math.min (value, maximum - minimum);
+ OS.RangeBase_Maximum (handle, maximum - value);
+ OS.ScrollBar_ViewportSize (handle, value);
+}
+
+/**
+ * Sets the receiver's selection, minimum value, maximum
+ * value, thumb, increment and page increment all at once.
+ * <p>
+ * Note: This is similar to setting the values individually
+ * using the appropriate methods, but may be implemented in a
+ * more efficient fashion on some platforms.
+ * </p>
+ *
+ * @param selection the new selection value
+ * @param minimum the new minimum value
+ * @param maximum the new maximum value
+ * @param thumb the new thumb value
+ * @param increment the new increment value
+ * @param pageIncrement the new pageIncrement value
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setValues (int selection, int minimum, int maximum, int thumb, int increment, int pageIncrement) {
+ checkWidget();
+ if (minimum < 0) return;
+ if (maximum < 0) return;
+ if (thumb < 1) return;
+ if (increment < 1) return;
+ if (pageIncrement < 1) return;
+ thumb = Math.min (thumb, maximum - minimum);
+ OS.RangeBase_Minimum (handle, minimum);
+ OS.RangeBase_Maximum (handle, maximum - thumb);
+ OS.ScrollBar_ViewportSize (handle, thumb);
+ OS.RangeBase_Value (handle, selection);
+ OS.RangeBase_LargeChange (handle, pageIncrement);
+ OS.RangeBase_SmallChange (handle, increment);
+}
+
+/**
+ * Marks the receiver as visible if the argument is <code>true</code>,
+ * and marks it invisible otherwise.
+ * <p>
+ * If one of the receiver's ancestors is not visible or some
+ * other condition makes the receiver not visible, marking
+ * it visible may not actually cause it to be displayed.
+ * </p>
+ *
+ * @param visible the new visibility state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setVisible (boolean visible) {
+ checkWidget ();
+ int topHandle = topHandle ();
+ if ((OS.UIElement_Visibility (topHandle) == OS.Visibility_Visible) == visible) return;
+ if (visible) {
+ sendEvent (SWT.Show);
+ if (isDisposed ()) return;
+ }
+ OS.UIElement_Visibility (topHandle, visible ? OS.Visibility_Visible : OS.Visibility_Hidden);
+ if (isDisposed ()) return;
+ if (!visible) {
+ sendEvent (SWT.Hide);
+ if (isDisposed ()) return;
+ }
+}
+
+int topHandle () {
+ return handle;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Scrollable.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Scrollable.java
new file mode 100644
index 0000000000..b7d8351114
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Scrollable.java
@@ -0,0 +1,270 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * This class is the abstract superclass of all classes which
+ * represent controls that have standard scroll bars.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>H_SCROLL, V_SCROLL</dd>
+ * <dt><b>Events:</b>
+ * <dd>(none)</dd>
+ * </dl>
+ * <p>
+ * IMPORTANT: This class is intended to be subclassed <em>only</em>
+ * within the SWT implementation.
+ * </p>
+ */
+
+public abstract class Scrollable extends Control {
+ ScrollBar horizontalBar, verticalBar;
+ int scrolledHandle;
+
+/**
+ * Prevents uninitialized instances from being created outside the package.
+ */
+Scrollable () {
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#H_SCROLL
+ * @see SWT#V_SCROLL
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Scrollable (Composite parent, int style) {
+ super (parent, style);
+}
+
+int clientHandle () {
+ return handle;
+}
+
+/**
+ * Given a desired <em>client area</em> for the receiver
+ * (as described by the arguments), returns the bounding
+ * rectangle which would be required to produce that client
+ * area.
+ * <p>
+ * In other words, it returns a rectangle such that, if the
+ * receiver's bounds were set to that rectangle, the area
+ * of the receiver which is capable of displaying data
+ * (that is, not covered by the "trimmings") would be the
+ * rectangle described by the arguments (relative to the
+ * receiver's parent).
+ * </p>
+ *
+ * @param x the desired x coordinate of the client area
+ * @param y the desired y coordinate of the client area
+ * @param width the desired width of the client area
+ * @param height the desired height of the client area
+ * @return the required bounds to produce the given client area
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #getClientArea
+ */
+public Rectangle computeTrim (int x, int y, int width, int height) {
+ checkWidget ();
+ if (verticalBar != null) width += OS.SystemParameters_VerticalScrollBarWidth ();
+ if (horizontalBar != null) height += OS.SystemParameters_HorizontalScrollBarHeight ();
+ return new Rectangle (x, y, width, height);
+}
+
+ScrollBar createScrollBar (int type) {
+ return new ScrollBar (this, type);
+}
+
+void createWidget () {
+ super.createWidget ();
+ if ((style & SWT.H_SCROLL) != 0) horizontalBar = createScrollBar (SWT.H_SCROLL);
+ if ((style & SWT.V_SCROLL) != 0) verticalBar = createScrollBar (SWT.V_SCROLL);
+}
+
+void deregister () {
+ super.deregister ();
+ if (scrolledHandle != 0) display.removeWidget (scrolledHandle);
+}
+
+int findScrollViewer (int current, int scrollViewerType) {
+ int type = OS.Object_GetType (current);
+ boolean found = OS.Object_Equals (scrollViewerType, type);
+ OS.GCHandle_Free (type);
+ if (found) return current;
+ int childCount = OS.VisualTreeHelper_GetChildrenCount (current);
+ for (int i = 0; i < childCount; i++) {
+ int child = OS.VisualTreeHelper_GetChild (current, i);
+ int result = findScrollViewer (child, scrollViewerType);
+ if (child != result) OS.GCHandle_Free (child);
+ if (result != 0) return result;
+ }
+ return 0;
+}
+
+/**
+ * Returns a rectangle which describes the area of the
+ * receiver which is capable of displaying data (that is,
+ * not covered by the "trimmings").
+ *
+ * @return the client area
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #computeTrim
+ */
+public Rectangle getClientArea () {
+ checkWidget ();
+ OS.UIElement_UpdateLayout (topHandle ());
+ int clientHandle = clientHandle ();
+ int width = (int) OS.FrameworkElement_ActualWidth (clientHandle);
+ int height = (int) OS.FrameworkElement_ActualHeight (clientHandle);
+ return new Rectangle (0, 0, width, height);
+}
+
+/**
+ * Returns the receiver's horizontal scroll bar if it has
+ * one, and null if it does not.
+ *
+ * @return the horizontal scroll bar (or null)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public ScrollBar getHorizontalBar () {
+ checkWidget ();
+ return horizontalBar;
+}
+
+int getScrollBarHandle (int style) {
+ int scrollbar = 0;
+ if (scrolledHandle != 0) {
+ int children = OS.Panel_Children (scrolledHandle);
+ int enumerator = OS.UIElementCollection_GetEnumerator (children);
+ int scrollType = OS.ScrollBar_typeid ();
+ while (OS.IEnumerator_MoveNext (enumerator)) {
+ int current = OS.IEnumerator_Current (enumerator);
+ if (OS.Type_IsInstanceOfType (scrollType, current)) {
+ int orientation = OS.ScrollBar_Orientation (current);
+ if ((style & SWT.H_SCROLL) != 0 && orientation == OS.Orientation_Horizontal) {
+ scrollbar = current;
+ break;
+ }
+ if ((style & SWT.V_SCROLL) != 0 && orientation == OS.Orientation_Vertical) {
+ scrollbar = current;
+ break;
+ }
+ }
+ OS.GCHandle_Free (current);
+ }
+ OS.GCHandle_Free (scrollType);
+ OS.GCHandle_Free (enumerator);
+ OS.GCHandle_Free (children);
+ } else {
+ if (!OS.FrameworkElement_IsLoaded (handle)) OS.UIElement_UpdateLayout (handle);
+ int scrollViewerType = OS.ScrollViewer_typeid ();
+ int scrollViewer = findScrollViewer (handle, scrollViewerType);
+ int template = OS.Control_Template (scrollViewer);
+ int part;
+ if ((style & SWT.H_SCROLL) != 0) {
+ part = createDotNetString ("PART_HorizontalScrollBar", false);
+ } else {
+ part = createDotNetString ("PART_VerticalScrollBar", false);
+ }
+ scrollbar = OS.FrameworkTemplate_FindName (template, part, scrollViewer);
+ OS.GCHandle_Free (part);
+ OS.GCHandle_Free (template);
+ OS.GCHandle_Free (scrollViewer);
+ OS.GCHandle_Free (scrollViewerType);
+ }
+ return scrollbar;
+}
+
+/**
+ * Returns the receiver's vertical scroll bar if it has
+ * one, and null if it does not.
+ *
+ * @return the vertical scroll bar (or null)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public ScrollBar getVerticalBar () {
+ checkWidget ();
+ return verticalBar;
+}
+
+void register () {
+ super.register ();
+ if (scrolledHandle != 0) display.addWidget (scrolledHandle, this);
+}
+
+void releaseChildren (boolean destroy) {
+ if (horizontalBar != null) {
+ horizontalBar.release (false);
+ horizontalBar = null;
+ }
+ if (verticalBar != null) {
+ verticalBar.release (false);
+ verticalBar = null;
+ }
+ super.releaseChildren (destroy);
+}
+
+void releaseHandle () {
+ super.releaseHandle ();
+ if (scrolledHandle != 0) OS.GCHandle_Free (scrolledHandle);
+ scrolledHandle = 0;
+}
+
+int topHandle () {
+ return scrolledHandle != 0 ? scrolledHandle : super.topHandle ();
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Shell.java
new file mode 100644
index 0000000000..41b82c1770
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Shell.java
@@ -0,0 +1,1206 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.events.*;
+
+/**
+ * Instances of this class represent the "windows"
+ * which the desktop or "window manager" is managing.
+ * Instances that do not have a parent (that is, they
+ * are built using the constructor, which takes a
+ * <code>Display</code> as the argument) are described
+ * as <em>top level</em> shells. Instances that do have
+ * a parent are described as <em>secondary</em> or
+ * <em>dialog</em> shells.
+ * <p>
+ * Instances are always displayed in one of the maximized,
+ * minimized or normal states:
+ * <ul>
+ * <li>
+ * When an instance is marked as <em>maximized</em>, the
+ * window manager will typically resize it to fill the
+ * entire visible area of the display, and the instance
+ * is usually put in a state where it can not be resized
+ * (even if it has style <code>RESIZE</code>) until it is
+ * no longer maximized.
+ * </li><li>
+ * When an instance is in the <em>normal</em> state (neither
+ * maximized or minimized), its appearance is controlled by
+ * the style constants which were specified when it was created
+ * and the restrictions of the window manager (see below).
+ * </li><li>
+ * When an instance has been marked as <em>minimized</em>,
+ * its contents (client area) will usually not be visible,
+ * and depending on the window manager, it may be
+ * "iconified" (that is, replaced on the desktop by a small
+ * simplified representation of itself), relocated to a
+ * distinguished area of the screen, or hidden. Combinations
+ * of these changes are also possible.
+ * </li>
+ * </ul>
+ * </p><p>
+ * The <em>modality</em> of an instance may be specified using
+ * style bits. The modality style bits are used to determine
+ * whether input is blocked for other shells on the display.
+ * The <code>PRIMARY_MODAL</code> style allows an instance to block
+ * input to its parent. The <code>APPLICATION_MODAL</code> style
+ * allows an instance to block input to every other shell in the
+ * display. The <code>SYSTEM_MODAL</code> style allows an instance
+ * to block input to all shells, including shells belonging to
+ * different applications.
+ * </p><p>
+ * Note: The styles supported by this class are treated
+ * as <em>HINT</em>s, since the window manager for the
+ * desktop on which the instance is visible has ultimate
+ * control over the appearance and behavior of decorations
+ * and modality. For example, some window managers only
+ * support resizable windows and will always assume the
+ * RESIZE style, even if it is not set. In addition, if a
+ * modality style is not supported, it is "upgraded" to a
+ * more restrictive modality style that is supported. For
+ * example, if <code>PRIMARY_MODAL</code> is not supported,
+ * it would be upgraded to <code>APPLICATION_MODAL</code>.
+ * A modality style may also be "downgraded" to a less
+ * restrictive style. For example, most operating systems
+ * no longer support <code>SYSTEM_MODAL</code> because
+ * it can freeze up the desktop, so this is typically
+ * downgraded to <code>APPLICATION_MODAL</code>.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>BORDER, CLOSE, MIN, MAX, NO_TRIM, RESIZE, TITLE, ON_TOP, TOOL</dd>
+ * <dd>APPLICATION_MODAL, MODELESS, PRIMARY_MODAL, SYSTEM_MODAL</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Activate, Close, Deactivate, Deiconify, Iconify</dd>
+ * </dl>
+ * Class <code>SWT</code> provides two "convenience constants"
+ * for the most commonly required style combinations:
+ * <dl>
+ * <dt><code>SHELL_TRIM</code></dt>
+ * <dd>
+ * the result of combining the constants which are required
+ * to produce a typical application top level shell: (that
+ * is, <code>CLOSE | TITLE | MIN | MAX | RESIZE</code>)
+ * </dd>
+ * <dt><code>DIALOG_TRIM</code></dt>
+ * <dd>
+ * the result of combining the constants which are required
+ * to produce a typical application dialog shell: (that
+ * is, <code>TITLE | CLOSE | BORDER</code>)
+ * </dd>
+ * </dl>
+ * </p>
+ * <p>
+ * Note: Only one of the styles APPLICATION_MODAL, MODELESS,
+ * PRIMARY_MODAL and SYSTEM_MODAL may be specified.
+ * </p><p>
+ * IMPORTANT: This class is not intended to be subclassed.
+ * </p>
+ *
+ * @see Decorations
+ * @see SWT
+ */
+public class Shell extends Decorations {
+ Region region;
+ Control lastActive;
+ boolean closing;
+ boolean moved, resized, opened;
+ int oldX, oldY, oldWidth, oldHeight;
+
+/**
+ * Constructs a new instance of this class. This is equivalent
+ * to calling <code>Shell((Display) null)</code>.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ */
+public Shell () {
+ this ((Display) null);
+}
+
+/**
+ * Constructs a new instance of this class given only the style
+ * value describing its behavior and appearance. This is equivalent
+ * to calling <code>Shell((Display) null, style)</code>.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param style the style of control to construct
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#BORDER
+ * @see SWT#CLOSE
+ * @see SWT#MIN
+ * @see SWT#MAX
+ * @see SWT#RESIZE
+ * @see SWT#TITLE
+ * @see SWT#NO_TRIM
+ * @see SWT#SHELL_TRIM
+ * @see SWT#DIALOG_TRIM
+ * @see SWT#MODELESS
+ * @see SWT#PRIMARY_MODAL
+ * @see SWT#APPLICATION_MODAL
+ * @see SWT#SYSTEM_MODAL
+ */
+public Shell (int style) {
+ this ((Display) null, style);
+}
+
+/**
+ * Constructs a new instance of this class given only the display
+ * to create it on. It is created with style <code>SWT.SHELL_TRIM</code>.
+ * <p>
+ * Note: Currently, null can be passed in for the display argument.
+ * This has the effect of creating the shell on the currently active
+ * display if there is one. If there is no current display, the
+ * shell is created on a "default" display. <b>Passing in null as
+ * the display argument is not considered to be good coding style,
+ * and may not be supported in a future release of SWT.</b>
+ * </p>
+ *
+ * @param display the display to create the shell on
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ */
+public Shell (Display display) {
+ this (display, SWT.SHELL_TRIM);
+}
+
+/**
+ * Constructs a new instance of this class given the display
+ * to create it on and a style value describing its behavior
+ * and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p><p>
+ * Note: Currently, null can be passed in for the display argument.
+ * This has the effect of creating the shell on the currently active
+ * display if there is one. If there is no current display, the
+ * shell is created on a "default" display. <b>Passing in null as
+ * the display argument is not considered to be good coding style,
+ * and may not be supported in a future release of SWT.</b>
+ * </p>
+ *
+ * @param display the display to create the shell on
+ * @param style the style of control to construct
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#BORDER
+ * @see SWT#CLOSE
+ * @see SWT#MIN
+ * @see SWT#MAX
+ * @see SWT#RESIZE
+ * @see SWT#TITLE
+ * @see SWT#NO_TRIM
+ * @see SWT#SHELL_TRIM
+ * @see SWT#DIALOG_TRIM
+ * @see SWT#MODELESS
+ * @see SWT#PRIMARY_MODAL
+ * @see SWT#APPLICATION_MODAL
+ * @see SWT#SYSTEM_MODAL
+ */
+public Shell (Display display, int style) {
+ this (display, null, style, 0);
+}
+
+Shell (Display display, Shell parent, int style, int handle) {
+ super ();
+ checkSubclass ();
+ if (display == null) display = Display.getCurrent ();
+ if (display == null) display = Display.getDefault ();
+ if (!display.isValidThread ()) {
+ error (SWT.ERROR_THREAD_INVALID_ACCESS);
+ }
+ if (parent != null && parent.isDisposed ()) {
+ error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+ this.style = checkStyle (style);
+ this.parent = parent;
+ this.display = display;
+ this.handle = handle;
+ createWidget ();
+}
+
+/**
+ * Constructs a new instance of this class given only its
+ * parent. It is created with style <code>SWT.DIALOG_TRIM</code>.
+ * <p>
+ * Note: Currently, null can be passed in for the parent.
+ * This has the effect of creating the shell on the currently active
+ * display if there is one. If there is no current display, the
+ * shell is created on a "default" display. <b>Passing in null as
+ * the parent is not considered to be good coding style,
+ * and may not be supported in a future release of SWT.</b>
+ * </p>
+ *
+ * @param parent a shell which will be the parent of the new instance
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the parent is disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ */
+public Shell (Shell parent) {
+ this (parent, SWT.DIALOG_TRIM);
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p><p>
+ * Note: Currently, null can be passed in for the parent.
+ * This has the effect of creating the shell on the currently active
+ * display if there is one. If there is no current display, the
+ * shell is created on a "default" display. <b>Passing in null as
+ * the parent is not considered to be good coding style,
+ * and may not be supported in a future release of SWT.</b>
+ * </p>
+ *
+ * @param parent a shell which will be the parent of the new instance
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the parent is disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#BORDER
+ * @see SWT#CLOSE
+ * @see SWT#MIN
+ * @see SWT#MAX
+ * @see SWT#RESIZE
+ * @see SWT#TITLE
+ * @see SWT#NO_TRIM
+ * @see SWT#SHELL_TRIM
+ * @see SWT#DIALOG_TRIM
+ * @see SWT#ON_TOP
+ * @see SWT#TOOL
+ * @see SWT#MODELESS
+ * @see SWT#PRIMARY_MODAL
+ * @see SWT#APPLICATION_MODAL
+ * @see SWT#SYSTEM_MODAL
+ */
+public Shell (Shell parent, int style) {
+ this (parent != null ? parent.display : null, parent, style, 0);
+}
+
+/**
+ * Invokes platform specific functionality to allocate a new shell.
+ * <p>
+ * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
+ * API for <code>Shell</code>. It is marked public only so that it
+ * can be shared within the packages provided by SWT. It is not
+ * available on all platforms, and should never be called from
+ * application code.
+ * </p>
+ *
+ * @param display the display for the shell
+ * @param handle the handle for the shell
+ * @return a new shell object containing the specified display and handle
+ */
+public static Shell wpf_new (Display display, int handle) {
+ return new Shell (display, null, SWT.NO_TRIM, handle);
+}
+
+static int checkStyle (int style) {
+ style = Decorations.checkStyle (style);
+ int mask = SWT.SYSTEM_MODAL | SWT.APPLICATION_MODAL | SWT.PRIMARY_MODAL;
+ int bits = style & ~mask;
+ if ((style & SWT.SYSTEM_MODAL) != 0) return bits | SWT.SYSTEM_MODAL;
+ if ((style & SWT.APPLICATION_MODAL) != 0) return bits | SWT.APPLICATION_MODAL;
+ if ((style & SWT.PRIMARY_MODAL) != 0) return bits | SWT.PRIMARY_MODAL;
+ return bits;
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when operations are performed on the receiver,
+ * by sending the listener one of the messages defined in the
+ * <code>ShellListener</code> interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ShellListener
+ * @see #removeShellListener
+ */
+public void addShellListener (ShellListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Close,typedListener);
+ addListener (SWT.Iconify,typedListener);
+ addListener (SWT.Deiconify,typedListener);
+ addListener (SWT.Activate, typedListener);
+ addListener (SWT.Deactivate, typedListener);
+}
+
+void addWidget () {
+ if (parent != null) {
+ OS.Window_Owner (shellHandle, ((Shell)parent).shellHandle);
+ }
+}
+
+void bringToTop () {
+ OS.Window_Activate (shellHandle);
+}
+
+void checkOpen () {
+ if (!opened) resized = false;
+}
+
+/**
+ * Requests that the window manager close the receiver in
+ * the same way it would be closed when the user clicks on
+ * the "close box" or performs some other platform specific
+ * key or mouse combination that indicates the window
+ * should be removed.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SWT#Close
+ * @see #dispose
+ */
+public void close () {
+ checkWidget ();
+ closeWidget ();
+}
+
+void createHandle () {
+ state |= CANVAS;
+ shellHandle = OS.gcnew_Window();
+ if (shellHandle == 0) error(SWT.ERROR_NO_HANDLES);
+
+ /*
+ * Feature in WPF. ...
+ */
+ OS.Window_ShowInTaskbar (shellHandle, false);
+ OS.Window_ResizeMode (shellHandle, OS.ResizeMode_NoResize);
+ OS.Window_WindowStyle (shellHandle, OS.WindowStyle_None);
+ OS.FrameworkElement_Width(shellHandle, 0);
+ OS.FrameworkElement_Height(shellHandle, 0);
+ OS.Window_Show(shellHandle);
+ OS.Window_Hide(shellHandle);
+ Rectangle bounds = display.getBounds();
+ OS.FrameworkElement_Width(shellHandle, bounds.width * 5 / 8);
+ OS.FrameworkElement_Height(shellHandle, bounds.height * 5 / 8);
+
+ int windowStyle = OS.WindowStyle_None, resizeMode = OS.ResizeMode_NoResize;
+ if ((style & SWT.NO_TRIM) == 0) {
+ if ((style & SWT.TOOL) != 0) {
+ windowStyle = OS.WindowStyle_ToolWindow;
+ } else if ((style & SWT.SHELL_TRIM) != 0) {
+ windowStyle = OS.WindowStyle_SingleBorderWindow;
+ }
+ if ((style & SWT.RESIZE) != 0) {
+ resizeMode |= OS.ResizeMode_CanResize;
+ }
+ }
+ OS.Window_ShowInTaskbar (shellHandle, parent == null);
+ OS.Window_ResizeMode (shellHandle, resizeMode);
+ OS.Window_WindowStyle (shellHandle, windowStyle);
+ OS.Window_Topmost (shellHandle, (style & SWT.ON_TOP) != 0);
+ OS.KeyboardNavigation_SetTabNavigation (shellHandle, OS.KeyboardNavigationMode_None);
+
+ boolean scrolled = (style & (SWT.H_SCROLL | SWT.V_SCROLL)) != 0;
+ createHandle (scrolled, true);
+ OS.ContentControl_Content (shellHandle, super.topHandle());
+}
+
+public Rectangle computeTrim (int x, int y, int width, int height) {
+ checkWidget ();
+ OS.UIElement_UpdateLayout(shellHandle);
+ int clientX = (int) OS.Window_Left (shellHandle);
+ int clientY = (int) OS.Window_Top (shellHandle);
+ int w = (int) OS.FrameworkElement_ActualWidth (shellHandle);
+ int h = (int) OS.FrameworkElement_ActualHeight (shellHandle);
+ int clientWidth = (int) OS.FrameworkElement_ActualWidth (handle);
+ int clientHeight = (int) OS.FrameworkElement_ActualHeight (handle);
+ int point = OS.gcnew_Point (clientX, clientY);
+ int result = OS.Visual_PointFromScreen (shellHandle, point);
+ OS.GCHandle_Free (point);
+ clientX = -(int) OS.Point_X (result);
+ clientY = -(int) OS.Point_Y (result);
+ OS.GCHandle_Free (result);
+ x -= clientX;
+ y -= clientY;
+ width += (w - clientWidth);
+ height += (h - clientHeight);
+ return new Rectangle (x, y, width, height);
+}
+
+void deregister () {
+ super.deregister ();
+ display.removeWidget (shellHandle);
+}
+
+
+void destroyWidget () {
+ if (shellHandle != 0 && !closing) OS.Window_Close (shellHandle);
+ releaseHandle ();
+ //TODO check leak
+}
+
+public void dispose () {
+ /*
+ * This code is intentionally commented. On some
+ * platforms, the owner window is repainted right
+ * away when a dialog window exits. This behavior
+ * is currently unspecified.
+ */
+// /*
+// * Note: It is valid to attempt to dispose a widget
+// * more than once. If this happens, fail silently.
+// */
+// if (!isValidWidget ()) return;
+// if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
+// Display oldDisplay = display;
+ super.dispose ();
+ // widget is disposed at this point
+// if (oldDisplay != null) oldDisplay.update ();
+}
+
+Control findBackgroundControl () {
+ return background != -1 || backgroundImage != null ? this : null;
+}
+
+Control findThemeControl () {
+ return null;
+}
+
+/**
+ * If the receiver is visible, moves it to the top of the
+ * drawing order for the display on which it was created
+ * (so that all other shells on that display, which are not
+ * the receiver's children will be drawn behind it) and forces
+ * the window manager to make the shell active.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.0
+ * @see Control#moveAbove
+ * @see Control#setFocus
+ * @see Control#setVisible
+ * @see Display#getActiveShell
+ * @see Decorations#setDefaultButton
+ * @see Shell#open
+ * @see Shell#setActive
+ */
+public void forceActive () {
+ checkWidget ();
+ if(!isVisible()) return;
+// OS.SetForegroundWindow (handle);
+ OS.Window_Activate (shellHandle);
+}
+
+public Rectangle getBounds () {
+ checkWidget ();
+ int x = (int) OS.Window_Left (shellHandle);
+ int y = (int) OS.Window_Top (shellHandle);
+ int width = (int) OS.FrameworkElement_ActualWidth (shellHandle);
+ int height = (int) OS.FrameworkElement_ActualHeight (shellHandle);
+ return new Rectangle (x, y, width, height);
+}
+
+/**
+ * Returns the receiver's input method editor mode. This
+ * will be the result of bitwise OR'ing together one or
+ * more of the following constants defined in class
+ * <code>SWT</code>:
+ * <code>NONE</code>, <code>ROMAN</code>, <code>DBCS</code>,
+ * <code>PHONETIC</code>, <code>NATIVE</code>, <code>ALPHA</code>.
+ *
+ * @return the IME mode
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SWT
+ */
+public int getImeInputMode () {
+ checkWidget ();
+ //TODO
+ return SWT.ROMAN;
+}
+
+public Point getLocation () {
+ checkWidget ();
+ int x = (int) OS.Window_Left (shellHandle);
+ int y = (int) OS.Window_Top (shellHandle);
+ return new Point (x, y);
+}
+
+/**
+ * Returns a point describing the minimum receiver's size. The
+ * x coordinate of the result is the minimum width of the receiver.
+ * The y coordinate of the result is the minimum height of the
+ * receiver.
+ *
+ * @return the receiver's size
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public Point getMinimumSize () {
+ checkWidget ();
+// int width = Math.max (0, minWidth);
+// int trim = SWT.TITLE | SWT.CLOSE | SWT.MIN | SWT.MAX;
+// if ((style & SWT.NO_TRIM) == 0 && (style & trim) != 0) {
+// width = Math.max (width, OS.GetSystemMetrics (OS.SM_CXMINTRACK));
+// }
+// int height = Math.max (0, minHeight);
+// if ((style & SWT.NO_TRIM) == 0 && (style & trim) != 0) {
+// if ((style & SWT.RESIZE) != 0) {
+// height = Math.max (height, OS.GetSystemMetrics (OS.SM_CYMINTRACK));
+// } else {
+// RECT rect = new RECT ();
+// int bits1 = OS.GetWindowLong (handle, OS.GWL_STYLE);
+// int bits2 = OS.GetWindowLong (handle, OS.GWL_EXSTYLE);
+// OS.AdjustWindowRectEx (rect, bits1, false, bits2);
+// height = Math.max (height, rect.bottom - rect.top);
+// }
+// }
+ int width = (int) OS.FrameworkElement_MinWidth (shellHandle);
+ int height = (int) OS.FrameworkElement_MinHeight (shellHandle);
+ return new Point (width, height);
+}
+
+/**
+ * Returns the region that defines the shape of the shell,
+ * or null if the shell has the default shape.
+ *
+ * @return the region that defines the shape of the shell (or null)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ *
+ */
+public Region getRegion () {
+ checkWidget ();
+ return region;
+}
+
+public Shell getShell () {
+ checkWidget ();
+ return this;
+}
+
+/**
+ * Returns an array containing all shells which are
+ * descendents of the receiver.
+ * <p>
+ * @return the dialog shells
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Shell [] getShells () {
+ checkWidget ();
+ int count = 0;
+ Shell [] shells = display.getShells ();
+ for (int i=0; i<shells.length; i++) {
+ Control shell = shells [i];
+ do {
+ shell = shell.parent;
+ } while (shell != null && shell != this);
+ if (shell == this) count++;
+ }
+ int index = 0;
+ Shell [] result = new Shell [count];
+ for (int i=0; i<shells.length; i++) {
+ Control shell = shells [i];
+ do {
+ shell = shell.parent;
+ } while (shell != null && shell != this);
+ if (shell == this) {
+ result [index++] = shells [i];
+ }
+ }
+ return result;
+}
+
+Composite findDeferredControl () {
+ return layoutCount > 0 ? this : null;
+}
+
+public boolean isEnabled () {
+ checkWidget ();
+ return getEnabled ();
+}
+
+void hookEvents () {
+ super.hookEvents ();
+ int handler = OS.gcnew_CancelEventHandler (jniRef, "HandleClosing");
+ OS.Window_Closing (shellHandle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_EventHandler (jniRef, "HandleActivated");
+ OS.Window_Activated (shellHandle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_EventHandler (jniRef, "HandleDeactivated");
+ OS.Window_Deactivated (shellHandle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_EventHandler (jniRef, "HandleLocationChanged");
+ OS.Window_LocationChanged (shellHandle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_SizeChangedEventHandler (jniRef, "HandleSizeChanged");
+ OS.FrameworkElement_SizeChanged (shellHandle, handler);
+ OS.GCHandle_Free (handler);
+}
+
+void HandleActivated (int sender, int e) {
+ if (!checkEvent (e)) return;
+ sendEvent (SWT.Activate);
+ if (isDisposed ()) return;
+ if (!restoreFocus () && !traverseGroup (true)) setFocus ();
+}
+
+void HandleClosing (int sender, int e) {
+ if (!checkEvent (e)) return;
+ closing = true;
+ boolean doit = false;
+ if (isEnabled () && isActive ()) {
+ Event event = new Event ();
+ sendEvent (SWT.Close, event);
+ doit = event.doit || isDisposed ();
+ }
+ if (doit) {
+ if (!isDisposed ()) release (false);
+ } else {
+ OS.CancelEventArgs_Cancel (e, true);
+ }
+ closing = false;
+}
+
+void HandleDeactivated (int sender, int e) {
+ if (!checkEvent (e)) return;
+ sendEvent (SWT.Deactivate);
+ if (isDisposed ()) return;
+ saveFocus ();
+}
+
+void HandleLocationChanged (int sender, int e) {
+ if (!checkEvent (e)) return;
+ int x = (int) OS.Window_Left (shellHandle);
+ int y = (int) OS.Window_Top (shellHandle);
+ if (!moved || oldX != x || oldY != y) {
+ moved = true;
+ oldX = x;
+ oldY = y;
+ sendEvent (SWT.Move);
+ // widget could be disposed at this point
+ }
+}
+
+void HandleSizeChanged (int sender, int e) {
+ if (!checkEvent (e)) return;
+ int width = (int) OS.FrameworkElement_ActualWidth (shellHandle);
+ int height = (int) OS.FrameworkElement_ActualHeight (shellHandle);
+ if (oldWidth != width || oldHeight != height) {
+ resized = true;
+ oldWidth = width;
+ oldHeight = height;
+ sendEvent (SWT.Resize);
+ if (isDisposed ()) return;
+ if (layout != null) {
+ markLayout (false, false);
+ updateLayout (false, false);
+ }
+ }
+}
+
+/**
+ * Moves the receiver to the top of the drawing order for
+ * the display on which it was created (so that all other
+ * shells on that display, which are not the receiver's
+ * children will be drawn behind it), marks it visible,
+ * sets the focus and asks the window manager to make the
+ * shell active.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Control#moveAbove
+ * @see Control#setFocus
+ * @see Control#setVisible
+ * @see Display#getActiveShell
+ * @see Decorations#setDefaultButton
+ * @see Shell#setActive
+ * @see Shell#forceActive
+ */
+public void open () {
+ checkWidget ();
+ bringToTop ();
+ if (isDisposed ()) return;
+ setVisible (true);
+ if (isDisposed ()) return;
+// if (!restoreFocus () && !traverseGroup (true)) setFocus ();
+}
+
+void register () {
+ super.register ();
+ display.addWidget (shellHandle, this);
+}
+
+void releaseChildren (boolean destroy) {
+ Shell [] shells = getShells ();
+ for (int i=0; i<shells.length; i++) {
+ Shell shell = shells [i];
+ if (shell != null && !shell.isDisposed ()) {
+ shell.release (false);
+ }
+ }
+ super.releaseChildren (destroy);
+}
+
+void releaseHandle () {
+ super.releaseHandle ();
+ if (shellHandle != 0) OS.GCHandle_Free (shellHandle);
+ shellHandle = 0;
+}
+
+void releaseParent () {
+ /* Do nothing */
+}
+
+void releaseWidget () {
+ super.releaseWidget ();
+// display.clearModal (this);
+ region = null;
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when operations are performed on the receiver.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ShellListener
+ * @see #addShellListener
+ */
+public void removeShellListener (ShellListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Close, listener);
+ eventTable.unhook (SWT.Iconify,listener);
+ eventTable.unhook (SWT.Deiconify,listener);
+ eventTable.unhook (SWT.Activate, listener);
+ eventTable.unhook (SWT.Deactivate, listener);
+}
+
+/**
+ * If the receiver is visible, moves it to the top of the
+ * drawing order for the display on which it was created
+ * (so that all other shells on that display, which are not
+ * the receiver's children will be drawn behind it) and asks
+ * the window manager to make the shell active
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.0
+ * @see Control#moveAbove
+ * @see Control#setFocus
+ * @see Control#setVisible
+ * @see Display#getActiveShell
+ * @see Decorations#setDefaultButton
+ * @see Shell#open
+ * @see Shell#setActive
+ */
+public void setActive () {
+ checkWidget ();
+ if(!isVisible()) return;
+ bringToTop ();
+ // widget could be disposed at this point
+}
+
+void setActiveControl (Control control) {
+ if (control != null && control.isDisposed ()) control = null;
+ if (lastActive != null && lastActive.isDisposed ()) lastActive = null;
+ if (lastActive == control) return;
+
+ /*
+ * Compute the list of controls to be activated and
+ * deactivated by finding the first common parent
+ * control.
+ */
+ Control [] activate = (control == null) ? new Control [0] : control.getPath ();
+ Control [] deactivate = (lastActive == null) ? new Control [0] : lastActive.getPath ();
+ lastActive = control;
+ int index = 0, length = Math.min (activate.length, deactivate.length);
+ while (index < length) {
+ if (activate [index] != deactivate [index]) break;
+ index++;
+ }
+
+ /*
+ * It is possible (but unlikely), that application
+ * code could have destroyed some of the widgets. If
+ * this happens, keep processing those widgets that
+ * are not disposed.
+ */
+ for (int i=deactivate.length-1; i>=index; --i) {
+ if (!deactivate [i].isDisposed ()) {
+ deactivate [i].sendEvent (SWT.Deactivate);
+ }
+ }
+ for (int i=activate.length-1; i>=index; --i) {
+ if (!activate [i].isDisposed ()) {
+ activate [i].sendEvent (SWT.Activate);
+ }
+ }
+}
+
+int setBounds (int x, int y, int width, int height, int flags) {
+ int result = 0;
+ if ((flags & MOVED) != 0) {
+ int currentX = (int) OS.Window_Left (shellHandle);
+ int currentY = (int) OS.Window_Top (shellHandle);
+ if (currentX != x || currentY != y) {
+ moved = true;
+ oldX = currentX;
+ oldY = currentY;
+ OS.Window_Left (shellHandle, x);
+ OS.Window_Top (shellHandle, y);
+ sendEvent (SWT.Move);
+ if (isDisposed ()) return 0;
+ result |= MOVED;
+ }
+ }
+ if ((flags & RESIZED) != 0) {
+ int currentWidth = (int) OS.FrameworkElement_ActualWidth (shellHandle);
+ int currentHeight = (int) OS.FrameworkElement_ActualHeight (shellHandle);
+ if (currentWidth != width || currentHeight != height) {
+ resized = true;
+ oldWidth = currentWidth;
+ oldHeight = currentHeight;
+ OS.FrameworkElement_Width (shellHandle, width);
+ OS.FrameworkElement_Height (shellHandle, height);
+ sendEvent (SWT.Resize);
+ if (isDisposed ()) return 0;
+ result |= RESIZED;
+ }
+ }
+ return result;
+}
+
+void setClipping () {
+
+}
+
+public void setEnabled (boolean enabled) {
+ checkWidget ();
+ if (OS.UIElement_IsEnabled (handle) == enabled) return;
+ super.setEnabled (enabled);
+// if (enabled && OS.Window_IsActive (shellHandle)) {
+// if (!restoreFocus ()) traverseGroup (true);
+// }
+}
+
+/**
+ * Sets the input method editor mode to the argument which
+ * should be the result of bitwise OR'ing together one or more
+ * of the following constants defined in class <code>SWT</code>:
+ * <code>NONE</code>, <code>ROMAN</code>, <code>DBCS</code>,
+ * <code>PHONETIC</code>, <code>NATIVE</code>, <code>ALPHA</code>.
+ *
+ * @param mode the new IME mode
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SWT
+ */
+public void setImeInputMode (int mode) {
+ checkWidget ();
+ //TODO
+}
+
+/**
+ * Sets the receiver's minimum size to the size specified by the arguments.
+ * If the new minimum size is larger than the current size of the receiver,
+ * the receiver is resized to the new minimum size.
+ *
+ * @param width the new minimum width for the receiver
+ * @param height the new minimum height for the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public void setMinimumSize (int width, int height) {
+ checkWidget ();
+ int widthLimit = 0, heightLimit = 0;
+ int trim = SWT.TITLE | SWT.CLOSE | SWT.MIN | SWT.MAX;
+ if ((style & SWT.NO_TRIM) == 0 && (style & trim) != 0) {
+// widthLimit = OS.GetSystemMetrics (OS.SM_CXMINTRACK);
+// if ((style & SWT.RESIZE) != 0) {
+// heightLimit = OS.GetSystemMetrics (OS.SM_CYMINTRACK);
+// } else {
+// RECT rect = new RECT ();
+// int bits1 = OS.GetWindowLong (handle, OS.GWL_STYLE);
+// int bits2 = OS.GetWindowLong (handle, OS.GWL_EXSTYLE);
+// OS.AdjustWindowRectEx (rect, bits1, false, bits2);
+// heightLimit = rect.bottom - rect.top;
+// }
+ }
+ int minWidth = Math.max (widthLimit, width);
+ int minHeight = Math.max (heightLimit, height);
+ OS.FrameworkElement_MinWidth(shellHandle, minWidth);
+ OS.FrameworkElement_MinHeight(shellHandle, minHeight);
+}
+
+/**
+ * Sets the receiver's minimum size to the size specified by the argument.
+ * If the new minimum size is larger than the current size of the receiver,
+ * the receiver is resized to the new minimum size.
+ *
+ * @param size the new minimum size for the receiver
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public void setMinimumSize (Point size) {
+ checkWidget ();
+ if (size == null) error (SWT.ERROR_NULL_ARGUMENT);
+ setMinimumSize (size.x, size.y);
+}
+
+void setParent () {
+ /* Do nothing. Not necessary for Shells */
+}
+
+/**
+ * Sets the shape of the shell to the region specified
+ * by the argument. When the argument is null, the
+ * default shape of the shell is restored. The shell
+ * must be created with the style SWT.NO_TRIM in order
+ * to specify a region.
+ *
+ * @param region the region that defines the shape of the shell (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the region has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ *
+ */
+public void setRegion (Region region) {
+ checkWidget ();
+ if ((style & SWT.NO_TRIM) == 0) return;
+ if (region != null && region.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ OS.UIElement_Clip (shellHandle, region.handle);
+ this.region = region;
+}
+
+public void setVisible (boolean visible) {
+ checkWidget ();
+ if (visible) {
+ OS.Window_Show (shellHandle);
+
+ opened = true;
+ if (!moved) {
+ moved = true;
+ Point location = getLocation();
+ oldX = location.x;
+ oldY = location.y;
+ sendEvent (SWT.Move);
+ if (isDisposed ()) return;
+ }
+ if (!resized) {
+ resized = true;
+ Point size = getSize ();
+ oldWidth = size.x;// - trimWidth ();
+ oldHeight = size.y;// - trimHeight ();
+ sendEvent (SWT.Resize);
+ if (isDisposed ()) return;
+ if (layout != null) {
+ markLayout (false, false);
+ updateLayout (false, false);
+ }
+ }
+
+ } else {
+ if (!closing) OS.Window_Hide (shellHandle);
+ }
+// if (drawCount != 0) {
+// if (((state & HIDDEN) == 0) == visible) return;
+// } else {
+// if (visible == OS.IsWindowVisible (handle)) return;
+// }
+//
+// /*
+// * Feature in Windows. When ShowWindow() is called used to hide
+// * a window, Windows attempts to give focus to the parent. If the
+// * parent is disabled by EnableWindow(), focus is assigned to
+// * another windows on the desktop. This means that if you hide
+// * a modal window before the parent is enabled, the parent will
+// * not come to the front. The fix is to change the modal state
+// * before hiding or showing a window so that this does not occur.
+// */
+// int mask = SWT.PRIMARY_MODAL | SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL;
+// if ((style & mask) != 0) {
+// if (visible) {
+// display.setModalShell (this);
+// Control control = display._getFocusControl ();
+// if (control != null && !control.isActive ()) {
+// bringToTop ();
+// if (isDisposed ()) return;
+// }
+// int hwndShell = OS.GetActiveWindow ();
+// if (hwndShell == 0) {
+// if (parent != null) hwndShell = parent.handle;
+// }
+// if (hwndShell != 0) {
+// OS.SendMessage (hwndShell, OS.WM_CANCELMODE, 0, 0);
+// }
+// OS.ReleaseCapture ();
+// } else {
+// display.clearModal (this);
+// }
+// } else {
+// updateModal ();
+// }
+//
+// /*
+// * Bug in Windows. Calling ShowOwnedPopups() to hide the
+// * child windows of a hidden window causes the application
+// * to be deactivated. The fix is to call ShowOwnedPopups()
+// * to hide children before hiding the parent.
+// */
+// if (showWithParent && !visible) {
+// if (!OS.IsWinCE) OS.ShowOwnedPopups (handle, false);
+// }
+// super.setVisible (visible);
+// if (isDisposed ()) return;
+// if (showWithParent == visible) return;
+// showWithParent = visible;
+// if (visible) {
+// if (!OS.IsWinCE) OS.ShowOwnedPopups (handle, true);
+// }
+}
+
+int topHandle () {
+ return shellHandle;
+}
+
+//boolean translateAccelerator (MSG msg) {
+// if (!isEnabled () || !isActive ()) return false;
+// if (menuBar != null && !menuBar.isEnabled ()) return false;
+// return translateMDIAccelerator (msg) || translateMenuAccelerator (msg);
+//}
+
+boolean traverseEscape () {
+ if (parent == null) return false;
+ if (!isVisible () || !isEnabled ()) return false;
+ close ();
+ return true;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Slider.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Slider.java
new file mode 100644
index 0000000000..d6d0dcdc59
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Slider.java
@@ -0,0 +1,490 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.events.*;
+
+/**
+ * Instances of this class are selectable user interface
+ * objects that represent a range of positive, numeric values.
+ * <p>
+ * At any given moment, a given slider will have a
+ * single 'selection' that is considered to be its
+ * value, which is constrained to be within the range of
+ * values the slider represents (that is, between its
+ * <em>minimum</em> and <em>maximum</em> values).
+ * </p><p>
+ * Typically, sliders will be made up of five areas:
+ * <ol>
+ * <li>an arrow button for decrementing the value</li>
+ * <li>a page decrement area for decrementing the value by a larger amount</li>
+ * <li>a <em>thumb</em> for modifying the value by mouse dragging</li>
+ * <li>a page increment area for incrementing the value by a larger amount</li>
+ * <li>an arrow button for incrementing the value</li>
+ * </ol>
+ * Based on their style, sliders are either <code>HORIZONTAL</code>
+ * (which have a left facing button for decrementing the value and a
+ * right facing button for incrementing it) or <code>VERTICAL</code>
+ * (which have an upward facing button for decrementing the value
+ * and a downward facing buttons for incrementing it).
+ * </p><p>
+ * On some platforms, the size of the slider's thumb can be
+ * varied relative to the magnitude of the range of values it
+ * represents (that is, relative to the difference between its
+ * maximum and minimum values). Typically, this is used to
+ * indicate some proportional value such as the ratio of the
+ * visible area of a document to the total amount of space that
+ * it would take to display it. SWT supports setting the thumb
+ * size even if the underlying platform does not, but in this
+ * case the appearance of the slider will not change.
+ * </p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>HORIZONTAL, VERTICAL</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Selection</dd>
+ * </dl>
+ * <p>
+ * Note: Only one of the styles HORIZONTAL and VERTICAL may be specified.
+ * </p><p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ *
+ * @see ScrollBar
+ */
+public class Slider extends Control {
+ boolean ignoreFocus;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#HORIZONTAL
+ * @see SWT#VERTICAL
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Slider (Composite parent, int style) {
+ super (parent, checkStyle (style));
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the receiver's value changes, by sending
+ * it one of the messages defined in the <code>SelectionListener</code>
+ * interface.
+ * <p>
+ * When <code>widgetSelected</code> is called, the event object detail field contains one of the following values:
+ * <code>SWT.NONE</code> - for the end of a drag.
+ * <code>SWT.DRAG</code>.
+ * <code>SWT.HOME</code>.
+ * <code>SWT.END</code>.
+ * <code>SWT.ARROW_DOWN</code>.
+ * <code>SWT.ARROW_UP</code>.
+ * <code>SWT.PAGE_DOWN</code>.
+ * <code>SWT.PAGE_UP</code>.
+ * <code>widgetDefaultSelected</code> is not called.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #removeSelectionListener
+ * @see SelectionEvent
+ */
+public void addSelectionListener (SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener(listener);
+ addListener (SWT.Selection,typedListener);
+ addListener (SWT.DefaultSelection,typedListener);
+}
+
+static int checkStyle (int style) {
+ return checkBits (style, SWT.HORIZONTAL, SWT.VERTICAL, 0, 0, 0, 0);
+}
+
+public Point computeSize (int wHint, int hHint, boolean changed) {
+ checkWidget ();
+ int border = getBorderWidth ();
+ int width = border * 2, height = border * 2;
+ if ((style & SWT.HORIZONTAL) != 0) {
+ width += OS.SystemParameters_HorizontalScrollBarButtonWidth () * 10;
+ height += OS.SystemParameters_HorizontalScrollBarHeight ();
+ } else {
+ width += OS.SystemParameters_VerticalScrollBarWidth ();
+ height += OS.SystemParameters_VerticalScrollBarButtonHeight () * 10;
+ }
+ if (wHint != SWT.DEFAULT) width = wHint + (border * 2);
+ if (hHint != SWT.DEFAULT) height = hHint + (border * 2);
+ return new Point (width, height);
+}
+
+void createHandle () {
+ handle = OS.gcnew_ScrollBar ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ if ((style & SWT.HORIZONTAL) != 0) OS.ScrollBar_Orientation (handle, OS.Orientation_Horizontal);
+ OS.RangeBase_Maximum (handle, 100);
+ OS.RangeBase_LargeChange (handle, 10);
+ OS.RangeBase_SmallChange (handle, 1);
+}
+
+/**
+ * Returns the amount that the receiver's value will be
+ * modified by when the up/down (or right/left) arrows
+ * are pressed.
+ *
+ * @return the increment
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getIncrement () {
+ checkWidget ();
+ return (int) OS.RangeBase_SmallChange (handle);
+}
+
+/**
+ * Returns the maximum value which the receiver will allow.
+ *
+ * @return the maximum
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getMaximum () {
+ checkWidget ();
+ int maximum = (int) OS.RangeBase_Maximum (handle);
+ int viewSize = (int) OS.ScrollBar_ViewportSize (handle);
+ return maximum + viewSize;
+}
+
+/**
+ * Returns the minimum value which the receiver will allow.
+ *
+ * @return the minimum
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getMinimum () {
+ checkWidget ();
+ return (int) OS.RangeBase_Minimum (handle);
+}
+
+/**
+ * Returns the amount that the receiver's value will be
+ * modified by when the page increment/decrement areas
+ * are selected.
+ *
+ * @return the page increment
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getPageIncrement () {
+ checkWidget ();
+ return (int) OS.RangeBase_LargeChange (handle);
+}
+
+/**
+ * Returns the 'selection', which is the receiver's value.
+ *
+ * @return the selection
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getSelection () {
+ checkWidget ();
+ return (int) OS.RangeBase_Value (handle);
+}
+
+/**
+ * Returns the size of the receiver's thumb relative to the
+ * difference between its maximum and minimum values.
+ *
+ * @return the thumb value
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getThumb () {
+ checkWidget ();
+ return (int) OS.ScrollBar_ViewportSize (handle);
+}
+
+void HandleScroll (int sender, int e) {
+ if (!checkEvent (e)) return;
+ Event event = new Event ();
+ switch (OS.ScrollEventArgs_ScrollEventType (e)) {
+ case OS.ScrollEventType_EndScroll: return;
+ case OS.ScrollEventType_ThumbPosition: event.detail = SWT.NONE; break;
+ case OS.ScrollEventType_ThumbTrack: event.detail = SWT.DRAG; break;
+ case OS.ScrollEventType_First: event.detail = SWT.HOME; break;
+ case OS.ScrollEventType_Last: event.detail = SWT.END; break;
+ case OS.ScrollEventType_LargeIncrement: event.detail = SWT.PAGE_DOWN; break;
+ case OS.ScrollEventType_LargeDecrement: event.detail = SWT.PAGE_UP; break;
+ case OS.ScrollEventType_SmallIncrement: event.detail = SWT.ARROW_DOWN; break;
+ case OS.ScrollEventType_SmallDecrement: event.detail = SWT.ARROW_UP; break;
+ }
+ postEvent (SWT.Selection, event);
+}
+
+void hookEvents () {
+ super.hookEvents ();
+ int handler = OS.gcnew_ScrollEventHandler (jniRef, "HandleScroll");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.ScrollBar_Scroll (handle, handler);
+ OS.GCHandle_Free (handler);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the receiver's value changes.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #addSelectionListener
+ */
+public void removeSelectionListener (SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Selection, listener);
+ eventTable.unhook (SWT.DefaultSelection,listener);
+}
+
+/**
+ * Sets the amount that the receiver's value will be
+ * modified by when the up/down (or right/left) arrows
+ * are pressed to the argument, which must be at least
+ * one.
+ *
+ * @param value the new increment (must be greater than zero)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setIncrement (int value) {
+ checkWidget ();
+ if (value < 1) return;
+ OS.RangeBase_SmallChange (handle, value);
+}
+
+/**
+ * Sets the maximum. If this value is negative or less than or
+ * equal to the minimum, the value is ignored. If necessary, first
+ * the thumb and then the selection are adjusted to fit within the
+ * new range.
+ *
+ * @param value the new maximum, which must be greater than the current minimum
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setMaximum (int value) {
+ checkWidget ();
+ if (value < 0) return;
+ int minimum = (int) OS.RangeBase_Minimum (handle);
+ if (value <= minimum) return;
+ int viewSize = (int) OS.ScrollBar_ViewportSize (handle);
+ if (value - minimum < viewSize) {
+ viewSize = value - minimum;
+ OS.ScrollBar_ViewportSize (handle, viewSize);
+ }
+ OS.RangeBase_Maximum (handle, value - viewSize);
+}
+
+/**
+ * Sets the minimum value. If this value is negative or greater
+ * than or equal to the maximum, the value is ignored. If necessary,
+ * first the thumb and then the selection are adjusted to fit within
+ * the new range.
+ *
+ * @param value the new minimum
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setMinimum (int value) {
+ checkWidget ();
+ if (value < 0) return;
+ int viewSize = (int) OS.ScrollBar_ViewportSize (handle);
+ int maximum = (int) OS.RangeBase_Maximum (handle) + viewSize;
+ if (value >= maximum) return;
+ if (maximum - value < viewSize) {
+ viewSize = maximum - value;
+ OS.RangeBase_Maximum (handle, maximum - viewSize);
+ OS.ScrollBar_ViewportSize (handle, viewSize);
+ }
+ OS.RangeBase_Minimum (handle, value);
+}
+
+/**
+ * Sets the amount that the receiver's value will be
+ * modified by when the page increment/decrement areas
+ * are selected to the argument, which must be at least
+ * one.
+ *
+ * @param value the page increment (must be greater than zero)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setPageIncrement (int value) {
+ checkWidget ();
+ if (value < 1) return;
+ OS.RangeBase_LargeChange (handle, value);
+}
+
+
+
+/**
+ * Sets the 'selection', which is the receiver's
+ * value, to the argument which must be greater than or equal
+ * to zero.
+ *
+ * @param value the new selection (must be zero or greater)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSelection (int value) {
+ checkWidget ();
+ OS.RangeBase_Value (handle, value);
+}
+
+/**
+ * Sets the size of the receiver's thumb relative to the
+ * difference between its maximum and minimum values. This new
+ * value will be ignored if it is less than one, and will be
+ * clamped if it exceeds the receiver's current range.
+ *
+ * @param value the new thumb value, which must be at least one and not
+ * larger than the size of the current range
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setThumb (int value) {
+ checkWidget ();
+ if (value < 1) return;
+ int minimum = (int) OS.RangeBase_Minimum (handle);
+ int viewSize = (int) OS.ScrollBar_ViewportSize (handle);
+ int maximum = (int) OS.RangeBase_Maximum (handle) + viewSize;
+ value = Math.min (value, maximum - minimum);
+ OS.RangeBase_Maximum (handle, maximum - value);
+ OS.ScrollBar_ViewportSize (handle, value);
+}
+
+/**
+ * Sets the receiver's selection, minimum value, maximum
+ * value, thumb, increment and page increment all at once.
+ * <p>
+ * Note: This is similar to setting the values individually
+ * using the appropriate methods, but may be implemented in a
+ * more efficient fashion on some platforms.
+ * </p>
+ *
+ * @param selection the new selection value
+ * @param minimum the new minimum value
+ * @param maximum the new maximum value
+ * @param thumb the new thumb value
+ * @param increment the new increment value
+ * @param pageIncrement the new pageIncrement value
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setValues (int selection, int minimum, int maximum, int thumb, int increment, int pageIncrement) {
+ checkWidget();
+ if (minimum < 0) return;
+ if (maximum < 0) return;
+ if (thumb < 1) return;
+ if (increment < 1) return;
+ if (pageIncrement < 1) return;
+ thumb = Math.min (thumb, maximum - minimum);
+ OS.RangeBase_Minimum (handle, minimum);
+ OS.RangeBase_Maximum (handle, maximum - thumb);
+ OS.ScrollBar_ViewportSize (handle, thumb);
+ OS.RangeBase_Value (handle, selection);
+ OS.RangeBase_LargeChange (handle, pageIncrement);
+ OS.RangeBase_SmallChange (handle, increment);
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Spinner.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Spinner.java
new file mode 100644
index 0000000000..e480d72ff6
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Spinner.java
@@ -0,0 +1,751 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.events.*;
+
+/**
+ * Instances of this class are selectable user interface
+ * objects that allow the user to enter and modify numeric
+ * values.
+ * <p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>READ_ONLY, WRAP</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Selection, Modify</dd>
+ * </dl>
+ * </p><p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ *
+ * @since 3.1
+ */
+public class Spinner extends Composite {
+ int textHandle, upHandle, downHandle;
+ int increment, pageIncrement, digits, max, min, value;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#READ_ONLY
+ * @see SWT#WRAP
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Spinner (Composite parent, int style) {
+ super (parent, checkStyle (style));
+}
+
+Control [] _getChildren () {
+ return new Control [0];
+}
+
+static int checkStyle (int style) {
+ /*
+ * Even though it is legal to create this widget
+ * with scroll bars, they serve no useful purpose
+ * because they do not automatically scroll the
+ * widget's client area. The fix is to clear
+ * the SWT style.
+ */
+ return style & ~(SWT.H_SCROLL | SWT.V_SCROLL);
+}
+
+protected void checkSubclass () {
+ if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
+}
+
+int backgroundHandle () {
+ return textHandle;
+}
+
+int backgroundProperty () {
+ return OS.Control_BackgroundProperty ();
+}
+
+public Point computeSize (int wHint, int hHint, boolean changed) {
+ checkWidget ();
+ return super.computeSize (handle, wHint, hHint, changed);
+}
+
+int createArrow (int direction) {
+ int geometry = OS.gcnew_StreamGeometry ();
+ int context = OS.StreamGeometry_Open (geometry);
+ int start = 0, point = 0, end = 0;
+ switch (direction) {
+ case SWT.DOWN:
+ start = OS.gcnew_Point (0, 0);
+ point = OS.gcnew_Point (3, 3);
+ end = OS.gcnew_Point (6, 0);
+ break;
+ case SWT.UP:
+ start = OS.gcnew_Point (0, 3);
+ point = OS.gcnew_Point (3, 0);
+ end = OS.gcnew_Point (6, 3);
+ break;
+ }
+ OS.StreamGeometryContext_BeginFigure (context, start, true, true);
+ OS.StreamGeometryContext_LineTo (context, point, true, true);
+ OS.StreamGeometryContext_LineTo (context, end, true, true);
+ OS.StreamGeometryContext_Close (context);
+ int path = OS.gcnew_Path ();
+ OS.Path_Data (path, geometry);
+ int padding = OS.gcnew_Thickness (3, 0, 3, 0);
+ OS.FrameworkElement_Margin (path, padding);
+ int brush = OS.Brushes_Black ();
+ OS.Path_Fill (path, brush);
+ OS.FrameworkElement_HorizontalAlignment (path, OS.HorizontalAlignment_Center);
+ OS.FrameworkElement_VerticalAlignment (path, OS.VerticalAlignment_Center);
+ OS.GCHandle_Free (padding);
+ OS.GCHandle_Free (start);
+ OS.GCHandle_Free (point);
+ OS.GCHandle_Free (end);
+ OS.GCHandle_Free (brush);
+ OS.GCHandle_Free (context);
+ OS.GCHandle_Free (geometry);
+ return path;
+}
+
+void createHandle () {
+ handle = OS.gcnew_Grid ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ int row0 = OS.gcnew_RowDefinition ();
+ int row1 = OS.gcnew_RowDefinition ();
+ int rows = OS.Grid_RowDefinitions (handle);
+ OS.RowDefinitionCollection_Add (rows, row0);
+ OS.RowDefinitionCollection_Add (rows, row1);
+ int col0 = OS.gcnew_ColumnDefinition ();
+ int col1 = OS.gcnew_ColumnDefinition ();
+ int columns = OS.Grid_ColumnDefinitions (handle);
+ OS.ColumnDefinitionCollection_Add (columns, col0);
+ OS.ColumnDefinitionCollection_Add (columns, col1);
+ int gridChildren = OS.Panel_Children (handle);
+ textHandle = OS.gcnew_TextBox ();
+ if (textHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.Grid_SetRowSpan (textHandle, 2);
+ OS.UIElementCollection_Add (gridChildren, textHandle);
+ upHandle = OS.gcnew_RepeatButton ();
+ if (upHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ int upArrow = createArrow (SWT.UP);
+ OS.ContentControl_Content (upHandle, upArrow);
+ OS.Grid_SetColumn (upHandle, 1);
+ OS.UIElementCollection_Add (gridChildren, upHandle);
+ downHandle = OS.gcnew_RepeatButton ();
+ if (downHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ int downArrow = createArrow (SWT.DOWN);
+ OS.ContentControl_Content (downHandle, downArrow);
+ OS.Grid_SetColumn (downHandle, 1);
+ OS.Grid_SetRow (downHandle, 1);
+ OS.UIElementCollection_Add (gridChildren, downHandle);
+ int colWidth0 = OS.gcnew_GridLength (10, OS.GridUnitType_Star);
+ OS.ColumnDefinition_Width(col0, colWidth0);
+ int colWidth1 = OS.gcnew_GridLength (1, OS.GridUnitType_Auto);
+ OS.ColumnDefinition_Width (col1, colWidth1);
+ OS.GCHandle_Free (colWidth0);
+ OS.GCHandle_Free (colWidth1);
+ OS.GCHandle_Free (upArrow);
+ OS.GCHandle_Free (downArrow);
+ OS.GCHandle_Free (row0);
+ OS.GCHandle_Free (row1);
+ OS.GCHandle_Free (rows);
+ OS.GCHandle_Free (col0);
+ OS.GCHandle_Free (col1);
+ OS.GCHandle_Free (columns);
+ OS.GCHandle_Free (gridChildren);
+}
+
+void createWidget () {
+ super.createWidget();
+ increment = 1;
+ pageIncrement = 10;
+ digits = 0;
+ max = 100;
+ value = 0;
+ updateText ();
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the receiver's text is modified, by sending
+ * it one of the messages defined in the <code>ModifyListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ModifyListener
+ * @see #removeModifyListener
+ */
+public void addModifyListener (ModifyListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Modify, typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the control is selected, by sending
+ * it one of the messages defined in the <code>SelectionListener</code>
+ * interface.
+ * <p>
+ * <code>widgetSelected</code> is not called for texts.
+ * <code>widgetDefaultSelected</code> is typically called when ENTER is pressed in a single-line text.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #removeSelectionListener
+ * @see SelectionEvent
+ */
+public void addSelectionListener(SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Selection,typedListener);
+ addListener (SWT.DefaultSelection,typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the receiver's text is verified, by sending
+ * it one of the messages defined in the <code>VerifyListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see VerifyListener
+ * @see #removeVerifyListener
+ */
+void addVerifyListener (VerifyListener listener) {
+ checkWidget();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Verify, typedListener);
+}
+
+/**
+ * Copies the selected text.
+ * <p>
+ * The current selection is copied to the clipboard.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void copy () {
+ checkWidget ();
+ //TODO
+}
+
+/**
+ * Cuts the selected text.
+ * <p>
+ * The current selection is first copied to the
+ * clipboard and then deleted from the widget.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void cut () {
+ checkWidget ();
+ if ((style & SWT.READ_ONLY) != 0) return;
+ //TODO
+}
+
+/**
+ * Returns the number of decimal places used by the receiver.
+ *
+ * @return the digits
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getDigits () {
+ checkWidget ();
+ return digits;
+}
+
+/**
+ * Returns the amount that the receiver's value will be
+ * modified by when the up/down arrows are pressed.
+ *
+ * @return the increment
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getIncrement () {
+ checkWidget ();
+ return increment;
+}
+
+/**
+ * Returns the maximum value which the receiver will allow.
+ *
+ * @return the maximum
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getMaximum () {
+ checkWidget ();
+ return max;
+}
+
+/**
+ * Returns the minimum value which the receiver will allow.
+ *
+ * @return the minimum
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getMinimum () {
+ checkWidget ();
+ return min;
+}
+
+/**
+ * Returns the amount that the receiver's position will be
+ * modified by when the page up/down keys are pressed.
+ *
+ * @return the page increment
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getPageIncrement () {
+ checkWidget ();
+ return pageIncrement;
+}
+
+/**
+ * Returns the <em>selection</em>, which is the receiver's position.
+ *
+ * @return the selection
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getSelection () {
+ checkWidget ();
+ return value;
+}
+
+void HandleDownClick (int sender, int e) {
+ if (!checkEvent (e)) return;
+ value -= increment;
+ value = Math.max (value, min);
+ updateText ();
+ postEvent (SWT.Selection);
+}
+
+void HandleUpClick (int sender, int e) {
+ if (!checkEvent (e)) return;
+ value += increment;
+ value = Math.min (value, max);
+ updateText ();
+ postEvent (SWT.Selection);
+}
+
+void hookEvents () {
+ super.hookEvents();
+ //TEXT
+// int handler = OS.gcnew_TextCompositionEventHandler (jniRef, "HandlePreviewTextInput");
+// if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+// OS.UIElement_PreviewTextInput (handle, handler);
+// OS.GCHandle_Free (handler);
+// handler = OS.gcnew_ExecutedRoutedEventHandler(jniRef, "HandlePreviewExecutedRoutedEvent");
+// if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+// OS.CommandManager_AddPreviewExecutedHandler(handle, handler);
+// OS.GCHandle_Free(handler);
+// handler = OS.gcnew_TextChangedEventHandler (jniRef, "HandleTextChanged");
+// if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+// OS.TextBoxBase_TextChanged (handle, handler);
+// OS.GCHandle_Free(handler);
+ //BUTTON
+ int handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleDownClick");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.ButtonBase_Click (downHandle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleUpClick");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.ButtonBase_Click (upHandle, handler);
+ OS.GCHandle_Free (handler);
+}
+
+/**
+ * Pastes text from clipboard.
+ * <p>
+ * The selected text is deleted from the widget
+ * and new text inserted from the clipboard.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void paste () {
+ checkWidget ();
+ //TODO
+}
+
+void releaseHandle () {
+ super.releaseHandle();
+ OS.GCHandle_Free (textHandle);
+ OS.GCHandle_Free (upHandle);
+ OS.GCHandle_Free (downHandle);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the receiver's text is modified.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ModifyListener
+ * @see #addModifyListener
+ */
+public void removeModifyListener (ModifyListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Modify, listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the control is selected.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #addSelectionListener
+ */
+public void removeSelectionListener(SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Selection, listener);
+ eventTable.unhook (SWT.DefaultSelection,listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the control is verified.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see VerifyListener
+ * @see #addVerifyListener
+ */
+void removeVerifyListener (VerifyListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Verify, listener);
+}
+
+/**
+ * Sets the number of decimal places used by the receiver.
+ * <p>
+ * The digit setting is used to allow for floating point values in the receiver.
+ * For example, to set the selection to a floating point value of 1.37 call setDigits() with
+ * a value of 2 and setSelection() with a value of 137. Similarly, if getDigits() has a value
+ * of 2 and getSelection() returns 137 this should be interpreted as 1.37. This applies to all
+ * numeric APIs.
+ * </p>
+ *
+ * @param value the new digits (must be greater than or equal to zero)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the value is less than zero</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setDigits (int value) {
+ checkWidget ();
+ if (value < 0) error (SWT.ERROR_INVALID_ARGUMENT);
+ digits = value;
+}
+
+/**
+ * Sets the amount that the receiver's value will be
+ * modified by when the up/down arrows are pressed to
+ * the argument, which must be at least one.
+ *
+ * @param value the new increment (must be greater than zero)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setIncrement (int value) {
+ checkWidget ();
+ if (value < 1) return;
+ increment = value;
+}
+
+/**
+ * Sets the maximum value that the receiver will allow. This new
+ * value will be ignored if it is not greater than the receiver's current
+ * minimum value. If the new maximum is applied then the receiver's
+ * selection value will be adjusted if necessary to fall within its new range.
+ *
+ * @param value the new maximum, which must be greater than the current minimum
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setMaximum (int value) {
+ checkWidget ();
+ if (value < 0) return;
+ max = value;
+}
+
+/**
+ * Sets the minimum value that the receiver will allow. This new
+ * value will be ignored if it is negative or is not less than the receiver's
+ * current maximum value. If the new minimum is applied then the receiver's
+ * selection value will be adjusted if necessary to fall within its new range.
+ *
+ * @param value the new minimum, which must be nonnegative and less than the current maximum
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setMinimum (int value) {
+ checkWidget ();
+ if (value < 0) return;
+ min = value;
+}
+
+/**
+ * Sets the amount that the receiver's position will be
+ * modified by when the page up/down keys are pressed
+ * to the argument, which must be at least one.
+ *
+ * @param value the page increment (must be greater than zero)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setPageIncrement (int value) {
+ checkWidget ();
+ if (value < 1) return;
+ pageIncrement = value;
+}
+
+/**
+ * Sets the <em>selection</em>, which is the receiver's
+ * position, to the argument. If the argument is not within
+ * the range specified by minimum and maximum, it will be
+ * adjusted to fall within this range.
+ *
+ * @param value the new selection (must be zero or greater)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSelection (int value) {
+ checkWidget ();
+ this.value = value;
+ updateText();
+}
+
+/**
+ * Sets the receiver's selection, minimum value, maximum
+ * value, digits, increment and page increment all at once.
+ * <p>
+ * Note: This is similar to setting the values individually
+ * using the appropriate methods, but may be implemented in a
+ * more efficient fashion on some platforms.
+ * </p>
+ *
+ * @param selection the new selection value
+ * @param minimum the new minimum value
+ * @param maximum the new maximum value
+ * @param digits the new digits value
+ * @param increment the new increment value
+ * @param pageIncrement the new pageIncrement value
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public void setValues (int selection, int minimum, int maximum, int digits, int increment, int pageIncrement) {
+ checkWidget ();
+ if (minimum < 0) return;
+ if (maximum <= minimum) return;
+ if (digits < 0) return;
+ if (increment < 1) return;
+ if (pageIncrement < 1) return;
+ value = Math.min (Math.max (minimum, selection), maximum);
+ setIncrement (increment);
+ this.pageIncrement = pageIncrement;
+ this.digits = digits;
+ this.min = minimum;
+ this.max = maximum;
+ this.increment = increment;
+ this.pageIncrement = pageIncrement;
+ updateText();
+}
+
+void updateText () {
+ String valStr = digits == 0 ? value+"" : new Double (value/Math.pow(10, digits)).toString();
+ int strPtr = createDotNetString (valStr, false);
+ OS.TextBox_Text (textHandle, strPtr);
+ OS.GCHandle_Free (strPtr);
+}
+
+String verifyText (String string, int start, int end, Event keyEvent) {
+ Event event = new Event ();
+ event.text = string;
+ event.start = start;
+ event.end = end;
+ if (keyEvent != null) {
+ event.character = keyEvent.character;
+ event.keyCode = keyEvent.keyCode;
+ event.stateMask = keyEvent.stateMask;
+ }
+// int index = 0;
+// if (digits > 0) {
+// String decimalSeparator = getDecimalSeparator ();
+// index = string.indexOf (decimalSeparator);
+// if (index != -1) {
+// string = string.substring (0, index) + string.substring (index + 1);
+// }
+// index = 0;
+// }
+// while (index < string.length ()) {
+// if (!Character.isDigit (string.charAt (index))) break;
+// index++;
+// }
+// event.doit = index == string.length ();
+// if (!OS.IsUnicode && OS.IsDBLocale) {
+// event.start = mbcsToWcsPos (start);
+// event.end = mbcsToWcsPos (end);
+// }
+ //TODO
+ sendEvent (SWT.Verify, event);
+ if (!event.doit || isDisposed ()) return null;
+ return event.text;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TabFolder.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TabFolder.java
new file mode 100644
index 0000000000..cf91843f8a
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TabFolder.java
@@ -0,0 +1,634 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.wpf.*;
+
+/**
+ * Instances of this class implement the notebook user interface
+ * metaphor. It allows the user to select a notebook page from
+ * set of pages.
+ * <p>
+ * The item children that may be added to instances of this class
+ * must be of type <code>TabItem</code>.
+ * <code>Control</code> children are created and then set into a
+ * tab item using <code>TabItem#setControl</code>.
+ * </p><p>
+ * Note that although this class is a subclass of <code>Composite</code>,
+ * it does not make sense to set a layout on it.
+ * </p><p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>TOP, BOTTOM</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Selection</dd>
+ * </dl>
+ * <p>
+ * Note: Only one of the styles TOP and BOTTOM may be specified.
+ * </p><p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ */
+public class TabFolder extends Composite {
+ int parentingHandle;
+ int itemCount;
+ Control [] children;
+ int childCount;
+ boolean ignoreSelection;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public TabFolder (Composite parent, int style) {
+ super (parent, checkStyle (style));
+}
+
+int backgroundProperty () {
+ return OS.Control_BackgroundProperty ();
+}
+
+void addChild (Control widget) {
+ super.addChild (widget);
+ if (childCount == children.length) {
+ Control [] newChildren = new Control [childCount + 4];
+ System.arraycopy (children, 0, newChildren, 0, childCount);
+ children = newChildren;
+ }
+ children [childCount++] = widget;
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the receiver's selection changes, by sending
+ * it one of the messages defined in the <code>SelectionListener</code>
+ * interface.
+ * <p>
+ * When <code>widgetSelected</code> is called, the item field of the event object is valid.
+ * <code>widgetDefaultSelected</code> is not called.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #removeSelectionListener
+ * @see SelectionEvent
+ */
+public void addSelectionListener (SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener(listener);
+ addListener (SWT.Selection,typedListener);
+ addListener (SWT.DefaultSelection,typedListener);
+}
+
+static int checkStyle (int style) {
+ /*
+ * When the SWT.TOP style has not been set, force the
+ * tabs to be on the bottom for tab folders on PPC.
+ */
+// if (OS.IsPPC) {
+// if ((style & SWT.TOP) == 0) style |= SWT.BOTTOM;
+// }
+ style = checkBits (style, SWT.TOP, SWT.BOTTOM, 0, 0, 0, 0);
+
+ /*
+ * Even though it is legal to create this widget
+ * with scroll bars, they serve no useful purpose
+ * because they do not automatically scroll the
+ * widget's client area. The fix is to clear
+ * the SWT style.
+ */
+ return style & ~(SWT.H_SCROLL | SWT.V_SCROLL);
+}
+
+protected void checkSubclass () {
+ if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
+}
+
+int clientHandle () {
+ int index = OS.Selector_SelectedIndex (handle);
+ if (index != -1) {
+ int items = OS.ItemsControl_Items (handle);
+ TabItem item = getItem (items, index);
+ OS.GCHandle_Free (items);
+ return item.contentHandle;
+ }
+ return handle;
+}
+
+public Point computeSize (int wHint, int hHint, boolean changed) {
+ Point size = super.computeSize (wHint, hHint, changed);
+ Point sizeTabFolder = super.computeSize (handle, wHint, hHint, changed);
+ return new Point (sizeTabFolder.x + 1, size.y + sizeTabFolder.y);
+}
+
+void createItem (TabItem item, int index) {
+ if (!(0 <= index && index <= itemCount)) error (SWT.ERROR_INVALID_RANGE);
+ item.createWidget ();
+ int items = OS.ItemsControl_Items (handle);
+ OS.ItemCollection_Insert (items, index, item.topHandle ());
+ int count = OS.ItemCollection_Count (items);
+ OS.GCHandle_Free (items);
+ if (itemCount == count) error (SWT.ERROR_ITEM_NOT_ADDED);
+ itemCount++;
+}
+
+void createHandle () {
+ parentingHandle = OS.gcnew_Canvas ();
+ if (parentingHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ handle = OS.gcnew_TabControl ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ if ((style & SWT.BOTTOM) != 0) OS.TabControl_TabStripPlacement (handle, OS.Dock_Bottom);
+ int children = OS.Panel_Children (parentingHandle);
+ OS.UIElementCollection_Add (children, handle);
+ OS.GCHandle_Free (children);
+ OS.Canvas_SetLeft (handle, 0);
+ OS.Canvas_SetTop (handle, 0);
+}
+
+void createWidget () {
+ super.createWidget ();
+ children = new Control [4];
+}
+
+void deregister () {
+ super.deregister ();
+ display.removeWidget (parentingHandle);
+}
+
+void destroyItem (TabItem item) {
+ int items = OS.ItemsControl_Items (handle);
+ OS.ItemCollection_Remove (items, item.topHandle ());
+ int count = OS.ItemCollection_Count (items);
+ OS.GCHandle_Free (items);
+ if (itemCount == count) error (SWT.ERROR_ITEM_NOT_REMOVED);
+ itemCount--;
+}
+
+Control findThemeControl () {
+ return this;
+}
+
+Control [] _getChildren () {
+ // return children in reverse order.
+ Control[] result = new Control [childCount];
+ for (int i =0; i < childCount; i++) {
+ result [childCount - i - 1] = children [i];
+ }
+ return result;
+}
+
+/**
+ * Returns the item at the given, zero-relative index in the
+ * receiver. Throws an exception if the index is out of range.
+ *
+ * @param index the index of the item to return
+ * @return the item at the given index
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public TabItem getItem (int index) {
+ checkWidget ();
+ if (!(0 <= index && index < itemCount)) error (SWT.ERROR_INVALID_RANGE);
+ int items = OS.ItemsControl_Items (handle);
+ TabItem item = getItem (items, index);
+ OS.GCHandle_Free (items);
+ return item;
+}
+
+TabItem getItem (int items, int index) {
+ int item = OS.ItemCollection_GetItemAt (items, index);
+ TabItem result = (TabItem) display.getWidget (item);
+ OS.GCHandle_Free(item);
+ return result;
+}
+
+/**
+ * Returns the number of items contained in the receiver.
+ *
+ * @return the number of items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getItemCount () {
+ return itemCount;
+}
+
+/**
+ * Returns an array of <code>TabItem</code>s which are the items
+ * in the receiver.
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its list of items, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ *
+ * @return the items in the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public TabItem [] getItems () {
+ checkWidget ();
+ TabItem [] result = new TabItem [itemCount];
+ int items = OS.ItemsControl_Items (handle);
+ for (int i=0; i<itemCount; i++) {
+ result [i] = getItem (items, i);
+ }
+ OS.GCHandle_Free (items);
+ return result;
+}
+
+/**
+ * Returns an array of <code>TabItem</code>s that are currently
+ * selected in the receiver. An empty array indicates that no
+ * items are selected.
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its selection, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ * @return an array representing the selection
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public TabItem [] getSelection () {
+ checkWidget ();
+ int index = OS.Selector_SelectedIndex (handle);
+ if (index == -1) return new TabItem [0];
+ int items = OS.ItemsControl_Items (handle);
+ TabItem item = getItem (items, index);
+ OS.GCHandle_Free (items);
+ return new TabItem [] {item};
+}
+
+/**
+ * Returns the zero-relative index of the item which is currently
+ * selected in the receiver, or -1 if no item is selected.
+ *
+ * @return the index of the selected item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getSelectionIndex () {
+ checkWidget ();
+ return OS.Selector_SelectedIndex (handle);
+}
+
+boolean hasItems () {
+ return true;
+}
+
+void HandleSelectionChange (int sender, int e) {
+ if (!checkEvent (e)) return;
+ if (ignoreSelection) return;
+ int selectedItem = OS.Selector_SelectedItem (handle);
+ if (selectedItem == 0) return;
+ TabItem item = (TabItem) display.getWidget (selectedItem);
+ OS.GCHandle_Free (selectedItem);
+ Event event = new Event ();
+ event.item = item;
+ postEvent (SWT.Selection, event);
+}
+
+void hookEvents () {
+ super.hookEvents ();
+ int handler = OS.gcnew_SelectionChangedEventHandler (jniRef, "HandleSelectionChange");
+ OS.Selector_SelectionChanged (handle, handler);
+ OS.GCHandle_Free (handler);
+}
+
+/**
+ * Searches the receiver's list starting at the first item
+ * (index 0) until an item is found that is equal to the
+ * argument, and returns the index of that item. If no item
+ * is found, returns -1.
+ *
+ * @param item the search item
+ * @return the index of the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int indexOf (TabItem item) {
+ checkWidget ();
+ if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int items = OS.ItemsControl_Items (handle);
+ int index = OS.ItemCollection_IndexOf (items, item.topHandle ());
+ OS.GCHandle_Free (items);
+ return index;
+}
+
+boolean mnemonicHit (char key) {
+ //TODO
+ return false;
+}
+
+boolean mnemonicMatch (char key) {
+ boolean found = false;
+ int items = OS.ItemsControl_Items (handle);
+ for (int i=0; i<itemCount; i++) {
+ TabItem item = getItem (items, i);
+ if (mnemonicMatch (item.textHandle, key)) {
+ found = true;
+ break;
+ }
+ }
+ OS.GCHandle_Free (items);
+ return found;
+}
+
+int parentingHandle() {
+ return parentingHandle;
+}
+
+void register () {
+ super.register ();
+ display.addWidget (parentingHandle, this);
+}
+
+void releaseChildren (boolean destroy) {
+ int items = OS.ItemsControl_Items (handle);
+ for (int i=0; i<itemCount; i++) {
+ TabItem item = getItem (items, i);
+ if (item != null && !item.isDisposed ()) item.release (false);
+ }
+ OS.GCHandle_Free (items);
+ super.releaseChildren (destroy);
+}
+
+void removeChild (Control control) {
+ super.removeChild (control);//TODO MAKE SURE removeControl gets called first
+ int index = 0;
+ while (index < childCount) {
+ if (children [index] == control) break;
+ index++;
+ }
+ if (index == childCount) return;
+ System.arraycopy(children, index+1, children, index, --childCount - index);
+ children [childCount] = null;
+}
+
+void releaseHandle() {
+ super.releaseHandle ();
+ if (parentingHandle != 0) OS.GCHandle_Free (parentingHandle);
+ parentingHandle = 0;
+}
+
+void removeControl (Control control) {
+ super.removeControl (control);
+ int items = OS.ItemsControl_Items (handle);
+ for (int i=0; i<itemCount; i++) {
+ TabItem item = getItem (items, i);
+ if (item.control == control) {
+ item.setControl (null);
+ break;
+ }
+ }
+ OS.GCHandle_Free (items);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the receiver's selection changes.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #addSelectionListener
+ */
+public void removeSelectionListener (SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Selection, listener);
+ eventTable.unhook (SWT.DefaultSelection,listener);
+}
+
+int setBounds (int x, int y, int width, int height, int flags) {
+ int result = super.setBounds (x, y, width, height, flags);
+ if ((result & RESIZED) != 0) {
+ OS.FrameworkElement_Height (handle, height);
+ OS.FrameworkElement_Width (handle, width);
+ int selectedItem = OS.Selector_SelectedItem (handle);
+ if (selectedItem != 0) {
+ TabItem item = (TabItem) display.getWidget (selectedItem);
+ OS.GCHandle_Free (selectedItem);
+ Control control = item.control;
+ if (control != null && !control.isDisposed ()) {
+ control.setBounds (getClientArea ());
+ }
+ }
+ }
+ return result;
+}
+
+void setForegroundBrush (int brush) {
+ if (brush != 0) {
+ OS.Control_Foreground (handle, brush);
+ } else {
+ int property = OS.Control_ForegroundProperty ();
+ OS.DependencyObject_ClearValue (handle, property);
+ OS.GCHandle_Free (property);
+ }
+}
+
+/**
+ * Sets the receiver's selection to the given item.
+ * The current selected is first cleared, then the new item is
+ * selected.
+ *
+ * @param item the item to select
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the item is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public void setSelection (TabItem item) {
+ checkWidget ();
+ if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
+ setSelection (new TabItem [] {item});
+}
+
+/**
+ * Sets the receiver's selection to be the given array of items.
+ * The current selected is first cleared, then the new items are
+ * selected.
+ *
+ * @param items the array of items
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the items array is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSelection (TabItem [] items) {
+ checkWidget ();
+ if (items == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (items.length == 0) {
+ setSelection (-1, false);
+ } else {
+ for (int i=items.length-1; i>=0; --i) {
+ int index = indexOf (items [i]);
+ if (index != -1) setSelection (index, false);
+ }
+ }
+}
+
+/**
+ * Selects the item at the given zero-relative index in the receiver.
+ * If the item at the index was already selected, it remains selected.
+ * The current selection is first cleared, then the new items are
+ * selected. Indices that are out of range are ignored.
+ *
+ * @param index the index of the item to select
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSelection (int index) {
+ checkWidget ();
+ if (!(0 <= index && index < itemCount)) return;
+ setSelection (index, false);
+}
+
+void setSelection (int index, boolean notify) {
+ int oldIndex = OS.Selector_SelectedIndex (handle);
+ if (oldIndex != -1) {
+ int items = OS.ItemsControl_Items (handle);
+ TabItem item = getItem (items, oldIndex);
+ OS.GCHandle_Free (items);
+ Control control = item.control;
+ if (control != null && !control.isDisposed ()) {
+ control.setVisible (false);
+ }
+ }
+ ignoreSelection = true;
+ OS.Selector_SelectedIndex (handle, index);
+ ignoreSelection = false;
+ int newIndex = OS.Selector_SelectedIndex (handle);
+ if (newIndex != -1) {
+ int items = OS.ItemsControl_Items (handle);
+ TabItem item = getItem (items, newIndex);
+ OS.GCHandle_Free (items);
+ Control control = item.control;
+ if (control != null && !control.isDisposed ()) {
+// control.setBounds (getClientArea ());
+ control.setVisible (true);
+ }
+ if (notify) {
+ Event event = new Event ();
+ event.item = item;
+ sendEvent (SWT.Selection, event);
+ }
+ }
+}
+
+int topHandle() {
+ return parentingHandle;
+}
+
+boolean traversePage (boolean next) {
+// GTK: OS.g_signal_emit_by_name (handle, OS.change_current_page, next ? 1 : -1);
+ int count = getItemCount ();
+ if (count <= 1) return false;
+ int index = getSelectionIndex ();
+ if (index == -1) {
+ index = 0;
+ } else {
+ int offset = (next) ? 1 : -1;
+ index = (index + offset + count) % count;
+ }
+ setSelection (index, true);
+ if (index == getSelectionIndex ()) {
+// OS.SendMessage (handle, OS.WM_CHANGEUISTATE, OS.UIS_INITIALIZE, 0);
+ return true;
+ }
+ return false;
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TabItem.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TabItem.java
new file mode 100644
index 0000000000..1f512507db
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TabItem.java
@@ -0,0 +1,361 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Instances of this class represent a selectable user interface object
+ * corresponding to a tab for a page in a tab folder.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>(none)</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * <p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ */
+
+public class TabItem extends Item {
+ TabFolder parent;
+ Control control;
+ String toolTipText;
+ int imageHandle, textHandle, contentHandle;
+
+
+/**
+ * Constructs a new instance of this class given its parent
+ * (which must be a <code>TabFolder</code>) and a style value
+ * describing its behavior and appearance. The item is added
+ * to the end of the items maintained by its parent.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public TabItem (TabFolder parent, int style) {
+ super (parent, style);
+ this.parent = parent;
+ parent.createItem (this, parent.getItemCount ());
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * (which must be a <code>TabFolder</code>), a style value
+ * describing its behavior and appearance, and the index
+ * at which to place it in the items maintained by its parent.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ * @param index the zero-relative index to store the receiver in its parent
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public TabItem (TabFolder parent, int style, int index) {
+ super (parent, style);
+ this.parent = parent;
+ parent.createItem (this, index);
+}
+
+protected void checkSubclass () {
+ if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
+}
+
+void createHandle () {
+ handle = OS.gcnew_TabItem ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ imageHandle = OS.gcnew_Image ();
+ if (imageHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.Image_Stretch (imageHandle, OS.Stretch_None);
+ int thickness = OS.gcnew_Thickness (0, 0, 3, 0);
+ if (thickness == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.FrameworkElement_Margin (imageHandle, thickness);
+ OS.GCHandle_Free (thickness);
+ OS.UIElement_Visibility (imageHandle, OS.Visibility_Collapsed);
+ textHandle = OS.gcnew_AccessText ();
+ if (textHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.FrameworkElement_VerticalAlignment (textHandle, OS.VerticalAlignment_Center);
+ int panel = OS.gcnew_StackPanel ();
+ if (panel == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.StackPanel_Orientation (panel, OS.Orientation_Horizontal);
+ thickness = OS.gcnew_Thickness (1, 1, 1, 1);
+ if (thickness == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.FrameworkElement_Margin (panel, thickness);
+ OS.GCHandle_Free(thickness);
+ int children = OS.Panel_Children (panel);
+ OS.UIElementCollection_Add (children, imageHandle);
+ OS.UIElementCollection_Add (children, textHandle);
+ OS.HeaderedContentControl_Header (handle, panel);
+ OS.GCHandle_Free (children);
+ OS.GCHandle_Free (panel);
+ contentHandle = OS.gcnew_Canvas ();
+ if (contentHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.ContentControl_Content (handle, contentHandle);
+}
+
+void deregister () {
+ display.removeWidget (handle);
+}
+
+void destroyWidget () {
+ parent.destroyItem (this);
+ releaseHandle ();
+}
+
+/**
+ * Returns the control that is used to fill the client area of
+ * the tab folder when the user selects the tab item. If no
+ * control has been set, return <code>null</code>.
+ * <p>
+ * @return the control
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Control getControl () {
+ checkWidget();
+ return control;
+}
+
+/**
+ * Returns the receiver's parent, which must be a <code>TabFolder</code>.
+ *
+ * @return the receiver's parent
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public TabFolder getParent () {
+ checkWidget();
+ return parent;
+}
+
+Control getWidgetControl () {
+ return parent;
+}
+
+/**
+ * Returns the receiver's tool tip text, or null if it has
+ * not been set.
+ *
+ * @return the receiver's tool tip text
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String getToolTipText () {
+ checkWidget();
+ return toolTipText;
+}
+
+void HandleSizeChanged (int sender, int e) {
+ if (!checkEvent (e)) return;
+ if (control == null) return;
+ control.setBounds (parent.getClientArea ());
+}
+
+void hookEvents () {
+ super.hookEvents ();
+ int handler = OS.gcnew_SizeChangedEventHandler (jniRef, "HandleSizeChanged");
+ OS.FrameworkElement_SizeChanged (contentHandle, handler);
+ OS.GCHandle_Free (handler);
+}
+
+void register() {
+ display.addWidget (handle, this);
+}
+
+void releaseHandle () {
+ super.releaseHandle ();
+ if (handle != 0) OS.GCHandle_Free (handle);
+ handle = 0;
+ parent = null;
+ if (textHandle != 0) OS.GCHandle_Free (textHandle);
+ textHandle = 0;
+ if (imageHandle !=0 )OS.GCHandle_Free (imageHandle);
+ imageHandle = 0;
+ if (contentHandle != 0) OS.GCHandle_Free (contentHandle);
+ contentHandle = 0;
+}
+
+void releaseParent () {
+ super.releaseParent ();
+ int index = parent.indexOf (this);
+ if (index == parent.getSelectionIndex ()) {
+ if (control != null) control.setVisible (false);
+ }
+}
+
+void releaseWidget () {
+ super.releaseWidget ();
+ control = null;
+ toolTipText = null;
+ deregister ();
+}
+
+/**
+ * Sets the control that is used to fill the client area of
+ * the tab folder when the user selects the tab item.
+ * <p>
+ * @param control the new control (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li>
+ * <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setControl (Control control) {
+ checkWidget();
+ if (control != null) {
+ if (control.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (control.parent != parent) error (SWT.ERROR_INVALID_PARENT);
+ }
+ Control oldControl = this.control, newControl = control;
+ this.control = control;
+ int children = OS.Panel_Children (contentHandle);
+ int parentHandle = parent.parentingHandle ();
+ int parentChildren = OS.Panel_Children (parentHandle);
+ if (newControl != null) {
+ int topHandle = newControl.topHandle ();
+ OS.UIElementCollection_Remove (parentChildren, topHandle);
+ OS.UIElementCollection_Add (children, topHandle);
+ }
+ if (oldControl != null) {
+ int topHandle = oldControl.topHandle ();
+ OS.UIElementCollection_Remove (children, topHandle);
+ OS.UIElementCollection_Add (parentChildren, topHandle);
+ }
+ OS.GCHandle_Free (children);
+ OS.GCHandle_Free (parentChildren);
+}
+
+public void setImage (Image image) {
+ checkWidget();
+ super.setImage (image);
+ OS.Image_Source (imageHandle, image != null ? image.handle : 0);
+ OS.UIElement_Visibility (imageHandle, image != null ? OS.Visibility_Visible : OS.Visibility_Collapsed);
+}
+
+/**
+ * Sets the receiver's text. The string may include
+ * the mnemonic character.
+ * </p>
+ * <p>
+ * Mnemonics are indicated by an '&amp;' that causes the next
+ * character to be the mnemonic. When the user presses a
+ * key sequence that matches the mnemonic, a selection
+ * event occurs. On most platforms, the mnemonic appears
+ * underlined but may be emphasised in a platform specific
+ * manner. The mnemonic indicator character '&amp;' can be
+ * escaped by doubling it in the string, causing a single
+ * '&amp;' to be displayed.
+ * </p>
+ *
+ * @param string the new text
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ */
+public void setText (String string) {
+ checkWidget();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (string.equals (text)) return;
+ super.setText (string);
+ int strPtr = createDotNetString (string, true);
+ if (strPtr == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.AccessText_Text (textHandle, strPtr);
+ OS.GCHandle_Free (strPtr);
+// OS.UIElement_Visibility (textHandle, string.length() == 0 ? OS.Visibility_Collapsed : OS.Visibility_Visible);
+}
+
+/**
+ * Sets the receiver's tool tip text to the argument, which
+ * may be null indicating that no tool tip text should be shown.
+ *
+ * @param string the new tool tip text (or null)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setToolTipText (String string) {
+ checkWidget();
+ toolTipText = string;
+ int strPtr = createDotNetString (string, false);
+ int header = OS.HeaderedContentControl_Header (handle);
+ OS.FrameworkElement_ToolTip (header, strPtr);
+ if (strPtr != 0) OS.GCHandle_Free (strPtr);
+ OS.GCHandle_Free (header);
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Table.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Table.java
new file mode 100644
index 0000000000..2d19ba9246
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Table.java
@@ -0,0 +1,2314 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.events.*;
+
+/**
+ * Instances of this class implement a selectable user interface
+ * object that displays a list of images and strings and issues
+ * notification when selected.
+ * <p>
+ * The item children that may be added to instances of this class
+ * must be of type <code>TableItem</code>.
+ * </p><p>
+ * Style <code>VIRTUAL</code> is used to create a <code>Table</code> whose
+ * <code>TableItem</code>s are to be populated by the client on an on-demand basis
+ * instead of up-front. This can provide significant performance improvements for
+ * tables that are very large or for which <code>TableItem</code> population is
+ * expensive (for example, retrieving values from an external source).
+ * </p><p>
+ * Here is an example of using a <code>Table</code> with style <code>VIRTUAL</code>:
+ * <code><pre>
+ * final Table table = new Table (parent, SWT.VIRTUAL | SWT.BORDER);
+ * table.setItemCount (1000000);
+ * table.addListener (SWT.SetData, new Listener () {
+ * public void handleEvent (Event event) {
+ * TableItem item = (TableItem) event.item;
+ * int index = table.indexOf (item);
+ * item.setText ("Item " + index);
+ * System.out.println (item.getText ());
+ * }
+ * });
+ * </pre></code>
+ * </p><p>
+ * Note that although this class is a subclass of <code>Composite</code>,
+ * it does not make sense to add <code>Control</code> children to it,
+ * or set a layout on it.
+ * </p><p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>SINGLE, MULTI, CHECK, FULL_SELECTION, HIDE_SELECTION, VIRTUAL</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Selection, DefaultSelection, SetData, MeasureItem, EraseItem, PaintItem</dd>
+ * </dl>
+ * </p><p>
+ * Note: Only one of the styles SINGLE, and MULTI may be specified.
+ * </p><p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ */
+
+public class Table extends Composite {
+ int gridViewHandle, parentingHandle;
+ int columnCount, itemCount;
+ boolean ignoreSelection;
+
+ static final String CHECKBOX_PART_NAME = "SWT_PART_CHECKBOX";
+ static final String IMAGE_PART_NAME = "SWT_PART_IMAGE";
+ static final String TEXT_PART_NAME = "SWT_PART_TEXT";
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#SINGLE
+ * @see SWT#MULTI
+ * @see SWT#CHECK
+ * @see SWT#FULL_SELECTION
+ * @see SWT#HIDE_SELECTION
+ * @see SWT#VIRTUAL
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Table (Composite parent, int style) {
+ super (parent, checkStyle (style));
+}
+
+void _addListener (int eventType, Listener listener) {
+ super._addListener (eventType, listener);
+ switch (eventType) {
+ case SWT.MeasureItem:
+ case SWT.EraseItem:
+ case SWT.PaintItem:
+ //TODO
+ break;
+ }
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the receiver's selection changes, by sending
+ * it one of the messages defined in the <code>SelectionListener</code>
+ * interface.
+ * <p>
+ * When <code>widgetSelected</code> is called, the item field of the event object is valid.
+ * If the receiver has <code>SWT.CHECK</code> style set and the check selection changes,
+ * the event object detail field contains the value <code>SWT.CHECK</code>.
+ * <code>widgetDefaultSelected</code> is typically called when an item is double-clicked.
+ * The item field of the event object is valid for default selection, but the detail field is not used.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #removeSelectionListener
+ * @see SelectionEvent
+ */
+public void addSelectionListener (SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Selection,typedListener);
+ addListener (SWT.DefaultSelection,typedListener);
+}
+
+int backgroundProperty () {
+ return OS.Control_BackgroundProperty ();
+}
+
+public Point computeSize (int wHint, int hHint, boolean changed) {
+ checkWidget ();
+ return super.computeSize (wHint, hHint, changed);
+}
+
+TableItem converterItem (int value) {
+ int content = OS.IntPtr_ToInt32 (value);
+ TableItem item;
+ if (content > 0) {
+ item = (TableItem) OS.JNIGetObject (content);
+ } else {
+ int items = OS.ItemsControl_Items (handle);
+ item = getItem (items, -content, true);
+ OS.GCHandle_Free (items);
+ }
+ checkData (item);
+ return item;
+}
+
+int converterColumnIndex (int parameter) {
+ int columnIndex = 0;
+ if (parameter != 0) {
+ TableColumn column = (TableColumn) OS.JNIGetObject (parameter);
+ columnIndex = indexOf(column);
+ }
+ return columnIndex;
+}
+
+int ConvertImage (int value, int targetType, int parameter, int culture) {
+ TableItem item = converterItem (value);
+ int columnIndex = converterColumnIndex (parameter);
+ int result = 0;
+ if (item.images != null && item.images [columnIndex] != null) {
+ result = item.images [columnIndex].handle;
+ }
+ return result;
+}
+
+int ConvertText (int value, int targetType, int parameter, int culture) {
+ TableItem item = converterItem (value);
+ int columnIndex = converterColumnIndex (parameter);
+ int result = 0;
+ if (item.strings != null) {
+ if (item.stringHandle != null && item.stringHandle [columnIndex] != 0) {
+ result = item.stringHandle [columnIndex];
+ } else {
+ if (item.stringHandle == null) {
+ int count = Math.max (1, columnCount);
+ item.stringHandle = new int [count];
+ }
+ item.stringHandle [columnIndex] = result = createDotNetString (item.strings [columnIndex], false);
+ }
+ }
+ return result;
+}
+
+boolean checkData (TableItem item) {
+ if ((style & SWT.VIRTUAL) == 0) return true;
+ if (!item.cached) {
+ item.cached = true;
+ Event event = new Event ();
+ event.item = item;
+ event.index = indexOf (item);
+ sendEvent (SWT.SetData, event);
+ //widget could be disposed at this point
+ if (isDisposed () || item.isDisposed ()) return false;
+ }
+ return true;
+}
+
+static int checkStyle (int style) {
+ /*
+ * To be compatible with Windows, force the H_SCROLL
+ * and V_SCROLL style bits. On Windows, it is not
+ * possible to create a table without scroll bars.
+ */
+ style |= SWT.H_SCROLL | SWT.V_SCROLL;
+ /* WPF is always FULL_SELECTION */
+ style |= SWT.FULL_SELECTION;
+ return checkBits (style, SWT.SINGLE, SWT.MULTI, 0, 0, 0, 0);
+}
+
+protected void checkSubclass () {
+ if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
+}
+
+/**
+ * Clears the item at the given zero-relative index in the receiver.
+ * The text, icon and other attributes of the item are set to the default
+ * value. If the table was created with the <code>SWT.VIRTUAL</code> style,
+ * these attributes are requested again as needed.
+ *
+ * @param index the index of the item to clear
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SWT#VIRTUAL
+ * @see SWT#SetData
+ *
+ * @since 3.0
+ */
+public void clear (int index) {
+ checkWidget ();
+ if (!(0 <= index && index < itemCount)) error (SWT.ERROR_INVALID_RANGE);
+ int items = OS.ItemsControl_Items (handle);
+ TableItem item = getItem (items, index, false);
+ OS.GCHandle_Free (items);
+ if (item != null) item.clear ();
+}
+
+/**
+ * Removes the items from the receiver which are between the given
+ * zero-relative start and end indices (inclusive). The text, icon
+ * and other attributes of the items are set to their default values.
+ * If the table was created with the <code>SWT.VIRTUAL</code> style,
+ * these attributes are requested again as needed.
+ *
+ * @param start the start index of the item to clear
+ * @param end the end index of the item to clear
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if either the start or end are not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SWT#VIRTUAL
+ * @see SWT#SetData
+ *
+ * @since 3.0
+ */
+public void clear (int start, int end) {
+ checkWidget ();
+ checkWidget ();
+ if (start > end) return;
+ if (!(0 <= start && start <= end && end < itemCount)) {
+ error (SWT.ERROR_INVALID_RANGE);
+ }
+ if (start == 0 && end == itemCount - 1) {
+ clearAll ();
+ } else {
+ int items = OS.ItemsControl_Items (handle);
+ for (int i=start; i<=end; i++) {
+ TableItem item = getItem (items, i, false);
+ if (item != null) item.clear ();
+ }
+ OS.GCHandle_Free (items);
+ }
+}
+
+/**
+ * Clears the items at the given zero-relative indices in the receiver.
+ * The text, icon and other attributes of the items are set to their default
+ * values. If the table was created with the <code>SWT.VIRTUAL</code> style,
+ * these attributes are requested again as needed.
+ *
+ * @param indices the array of indices of the items
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * <li>ERROR_NULL_ARGUMENT - if the indices array is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SWT#VIRTUAL
+ * @see SWT#SetData
+ *
+ * @since 3.0
+ */
+public void clear (int [] indices) {
+ checkWidget ();
+ if (indices == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (indices.length == 0) return;
+ for (int i=0; i<indices.length; i++) {
+ if (!(0 <= indices [i] && indices [i] < itemCount)) {
+ error (SWT.ERROR_INVALID_RANGE);
+ }
+ }
+ int items = OS.ItemsControl_Items (handle);
+ for (int i=0; i<indices.length; i++) {
+ int index = indices [i];
+ TableItem item = getItem (items, index, false);
+ if (item != null) item.clear ();
+ }
+ OS.GCHandle_Free (items);
+}
+
+/**
+ * Clears all the items in the receiver. The text, icon and other
+ * attributes of the items are set to their default values. If the
+ * table was created with the <code>SWT.VIRTUAL</code> style, these
+ * attributes are requested again as needed.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SWT#VIRTUAL
+ * @see SWT#SetData
+ *
+ * @since 3.0
+ */
+public void clearAll () {
+ checkWidget ();
+ int items = OS.ItemsControl_Items (handle);
+ for (int i=0; i<itemCount; i++) {
+ TableItem item = getItem (items, i, false);
+ if (item != null) item.clear ();
+ }
+ OS.GCHandle_Free (items);
+}
+
+int createCellTemplate (int columnJniRef, int index) {
+ int template = OS.gcnew_DataTemplate ();
+ int stackPanelType = OS.StackPanel_typeid ();
+ int stackPanelNode = OS.gcnew_FrameworkElementFactory (stackPanelType);
+ if (index == 0 && (style & SWT.CHECK) != 0) {
+ int checkBoxType = OS.CheckBox_typeid ();
+ int checkBoxName = createDotNetString (CHECKBOX_PART_NAME, false);
+ int checkBoxNode = OS.gcnew_FrameworkElementFactory (checkBoxType, checkBoxName);
+ int verticalAlignmentProperty = OS.FrameworkElement_VerticalAlignmentProperty ();
+ OS.FrameworkElementFactory_SetValueVerticalAlignment (checkBoxNode, verticalAlignmentProperty, OS.VerticalAlignment_Center);
+ int marginProperty = OS.FrameworkElement_MarginProperty ();
+ int thickness = OS.gcnew_Thickness (0,0,4,0);
+ OS.FrameworkElementFactory_SetValue (checkBoxNode, marginProperty, thickness);
+ OS.FrameworkElementFactory_AppendChild (stackPanelNode, checkBoxNode);
+
+// int checkProperty = OS.ToggleButton_IsCheckedProperty ();
+// OS.FrameworkElementFactory_SetBinding (checkBoxNode, checkProperty, binding);
+// OS.GCHandle_Free (checkProperty);
+
+ OS.GCHandle_Free (thickness);
+ OS.GCHandle_Free (marginProperty);
+ OS.GCHandle_Free (verticalAlignmentProperty);
+ OS.GCHandle_Free (checkBoxName);
+ OS.GCHandle_Free (checkBoxNode);
+ OS.GCHandle_Free (checkBoxType);
+ }
+ int textType = OS.TextBlock_typeid ();
+ int textName = createDotNetString (TEXT_PART_NAME, false);
+ int textNode = OS.gcnew_FrameworkElementFactory (textType, textName);
+ int imageType = OS.Image_typeid ();
+ int imageName = createDotNetString (IMAGE_PART_NAME, false);
+ int imageNode = OS.gcnew_FrameworkElementFactory (imageType, imageName);
+ int marginProperty = OS.FrameworkElement_MarginProperty ();
+ int thickness = OS.gcnew_Thickness (0,0,4,0);
+ OS.FrameworkElementFactory_SetValue (imageNode, marginProperty, thickness);
+ int orientationProperty = OS.StackPanel_OrientationProperty ();
+ OS.FrameworkElementFactory_SetValueOrientation (stackPanelNode, orientationProperty, OS.Orientation_Horizontal);
+ OS.FrameworkElementFactory_AppendChild (stackPanelNode, imageNode);
+ OS.FrameworkElementFactory_AppendChild (stackPanelNode, textNode);
+ OS.FrameworkTemplate_VisualTree (template, stackPanelNode);
+
+ //bindings
+ int textBinding = OS.gcnew_Binding ();
+ int textConverter = OS.gcnew_SWTCellConverter (jniRef, "ConvertText");
+ OS.Binding_Converter (textBinding, textConverter);
+ OS.Binding_ConverterParameter (textBinding, columnJniRef);
+ int textProperty = OS.TextBlock_TextProperty ();
+ OS.FrameworkElementFactory_SetBinding (textNode, textProperty, textBinding);
+ int imageBinding = OS.gcnew_Binding ();
+ int imageConverter = OS.gcnew_SWTCellConverter (jniRef, "ConvertImage");
+ OS.Binding_Converter (imageBinding, imageConverter);
+ OS.Binding_ConverterParameter (imageBinding, columnJniRef);
+ int imageProperty = OS.Image_SourceProperty ();
+ OS.FrameworkElementFactory_SetBinding (imageNode, imageProperty, imageBinding);
+ OS.GCHandle_Free (textBinding);
+ OS.GCHandle_Free (textConverter);
+ OS.GCHandle_Free (textProperty);
+ OS.GCHandle_Free (imageBinding);
+ OS.GCHandle_Free (imageConverter);
+ OS.GCHandle_Free (imageProperty);
+
+ OS.GCHandle_Free (marginProperty);
+ OS.GCHandle_Free (thickness);
+ OS.GCHandle_Free (stackPanelType);
+ OS.GCHandle_Free (imageType);
+ OS.GCHandle_Free (textType);
+ OS.GCHandle_Free (stackPanelNode);
+ OS.GCHandle_Free (textName);
+ OS.GCHandle_Free (textNode);
+ OS.GCHandle_Free (imageName);
+ OS.GCHandle_Free (imageNode);
+ OS.GCHandle_Free (orientationProperty);
+ return template;
+}
+
+void createDefaultColumn () {
+ int column = OS.gcnew_GridViewColumn ();
+ int columnCollection = OS.GridView_Columns (gridViewHandle);
+ OS.GridViewColumnCollection_Insert (columnCollection, 0, column);
+ int cellTemplate = createCellTemplate (0, 0);
+ OS.GridViewColumn_CellTemplate (column, cellTemplate);
+ OS.GCHandle_Free (columnCollection);
+ OS.GCHandle_Free (column);
+ OS.GCHandle_Free (cellTemplate);
+}
+
+void createHandle () {
+ parentingHandle = OS.gcnew_Canvas ();
+ if (parentingHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ handle = OS.gcnew_ListView ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ gridViewHandle = OS.gcnew_GridView ();
+ if (gridViewHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.ListView_View (handle, gridViewHandle);
+ if ((style & SWT.MULTI) == 0) OS.ListBox_SelectionMode (handle, OS.SelectionMode_Single);
+ createDefaultColumn ();
+ setHeaderVisible (false);
+ OS.Selector_IsSynchronizedWithCurrentItem (handle, true);
+ OS.GridView_AllowsColumnReorder (gridViewHandle, false);
+ OS.Canvas_SetLeft (handle, 0);
+ OS.Canvas_SetTop (handle, 0);
+ int children = OS.Panel_Children (parentingHandle);
+ OS.UIElementCollection_Add (children, handle);
+ OS.GCHandle_Free (children);
+}
+
+int createHeaderTemplate (int columnJniRef) {
+ int template = OS.gcnew_DataTemplate ();
+ int stackPanelType = OS.StackPanel_typeid ();
+ int stackPanelNode = OS.gcnew_FrameworkElementFactory (stackPanelType);
+ int textType = OS.TextBlock_typeid ();
+ int textName = createDotNetString(TEXT_PART_NAME, false);
+ int textNode = OS.gcnew_FrameworkElementFactory (textType, textName);
+ int imageType = OS.Image_typeid ();
+ int imageName = createDotNetString(IMAGE_PART_NAME, false);
+ int imageNode = OS.gcnew_FrameworkElementFactory (imageType, imageName);
+ int marginProperty = OS.FrameworkElement_MarginProperty ();
+ int thickness = OS.gcnew_Thickness (0,0,4,0);
+ OS.FrameworkElementFactory_SetValue (imageNode, marginProperty, thickness);
+ int orientationProperty = OS.StackPanel_OrientationProperty ();
+ OS.FrameworkElementFactory_SetValueOrientation (stackPanelNode, orientationProperty, OS.Orientation_Horizontal);
+ OS.FrameworkElementFactory_AppendChild (stackPanelNode, imageNode);
+ OS.FrameworkElementFactory_AppendChild (stackPanelNode, textNode);
+ OS.FrameworkTemplate_VisualTree (template, stackPanelNode);
+ //bindings
+ int textBinding = OS.gcnew_Binding ();
+ int textConverter = OS.gcnew_SWTCellConverter (columnJniRef, "ConvertText");
+ OS.Binding_Converter (textBinding, textConverter);
+ OS.Binding_ConverterParameter (textBinding, columnJniRef);
+ int textProperty = OS.TextBlock_TextProperty ();
+ OS.FrameworkElementFactory_SetBinding (textNode, textProperty, textBinding);
+ int imageBinding = OS.gcnew_Binding ();
+ int imageConverter = OS.gcnew_SWTCellConverter (columnJniRef, "ConvertImage");
+ OS.Binding_Converter (imageBinding, imageConverter);
+ OS.Binding_ConverterParameter (imageBinding, columnJniRef);
+ int imageProperty = OS.Image_SourceProperty ();
+ OS.FrameworkElementFactory_SetBinding (imageNode, imageProperty, imageBinding);
+ OS.GCHandle_Free (textBinding);
+ OS.GCHandle_Free (textConverter);
+ OS.GCHandle_Free (textProperty);
+ OS.GCHandle_Free (imageBinding);
+ OS.GCHandle_Free (imageConverter);
+ OS.GCHandle_Free (imageProperty);
+
+ OS.GCHandle_Free (imageType);
+ OS.GCHandle_Free (imageName);
+ OS.GCHandle_Free (marginProperty);
+ OS.GCHandle_Free (thickness);
+ OS.GCHandle_Free (textType);
+ OS.GCHandle_Free (textName);
+ OS.GCHandle_Free (stackPanelType);
+ OS.GCHandle_Free (stackPanelNode);
+ OS.GCHandle_Free (textNode);
+ OS.GCHandle_Free (imageNode);
+ OS.GCHandle_Free (orientationProperty);
+ return template;
+}
+
+void createItem (TableColumn column, int index) {
+ if (index == -1) index = columnCount;
+ if (!(0 <= index && index <= columnCount)) error (SWT.ERROR_INVALID_RANGE);
+ column.createWidget ();
+ int template = createHeaderTemplate(column.jniRef);
+ OS.GridViewColumn_HeaderTemplate (column.handle, template);
+ OS.GCHandle_Free (template);
+ template = createCellTemplate (column.jniRef, index);
+ OS.GridViewColumn_CellTemplate (column.handle, template);
+ OS.GCHandle_Free (template);
+ int columns = OS.GridView_Columns (gridViewHandle);
+ if (columnCount == 0) OS.GridViewColumnCollection_Clear (columns);
+ OS.GridViewColumnCollection_Insert (columns, index, column.handle);
+ OS.GCHandle_Free (columns);
+ // When columnCount is 0, a "default column" is created in
+ // the WPF control, therefore there is no need to manipulate
+ // the item's array the first time a TableColumn is created
+ // because the number of columns in the OS control is still one.
+ if (columnCount != 0) {
+ int items = OS.ItemsControl_Items (handle);
+ for (int i=0; i<itemCount; i++) {
+ TableItem item = getItem (items, i, false);
+ if (item != null) {
+ String [] strings = item.strings;
+ if (strings != null) {
+ String [] temp = new String [columnCount + 1];
+ System.arraycopy (strings, 0, temp, 0, index);
+ System.arraycopy (strings, index, temp, index + 1, columnCount - index);
+ item.strings = temp;
+ }
+ int [] stringHandle = item.stringHandle;
+ if (stringHandle != null) {
+ int [] temp = new int [columnCount + 1];
+ System.arraycopy (stringHandle, 0, temp, 0, index);
+ System.arraycopy (stringHandle, index, temp, index + 1, columnCount - index);
+ item.stringHandle = temp;
+ }
+ Image [] images = item.images;
+ if (images != null) {
+ Image [] temp = new Image [columnCount + 1];
+ System.arraycopy (images, 0, temp, 0, index);
+ System.arraycopy (images, index, temp, index + 1, columnCount - index);
+ item.images = temp;
+ }
+ }
+ OS.GCHandle_Free (items);
+ }
+ }
+ columnCount++;
+}
+
+void createItem (TableItem item, int index) {
+ if (index == -1) index = itemCount;
+ if (!(0 <= index && index <= itemCount)) error (SWT.ERROR_INVALID_RANGE);
+ item.createWidget ();
+ int items = OS.ItemsControl_Items (handle);
+ OS.ItemCollection_Insert (items, index, item.handle);
+ int count = OS.ItemCollection_Count (items);
+ OS.GCHandle_Free (items);
+ if (itemCount == count) error (SWT.ERROR_ITEM_NOT_ADDED);
+ itemCount++;
+}
+
+void deregister () {
+ super.deregister ();
+ display.removeWidget (parentingHandle);
+}
+
+/**
+ * Deselects the items at the given zero-relative indices in the receiver.
+ * If the item at the given zero-relative index in the receiver
+ * is selected, it is deselected. If the item at the index
+ * was not selected, it remains deselected. Indices that are out
+ * of range and duplicate indices are ignored.
+ *
+ * @param indices the array of indices for the items to deselect
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the set of indices is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void deselect (int [] indices) {
+ checkWidget ();
+ if (indices == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (indices.length == 0) return;
+ int items = OS.ItemsControl_Items (handle);
+ ignoreSelection = true;
+ for (int i=0; i<indices.length; i++) {
+ if (!(0 <= indices[i] && indices[i] < itemCount)) continue;
+ int item = OS.ItemCollection_GetItemAt (items, i);
+ OS.ListBoxItem_IsSelected (item, false);
+ OS.GCHandle_Free (item);
+ }
+ ignoreSelection = false;
+ OS.GCHandle_Free (items);
+}
+
+/**
+ * Deselects the item at the given zero-relative index in the receiver.
+ * If the item at the index was already deselected, it remains
+ * deselected. Indices that are out of range are ignored.
+ *
+ * @param index the index of the item to deselect
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void deselect (int index) {
+ checkWidget ();
+ if (!(0 <= index && index < itemCount)) return;
+ int items = OS.ItemsControl_Items (handle);
+ int item = OS.ItemCollection_GetItemAt (items, index);
+ ignoreSelection = true;
+ OS.ListBoxItem_IsSelected (item, false);
+ ignoreSelection = false;
+ OS.GCHandle_Free (item);
+ OS.GCHandle_Free (items);
+}
+
+/**
+ * Deselects the items at the given zero-relative indices in the receiver.
+ * If the item at the given zero-relative index in the receiver
+ * is selected, it is deselected. If the item at the index
+ * was not selected, it remains deselected. The range of the
+ * indices is inclusive. Indices that are out of range are ignored.
+ *
+ * @param start the start index of the items to deselect
+ * @param end the end index of the items to deselect
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void deselect (int start, int end) {
+ checkWidget ();
+ if (start <= 0 && end >= itemCount - 1) {
+ deselectAll ();
+ } else {
+ start = Math.max (0, start);
+ end = Math.min (end, itemCount - 1);
+ int items = OS.ItemsControl_Items (handle);
+ ignoreSelection = true;
+ for (int i=start; i<=end; i++) {
+ int item = OS.ItemCollection_GetItemAt (items, i);
+ OS.ListBoxItem_IsSelected (item, false);
+ OS.GCHandle_Free (item);
+ }
+ ignoreSelection = false;
+ OS.GCHandle_Free (items);
+ }
+}
+
+/**
+ * Deselects all selected items in the receiver.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void deselectAll () {
+ checkWidget ();
+ ignoreSelection = true;
+ OS.ListBox_UnselectAll(handle);
+ ignoreSelection = false;
+}
+
+void destroyItem (TableColumn column) {
+ int columns = OS.GridView_Columns (gridViewHandle);
+ int index = OS.GridViewColumnCollection_IndexOf (columns, column.handle);
+ boolean removed = OS.GridViewColumnCollection_Remove (columns, column.handle);
+ OS.GCHandle_Free (columns);
+ if (!removed) error (SWT.ERROR_ITEM_NOT_REMOVED);
+ columnCount--;
+ if (columnCount == 0) {
+ createDefaultColumn ();
+ }
+ int items = OS.ItemsControl_Items (handle);
+ for (int i=0; i<itemCount; i++) {
+ TableItem item = getItem (items, i, false);
+ if (item != null) {
+ String [] strings = item.strings;
+ if (strings != null) {
+ String [] temp = new String [columnCount];
+ System.arraycopy (strings, 0, temp, 0, index);
+ System.arraycopy (strings, index + 1, temp, index, columnCount - index);
+ item.strings = temp;
+ }
+ int [] stringHandle = item.stringHandle;
+ if (stringHandle != null) {
+ int [] temp = new int [columnCount];
+ System.arraycopy (stringHandle, 0, temp, 0, index);
+ System.arraycopy (stringHandle, index + 1, temp, index, columnCount - index);
+ if (stringHandle [index] != 0) OS.GCHandle_Free (stringHandle [index]);
+ item.stringHandle = temp;
+ }
+ Image [] images = item.images;
+ if (images != null) {
+ Image [] temp = new Image [columnCount];
+ System.arraycopy (images, 0, temp, 0, index);
+ System.arraycopy (images, index + 1, temp, index, columnCount - index);
+ item.images = temp;
+ }
+ }
+ }
+ OS.GCHandle_Free (items);
+}
+
+void destroyItem (TableItem item) {
+ int items = OS.ItemsControl_Items (handle);
+ OS.ItemCollection_Remove (items, item.handle);
+ int count = OS.ItemCollection_Count (items);
+ OS.GCHandle_Free (items);
+ if (itemCount == count) error (SWT.ERROR_ITEM_NOT_REMOVED);
+ itemCount--;
+}
+
+/**
+ * Returns the column at the given, zero-relative index in the
+ * receiver. Throws an exception if the index is out of range.
+ * Columns are returned in the order that they were created.
+ * If no <code>TableColumn</code>s were created by the programmer,
+ * this method will throw <code>ERROR_INVALID_RANGE</code> despite
+ * the fact that a single column of data may be visible in the table.
+ * This occurs when the programmer uses the table like a list, adding
+ * items but never creating a column.
+ *
+ * @param index the index of the column to return
+ * @return the column at the given index
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Table#getColumnOrder()
+ * @see Table#setColumnOrder(int[])
+ * @see TableColumn#getMoveable()
+ * @see TableColumn#setMoveable(boolean)
+ * @see SWT#Move
+ */
+public TableColumn getColumn (int index) {
+ checkWidget ();
+ if (!(0 <= index && index < columnCount)) error (SWT.ERROR_INVALID_RANGE);
+ int columns = OS.GridView_Columns (gridViewHandle);
+ TableColumn column = getColumn (columns, index);
+ OS.GCHandle_Free (columns);
+ return column;
+}
+
+TableColumn getColumn (int columns, int index) {
+ int gridColumn = OS.GridViewColumnCollection_default (columns, index);
+ int header = OS.GridViewColumn_Header (gridColumn);
+ int content = OS.ContentControl_Content(header);
+ TableColumn column = (TableColumn)OS.JNIGetObject (OS.IntPtr_ToInt32(content));
+ OS.GCHandle_Free (gridColumn);
+ OS.GCHandle_Free (header);
+ OS.GCHandle_Free (content);
+ return column;
+}
+
+void updateMoveable () {
+ int columns = OS.GridView_Columns (gridViewHandle);
+ boolean moveable = true;
+ for (int i = 0; moveable && i < columnCount; i++) {
+ TableColumn column = getColumn (columns, i);
+ if (!column.moveable) moveable = false;
+ }
+ OS.GCHandle_Free (columns);
+ OS.GridView_AllowsColumnReorder (gridViewHandle, moveable);
+}
+
+/**
+ * Returns the number of columns contained in the receiver.
+ * If no <code>TableColumn</code>s were created by the programmer,
+ * this value is zero, despite the fact that visually, one column
+ * of items may be visible. This occurs when the programmer uses
+ * the table like a list, adding items but never creating a column.
+ *
+ * @return the number of columns
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getColumnCount () {
+ checkWidget ();
+ return columnCount;
+}
+
+/**
+ * Returns an array of zero-relative integers that map
+ * the creation order of the receiver's items to the
+ * order in which they are currently being displayed.
+ * <p>
+ * Specifically, the indices of the returned array represent
+ * the current visual order of the items, and the contents
+ * of the array represent the creation order of the items.
+ * </p><p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its list of items, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ *
+ * @return the current visual order of the receiver's items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Table#setColumnOrder(int[])
+ * @see TableColumn#getMoveable()
+ * @see TableColumn#setMoveable(boolean)
+ * @see SWT#Move
+ *
+ * @since 3.1
+ */
+public int[] getColumnOrder () {
+ checkWidget ();
+ //TODO
+ int [] order = new int [columnCount];
+ for (int i=0; i<order.length; i++) order [i] = i;
+ return order;
+}
+
+/**
+ * Returns an array of <code>TableColumn</code>s which are the
+ * columns in the receiver. Columns are returned in the order
+ * that they were created. If no <code>TableColumn</code>s were
+ * created by the programmer, the array is empty, despite the fact
+ * that visually, one column of items may be visible. This occurs
+ * when the programmer uses the table like a list, adding items but
+ * never creating a column.
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its list of items, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ *
+ * @return the items in the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Table#getColumnOrder()
+ * @see Table#setColumnOrder(int[])
+ * @see TableColumn#getMoveable()
+ * @see TableColumn#setMoveable(boolean)
+ * @see SWT#Move
+ */
+public TableColumn [] getColumns () {
+ checkWidget ();
+ TableColumn [] result = new TableColumn [columnCount];
+ int columns = OS.GridView_Columns (gridViewHandle);
+ for (int i = 0; i < result.length; i++) {
+ result[i] = getColumn (columns, i);
+ }
+ OS.GCHandle_Free (columns);
+ return result;
+}
+
+int getFocusIndex () {
+// checkWidget ();
+ int itemCollection = OS.ItemsControl_Items (handle);
+ int index = OS.ItemCollection_CurrentPosition (itemCollection);
+ OS.GCHandle_Free (itemCollection);
+ return index;
+}
+
+/**
+ * Returns the width in pixels of a grid line.
+ *
+ * @return the width of a grid line in pixels
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getGridLineWidth () {
+ checkWidget ();
+ return 0; //FIXME: No grid lines yet
+}
+
+/**
+ * Returns the height of the receiver's header
+ *
+ * @return the height of the header or zero if the header is not visible
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.0
+ */
+public int getHeaderHeight () {
+ checkWidget ();
+ // TODO
+ return -1;
+}
+
+/**
+ * Returns <code>true</code> if the receiver's header is visible,
+ * and <code>false</code> otherwise.
+ * <p>
+ * If one of the receiver's ancestors is not visible or some
+ * other condition makes the receiver not visible, this method
+ * may still indicate that it is considered visible even though
+ * it may not actually be showing.
+ * </p>
+ *
+ * @return the receiver's header's visibility state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getHeaderVisible () {
+ checkWidget ();
+ //TODO
+ return true;
+}
+
+/**
+ * Returns the item at the given, zero-relative index in the
+ * receiver. Throws an exception if the index is out of range.
+ *
+ * @param index the index of the item to return
+ * @return the item at the given index
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public TableItem getItem (int index) {
+ checkWidget ();
+ if (!(0 <= index && index < itemCount)) error (SWT.ERROR_INVALID_RANGE);
+ int items = OS.ItemsControl_Items (handle);
+ TableItem item = getItem (items, index, true);
+ OS.GCHandle_Free (items);
+ return item;
+}
+
+TableItem getItem (int items, int index, boolean create) {
+ int item = OS.ItemCollection_GetItemAt (items, index);
+ int content = OS.ContentControl_Content (item);
+ int contentValue = OS.IntPtr_ToInt32 (content);
+ TableItem result = null;
+ if (contentValue > 0 ) {
+ result = (TableItem) OS.JNIGetObject (contentValue);
+ OS.GCHandle_Free (item);
+ } else {
+ if (create) {
+ result = new TableItem (this, SWT.NONE, 0, item);
+ } else {
+ OS.GCHandle_Free (item);
+ }
+ }
+ OS.GCHandle_Free (content);
+ return result;
+}
+
+/**
+ * Returns the item at the given point in the receiver
+ * or null if no such item exists. The point is in the
+ * coordinate system of the receiver.
+ * <p>
+ * The item that is returned represents an item that could be selected by the user.
+ * For example, if selection only occurs in items in the first column, then null is
+ * returned if the point is outside of the item.
+ * Note that the SWT.FULL_SELECTION style hint, which specifies the selection policy,
+ * determines the extent of the selection.
+ * </p>
+ *
+ * @param point the point used to locate the item
+ * @return the item at the given point, or null if the point is not in a selectable item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public TableItem getItem (Point point) {
+ checkWidget ();
+ if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int pt = OS.gcnew_Point (point.x, point.y);
+ int input = OS.UIElement_InputHitTest (handle, pt);
+ Widget widget = display.getWidget (input);
+ OS.GCHandle_Free (input);
+ OS.GCHandle_Free (pt);
+ if (widget == this) return null;
+ return (TableItem) widget;
+}
+
+/**
+ * Returns the number of items contained in the receiver.
+ *
+ * @return the number of items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getItemCount () {
+ checkWidget ();
+ return itemCount;
+}
+
+/**
+ * Returns the height of the area which would be used to
+ * display <em>one</em> of the items in the receiver's.
+ *
+ * @return the height of one item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getItemHeight () {
+ checkWidget ();
+ //FIXME what is the default size?
+ if (itemCount == 0) return 16;
+ int items = OS.ItemsControl_Items (handle);
+ int item = OS.ItemCollection_GetItemAt (items, 0);
+ double height = OS.FrameworkElement_ActualHeight (item);
+ OS.GCHandle_Free (item);
+ OS.GCHandle_Free (items);
+ return (int) height;
+}
+
+/**
+ * Returns a (possibly empty) array of <code>TableItem</code>s which
+ * are the items in the receiver.
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its list of items, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ *
+ * @return the items in the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public TableItem [] getItems () {
+ checkWidget ();
+ TableItem [] result = new TableItem [itemCount];
+ int items = OS.ItemsControl_Items (handle);
+ for (int i=0; i<itemCount; i++) {
+ result [i] = getItem (items, i, true);
+ }
+ OS.GCHandle_Free (items);
+ return result;
+}
+
+/**
+ * Returns <code>true</code> if the receiver's lines are visible,
+ * and <code>false</code> otherwise.
+ * <p>
+ * If one of the receiver's ancestors is not visible or some
+ * other condition makes the receiver not visible, this method
+ * may still indicate that it is considered visible even though
+ * it may not actually be showing.
+ * </p>
+ *
+ * @return the visibility state of the lines
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getLinesVisible () {
+ checkWidget ();
+ //TODO
+ return false;
+}
+
+/**
+ * Returns an array of <code>TableItem</code>s that are currently
+ * selected in the receiver. The order of the items is unspecified.
+ * An empty array indicates that no items are selected.
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its selection, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ * @return an array representing the selection
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public TableItem [] getSelection () {
+ checkWidget ();
+ int selected = OS.ListBox_SelectedItems (handle);
+ int enumerator = OS.IList_GetEnumerator (selected);
+ int count = OS.ICollection_Count (selected);
+ TableItem [] result = new TableItem [count];
+ int index = 0;
+ while (OS.IEnumerator_MoveNext (enumerator)) {
+ int item = OS.IEnumerator_Current (enumerator);
+ result [index++] = (TableItem)display.getWidget (item);
+ OS.GCHandle_Free (item);
+ }
+ OS.GCHandle_Free (enumerator);
+ OS.GCHandle_Free (selected);
+ return result;
+}
+
+/**
+ * Returns the number of selected items contained in the receiver.
+ *
+ * @return the number of selected items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getSelectionCount () {
+ checkWidget ();
+ int selected = OS.ListBox_SelectedItems (handle);
+ int count = OS.ICollection_Count (selected);
+ OS.GCHandle_Free (selected);
+ return count;
+}
+
+/**
+ * Returns the zero-relative index of the item which is currently
+ * selected in the receiver, or -1 if no item is selected.
+ *
+ * @return the index of the selected item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getSelectionIndex () {
+ checkWidget ();
+ return OS.Selector_SelectedIndex (handle);
+}
+
+/**
+ * Returns the zero-relative indices of the items which are currently
+ * selected in the receiver. The order of the indices is unspecified.
+ * The array is empty if no items are selected.
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its selection, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ * @return the array of indices of the selected items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int [] getSelectionIndices () {
+ checkWidget ();
+ int itemCollection = OS.ItemsControl_Items (handle);
+ int list = OS.ListBox_SelectedItems (handle);
+ int enumerator = OS.IList_GetEnumerator (list);
+ int count = OS.ICollection_Count (list);
+ int [] indices = new int [count];
+ int index = 0;
+ while (OS.IEnumerator_MoveNext (enumerator)) {
+ int item = OS.IEnumerator_Current (enumerator);
+ indices [index++] = OS.ItemCollection_IndexOf (itemCollection, item);
+ OS.GCHandle_Free (item);
+ }
+ OS.GCHandle_Free (enumerator);
+ OS.GCHandle_Free (list);
+ OS.GCHandle_Free (itemCollection);
+ return indices;
+}
+
+/**
+ * Returns the column which shows the sort indicator for
+ * the receiver. The value may be null if no column shows
+ * the sort indicator.
+ *
+ * @return the sort indicator
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #setSortColumn(TableColumn)
+ *
+ * @since 3.2
+ */
+public TableColumn getSortColumn () {
+ checkWidget ();
+ //TODO
+ return null;
+}
+
+/**
+ * Returns the direction of the sort indicator for the receiver.
+ * The value will be one of <code>UP</code>, <code>DOWN</code>
+ * or <code>NONE</code>.
+ *
+ * @return the sort direction
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #setSortDirection(int)
+ *
+ * @since 3.2
+ */
+public int getSortDirection () {
+ checkWidget ();
+ //TODO
+ return -1;
+}
+
+/**
+ * Returns the zero-relative index of the item which is currently
+ * at the top of the receiver. This index can change when items are
+ * scrolled or new items are added or removed.
+ *
+ * @return the index of the top item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getTopIndex () {
+ checkWidget ();
+ int items = OS.ItemsControl_Items (handle);
+ int item = OS.ItemCollection_GetItemAt (items, 0);
+ OS.GCHandle_Free (items);
+ int virtualizingStackPanel = OS.VisualTreeHelper_GetParent (item);
+ OS.GCHandle_Free (item);
+ int topIndex = 0;
+ if (virtualizingStackPanel != 0) {
+ topIndex = (int) OS.VirtualizingStackPanel_VerticalOffset (virtualizingStackPanel);
+ OS.GCHandle_Free (virtualizingStackPanel);
+ }
+ return topIndex;
+}
+
+boolean hasItems () {
+ return true;
+}
+
+void HandleChecked (int sender, int e) {
+ if (!checkEvent (e)) return;
+ if (ignoreSelection) return;
+ int source = OS.RoutedEventArgs_Source (e);
+ TableItem item = (TableItem) display.getWidget (source);
+ OS.GCHandle_Free (source);
+ if (item.grayed) {
+ int checkbox = item.findPart (0, CHECKBOX_PART_NAME);
+ if (checkbox != 0) {
+ OS.ToggleButton_IsCheckedNullSetter (checkbox);
+ OS.GCHandle_Free (checkbox);
+ }
+ }
+ item.checked = true;
+ Event event = new Event ();
+ event.item = item;
+ event.detail = SWT.CHECK;
+ sendEvent (SWT.Selection, event);
+}
+
+void HandleIndeterminate (int sender, int e) {
+ if (!checkEvent (e)) return;
+ int source = OS.RoutedEventArgs_Source (e);
+ TableItem item = (TableItem) display.getWidget (source);
+ OS.GCHandle_Free (source);
+ if (!item.grayed) {
+ int checkbox = item.findPart (0, CHECKBOX_PART_NAME);
+ if (checkbox != 0) {
+ OS.ToggleButton_IsChecked (checkbox, false);
+ OS.GCHandle_Free (checkbox);
+ }
+ }
+}
+
+void HandleKeyDown (int sender, int e) {
+ if (!checkEvent (e)) return;
+ super.HandleKeyDown (sender, e);
+ int key = OS.KeyEventArgs_Key (e);
+ if (key == OS.Key_Return) {
+ int source = OS.RoutedEventArgs_OriginalSource (e);
+ Widget widget = display.getWidget (source);
+ OS.GCHandle_Free (source);
+ if (widget == this || widget == null) return;
+ TableItem item = (TableItem)widget;
+ Event event = new Event ();
+ event.item = item;
+ postEvent (SWT.DefaultSelection, event);
+ }
+}
+
+void HandleMouseDoubleClick (int sender, int e) {
+ if (!checkEvent (e)) return;
+ int source = OS.RoutedEventArgs_OriginalSource (e);
+ Widget widget = display.getWidget (source);
+ OS.GCHandle_Free (source);
+ if (widget == this || widget == null) return;
+ TableItem item = (TableItem)widget;
+ Event event = new Event ();
+ event.item = item;
+ postEvent (SWT.DefaultSelection, event);
+}
+
+void HandleSelectionChanged (int sender, int e) {
+ if (!checkEvent (e)) return;
+ if (ignoreSelection) return;
+ int item = 0;
+ int list = OS.SelectionChangedEventArgs_AddedItems (e);
+ if (list != 0) {
+ int count = OS.ICollection_Count (list);
+ if (count > 0) item = OS.IList_default (list, count - 1);
+ }
+ OS.GCHandle_Free (list);
+ if (item == 0) {
+ list = OS.SelectionChangedEventArgs_RemovedItems (e);
+ int count = OS.ICollection_Count (list);
+ if (count > 0) item = OS.IList_default (list, count - 1);
+ OS.GCHandle_Free (list);
+ }
+ if (item != 0) {
+ TableItem result = (TableItem)display.getWidget (item);
+ OS.GCHandle_Free (item);
+ if (result != null) {
+ Event event = new Event ();
+ event.item = result;
+ postEvent (SWT.Selection, event);
+ }
+ }
+}
+
+void HandleUnchecked (int sender, int e) {
+ if (!checkEvent (e)) return;
+ if (ignoreSelection) return;
+ int source = OS.RoutedEventArgs_Source (e);
+ TableItem item = (TableItem) display.getWidget (source);
+ OS.GCHandle_Free (source);
+ item.checked = false;
+ Event event = new Event ();
+ event.item = item;
+ event.detail = SWT.CHECK;
+ sendEvent (SWT.Selection, event);
+}
+
+void hookEvents () {
+ super.hookEvents ();
+ int handler = OS.gcnew_SelectionChangedEventHandler (jniRef, "HandleSelectionChanged");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.Selector_SelectionChanged (handle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_MouseButtonEventHandler (jniRef, "HandleMouseDoubleClick");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.Control_MouseDoubleClick (handle, handler);
+ OS.GCHandle_Free (handler);
+ if ((style & SWT.CHECK) != 0) {
+ /* Item events */
+ handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleChecked");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ int event = OS.ToggleButton_CheckedEvent ();
+ OS.UIElement_AddHandler (handle, event, handler);
+ OS.GCHandle_Free (event);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleUnchecked");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ event = OS.ToggleButton_UncheckedEvent ();
+ OS.UIElement_AddHandler (handle, event, handler);
+ OS.GCHandle_Free (event);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleIndeterminate");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ event = OS.ToggleButton_IndeterminateEvent ();
+ OS.UIElement_AddHandler (handle, event, handler);
+ OS.GCHandle_Free (event);
+ OS.GCHandle_Free (handler);
+ }
+}
+
+/**
+ * Searches the receiver's list starting at the first column
+ * (index 0) until a column is found that is equal to the
+ * argument, and returns the index of that column. If no column
+ * is found, returns -1.
+ *
+ * @param column the search column
+ * @return the index of the column
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int indexOf (TableColumn column) {
+ checkWidget ();
+ if (column == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int columns = OS.GridView_Columns (gridViewHandle);
+ int index = OS.GridViewColumnCollection_IndexOf (columns, column.handle);
+ OS.GCHandle_Free (columns);
+ return index;
+}
+
+/**
+ * Searches the receiver's list starting at the first item
+ * (index 0) until an item is found that is equal to the
+ * argument, and returns the index of that item. If no item
+ * is found, returns -1.
+ *
+ * @param item the search item
+ * @return the index of the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int indexOf (TableItem item) {
+ checkWidget ();
+ if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int items = OS.ItemsControl_Items(handle);
+ int index = OS.ItemCollection_IndexOf(items, item.handle);
+ OS.GCHandle_Free (items);
+ return index;
+}
+
+/**
+ * Returns <code>true</code> if the item is selected,
+ * and <code>false</code> otherwise. Indices out of
+ * range are ignored.
+ *
+ * @param index the index of the item
+ * @return the visibility state of the item at the index
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean isSelected (int index) {
+ checkWidget ();
+ int items = OS.ItemsControl_Items (handle);
+ int item = OS.ItemCollection_GetItemAt (items, index);
+ boolean result = OS.ListBoxItem_IsSelected (item);
+ OS.GCHandle_Free (item);
+ OS.GCHandle_Free (items);
+ return result;
+}
+
+int parentingHandle () {
+ return parentingHandle;
+}
+
+void register() {
+ super.register();
+ display.addWidget (parentingHandle, this);
+}
+
+void releaseChildren (boolean destroy) {
+ int items = OS.ItemsControl_Items (handle);
+ for (int i=0; i<itemCount; i++) {
+ TableItem item = getItem (items, i, false);
+ if (item != null && !item.isDisposed ()) item.release (false);
+ }
+ OS.GCHandle_Free (items);
+ int columns = OS.GridView_Columns (gridViewHandle);
+ for (int i=0; i<columnCount; i++) {
+ TableColumn column = getColumn(columns, i);
+ if (!column.isDisposed ()) column.release (false);
+ }
+ OS.GCHandle_Free (columns);
+ super.releaseChildren (destroy);
+}
+
+void releaseHandle () {
+ super.releaseHandle ();
+ OS.GCHandle_Free (gridViewHandle);
+ gridViewHandle = 0;
+ OS.GCHandle_Free (parentingHandle);
+ parentingHandle = 0;
+}
+
+/**
+ * Removes the items from the receiver's list at the given
+ * zero-relative indices.
+ *
+ * @param indices the array of indices of the items
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * <li>ERROR_NULL_ARGUMENT - if the indices array is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void remove (int [] indices) {
+ checkWidget ();
+ if (indices == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (indices.length == 0) return;
+ int [] newIndices = new int [indices.length];
+ System.arraycopy (indices, 0, newIndices, 0, indices.length);
+ sort (newIndices);
+ int start = newIndices [newIndices.length - 1], end = newIndices [0];
+ if (!(0 <= start && start <= end && end < itemCount)) {
+ error (SWT.ERROR_INVALID_RANGE);
+ }
+ int items = OS.ItemsControl_Items (handle);
+ for (int i = newIndices.length-1; i >= 0; i--) {
+ OS.ItemCollection_RemoveAt (items, indices [i]);
+ }
+ itemCount = OS.ItemCollection_Count (items);
+ OS.GCHandle_Free (items);
+}
+
+/**
+ * Removes the item from the receiver at the given
+ * zero-relative index.
+ *
+ * @param index the index for the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void remove (int index) {
+ checkWidget ();
+ if (!(0 <= index && index < itemCount)) return;
+ int items = OS.ItemsControl_Items (handle);
+ OS.ItemCollection_RemoveAt (items, index);
+ itemCount = OS.ItemCollection_Count (items);
+ OS.GCHandle_Free (items);
+}
+
+/**
+ * Removes the items from the receiver which are
+ * between the given zero-relative start and end
+ * indices (inclusive).
+ *
+ * @param start the start of the range
+ * @param end the end of the range
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if either the start or end are not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void remove (int start, int end) {
+ checkWidget ();
+ if (start > end) return;
+ if (!(0 <= start && start <= end && end < itemCount)) error (SWT.ERROR_INVALID_RANGE);
+ if (start == 0 && end == itemCount - 1) {
+ removeAll ();
+ return;
+ }
+ int items = OS.ItemsControl_Items (handle);
+ for (int i = end; i >= start; i--) {
+ OS.ItemCollection_RemoveAt (items, i);
+ }
+ itemCount = OS.ItemCollection_Count (items);
+ OS.GCHandle_Free (items);
+}
+
+/**
+ * Removes all of the items from the receiver.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void removeAll () {
+ checkWidget ();
+ int items = OS.ItemsControl_Items (handle);
+ for (int i = 0; i < itemCount; i++) {
+ TableItem item = getItem (items, i, false);
+ if (item != null && !item.isDisposed ()) item.release (false);
+ }
+ OS.ItemCollection_Clear (items);
+ itemCount = OS.ItemCollection_Count (items);
+ OS.GCHandle_Free (items);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the receiver's selection changes.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #addSelectionListener(SelectionListener)
+ */
+public void removeSelectionListener(SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Selection, listener);
+ eventTable.unhook (SWT.DefaultSelection,listener);
+}
+
+/**
+ * Selects the items at the given zero-relative indices in the receiver.
+ * The current selection is not cleared before the new items are selected.
+ * <p>
+ * If the item at a given index is not selected, it is selected.
+ * If the item at a given index was already selected, it remains selected.
+ * Indices that are out of range and duplicate indices are ignored.
+ * If the receiver is single-select and multiple indices are specified,
+ * then all indices are ignored.
+ * </p>
+ *
+ * @param indices the array of indices for the items to select
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the array of indices is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Table#setSelection(int[])
+ */
+public void select (int [] indices) {
+ checkWidget ();
+ if (indices == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int length = indices.length;
+ if (length == 0 || ((style & SWT.SINGLE) != 0 && length > 1)) return;
+ ignoreSelection = true;
+ int items = OS.ItemsControl_Items (handle);
+ for (int i = 0; i < indices.length; i++) {
+ if (!(0 <= indices[i] && indices[i] < itemCount)) continue;
+ int item = OS.ItemCollection_GetItemAt (items, indices[i]);
+ OS.ListBoxItem_IsSelected (item, true);
+ OS.GCHandle_Free (item);
+ }
+ OS.GCHandle_Free (items);
+ ignoreSelection = false;
+}
+
+/**
+ * Selects the item at the given zero-relative index in the receiver.
+ * If the item at the index was already selected, it remains
+ * selected. Indices that are out of range are ignored.
+ *
+ * @param index the index of the item to select
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void select (int index) {
+ checkWidget ();
+ if (!(0 <= index && index < itemCount)) return;
+ int items = OS.ItemsControl_Items (handle);
+ int item = OS.ItemCollection_GetItemAt (items, index);
+ ignoreSelection = true;
+ OS.ListBoxItem_IsSelected (item, true);
+ ignoreSelection = false;
+ OS.GCHandle_Free (item);
+ OS.GCHandle_Free (items);
+}
+
+/**
+ * Selects the items in the range specified by the given zero-relative
+ * indices in the receiver. The range of indices is inclusive.
+ * The current selection is not cleared before the new items are selected.
+ * <p>
+ * If an item in the given range is not selected, it is selected.
+ * If an item in the given range was already selected, it remains selected.
+ * Indices that are out of range are ignored and no items will be selected
+ * if start is greater than end.
+ * If the receiver is single-select and there is more than one item in the
+ * given range, then all indices are ignored.
+ * </p>
+ *
+ * @param start the start of the range
+ * @param end the end of the range
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Table#setSelection(int,int)
+ */
+public void select (int start, int end) {
+ checkWidget ();
+ if (start <= 0 && end >= itemCount - 1) {
+ deselectAll ();
+ } else {
+ start = Math.max (0, start);
+ end = Math.min (end, itemCount - 1);
+ int items = OS.ItemsControl_Items (handle);
+ ignoreSelection = true;
+ for (int i=start; i<=end; i++) {
+ int item = OS.ItemCollection_GetItemAt (items, i);
+ OS.ListBoxItem_IsSelected (item, true);
+ OS.GCHandle_Free (item);
+ }
+ ignoreSelection = false;
+ OS.GCHandle_Free (items);
+ }
+}
+
+/**
+ * Selects all of the items in the receiver.
+ * <p>
+ * If the receiver is single-select, do nothing.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void selectAll () {
+ checkWidget ();
+ if ((style & SWT.SINGLE) != 0) return;
+ ignoreSelection = true;
+ OS.ListBox_SelectAll (handle);
+ ignoreSelection = false;
+}
+
+int setBounds (int x, int y, int width, int height, int flags) {
+ int result = super.setBounds (x, y, width, height, flags);
+ if ((result & RESIZED) != 0) {
+ if (columnCount == 0) {
+ int columns = OS.GridView_Columns (gridViewHandle);
+ int column = OS.GridViewColumnCollection_default (columns, 0);
+ OS.GridViewColumn_Width (column, width);
+ OS.GCHandle_Free (column);
+ OS.GCHandle_Free (columns);
+ }
+ OS.FrameworkElement_Width (handle, width);
+ OS.FrameworkElement_Height (handle, height);
+ }
+ return result;
+}
+
+/**
+ * Sets the order that the items in the receiver should
+ * be displayed in to the given argument which is described
+ * in terms of the zero-relative ordering of when the items
+ * were added.
+ *
+ * @param order the new order to display the items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the item order is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the item order is not the same length as the number of items</li>
+ * </ul>
+ *
+ * @see Table#getColumnOrder()
+ * @see TableColumn#getMoveable()
+ * @see TableColumn#setMoveable(boolean)
+ * @see SWT#Move
+ *
+ * @since 3.1
+ */
+public void setColumnOrder (int [] order) {
+ checkWidget ();
+ if (order == null) error (SWT.ERROR_NULL_ARGUMENT);
+ //TODO
+}
+
+void setForegroundBrush (int brush) {
+ if (brush != 0) {
+ OS.Control_Foreground (handle, brush);
+ } else {
+ int property = OS.Control_ForegroundProperty ();
+ OS.DependencyObject_ClearValue (handle, property);
+ OS.GCHandle_Free (property);
+ }
+}
+
+/**
+ * Marks the receiver's header as visible if the argument is <code>true</code>,
+ * and marks it invisible otherwise.
+ * <p>
+ * If one of the receiver's ancestors is not visible or some
+ * other condition makes the receiver not visible, marking
+ * it visible may not actually cause it to be displayed.
+ * </p>
+ *
+ * @param show the new visibility state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setHeaderVisible (boolean show) {
+ checkWidget ();
+ int style = 0;
+ if (!show) {
+ style = OS.gcnew_Style ();
+ int dp = OS.FrameworkElement_VisibilityProperty ();
+ int setter = OS.gcnew_Setter (dp, OS.Visibility_Collapsed);
+ int collection = OS.Style_Setters (style);
+ OS.SetterBaseCollection_Add (collection, setter);
+ OS.GCHandle_Free (collection);
+ OS.GCHandle_Free (setter);
+ OS.GCHandle_Free (dp);
+ }
+ OS.GridView_ColumnHeaderContainerStyle (gridViewHandle, style);
+ if (style != 0) OS.GCHandle_Free (style);
+}
+
+/**
+ * Sets the number of items contained in the receiver.
+ *
+ * @param count the number of items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void setItemCount (int count) {
+ checkWidget ();
+ count = Math.max (0, count);
+ if (count == itemCount) return;
+ int index = count;
+ int items = OS.ItemsControl_Items (handle);
+ while (index < itemCount) {
+ TableItem item = getItem (items, index, false);
+ if (item != null) {
+ if (!item.isDisposed()) item.release (false);
+ } else {
+ OS.ItemCollection_RemoveAt (items, index);
+ }
+ index++;
+ }
+ if (OS.ItemCollection_Count (items) > count) error (SWT.ERROR_ITEM_NOT_REMOVED);
+ if ((style & SWT.VIRTUAL) != 0) {
+ for (int i=itemCount; i<count; i++) {
+ int item = OS.gcnew_ListViewItem ();
+ if (item == 0) error (SWT.ERROR_NO_HANDLES);
+ int content = OS.gcnew_IntPtr (-i);
+ OS.ContentControl_Content (item, content);
+ OS.ItemCollection_Add (items, item);
+ OS.GCHandle_Free (content);
+ OS.GCHandle_Free (item);
+ }
+ } else {
+ for (int i=itemCount; i<count; i++) {
+ new TableItem (this, SWT.NONE, i);
+ }
+ }
+ itemCount = OS.ItemCollection_Count (items);
+ OS.GCHandle_Free (items);
+ if (itemCount != count) error (SWT.ERROR_ITEM_NOT_ADDED);
+}
+
+/**
+ * Sets the height of the area which would be used to
+ * display <em>one</em> of the items in the table.
+ *
+ * @return the height of one item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+/*public*/ void setItemHeight (int itemHeight) {
+ checkWidget ();
+}
+
+/**
+ * Marks the receiver's lines as visible if the argument is <code>true</code>,
+ * and marks it invisible otherwise.
+ * <p>
+ * If one of the receiver's ancestors is not visible or some
+ * other condition makes the receiver not visible, marking
+ * it visible may not actually cause it to be displayed.
+ * </p>
+ *
+ * @param show the new visibility state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setLinesVisible (boolean show) {
+ checkWidget ();
+ //TODO
+}
+
+/**
+ * Selects the items at the given zero-relative indices in the receiver.
+ * The current selection is cleared before the new items are selected.
+ * <p>
+ * Indices that are out of range and duplicate indices are ignored.
+ * If the receiver is single-select and multiple indices are specified,
+ * then all indices are ignored.
+ * </p>
+ *
+ * @param indices the indices of the items to select
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the array of indices is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Table#deselectAll()
+ * @see Table#select(int[])
+ */
+public void setSelection (int [] indices) {
+ checkWidget ();
+ if (indices == null) error (SWT.ERROR_NULL_ARGUMENT);
+ deselectAll ();
+ int length = indices.length;
+ if (length == 0 || ((style & SWT.SINGLE) != 0 && length > 1)) return;
+ select (indices);
+ //TODO
+// int focusIndex = indices [0];
+// if (focusIndex != -1) setFocusIndex (focusIndex);
+ showSelection ();
+}
+
+/**
+ * Sets the receiver's selection to the given item.
+ * The current selection is cleared before the new item is selected.
+ * <p>
+ * If the item is not in the receiver, then it is ignored.
+ * </p>
+ *
+ * @param item the item to select
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the item is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public void setSelection (TableItem item) {
+ checkWidget ();
+ if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
+ setSelection (new TableItem [] {item});
+}
+
+/**
+ * Sets the receiver's selection to be the given array of items.
+ * The current selection is cleared before the new items are selected.
+ * <p>
+ * Items that are not in the receiver are ignored.
+ * If the receiver is single-select and multiple items are specified,
+ * then all items are ignored.
+ * </p>
+ *
+ * @param items the array of items
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the array of items is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if one of the items has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Table#deselectAll()
+ * @see Table#select(int[])
+ * @see Table#setSelection(int[])
+ */
+public void setSelection (TableItem [] items) {
+ checkWidget ();
+ if (items == null) error (SWT.ERROR_NULL_ARGUMENT);
+ deselectAll ();
+ int length = items.length;
+ if (length == 0 || ((style & SWT.SINGLE) != 0 && length > 1)) return;
+ for (int i=length-1; i>=0; --i) {
+ int index = indexOf (items [i]);
+ if (index != -1) {
+ select (index);
+ }
+ }
+ //TODO
+// if (focusIndex != -1) setFocusIndex (focusIndex);
+ showSelection ();
+}
+
+/**
+ * Selects the item at the given zero-relative index in the receiver.
+ * The current selection is first cleared, then the new item is selected.
+ *
+ * @param index the index of the item to select
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Table#deselectAll()
+ * @see Table#select(int)
+ */
+public void setSelection (int index) {
+ checkWidget ();
+ deselectAll ();
+ select (index);
+ //TODO
+// if (index != -1) setFocusIndex (index);
+ showSelection ();
+}
+
+/**
+ * Selects the items in the range specified by the given zero-relative
+ * indices in the receiver. The range of indices is inclusive.
+ * The current selection is cleared before the new items are selected.
+ * <p>
+ * Indices that are out of range are ignored and no items will be selected
+ * if start is greater than end.
+ * If the receiver is single-select and there is more than one item in the
+ * given range, then all indices are ignored.
+ * </p>
+ *
+ * @param start the start index of the items to select
+ * @param end the end index of the items to select
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Table#deselectAll()
+ * @see Table#select(int,int)
+ */
+public void setSelection (int start, int end) {
+ checkWidget ();
+ deselectAll ();
+ if (end < 0 || start > end || ((style & SWT.SINGLE) != 0 && start != end)) return;
+ if (itemCount == 0 || start >= itemCount) return;
+ start = Math.max (0, start);
+ end = Math.min (end, itemCount - 1);
+ select (start, end);
+ //TODO
+// setFocusIndex (start);
+ showSelection ();
+}
+
+/**
+ * Sets the column used by the sort indicator for the receiver. A null
+ * value will clear the sort indicator. The current sort column is cleared
+ * before the new column is set.
+ *
+ * @param column the column used by the sort indicator or <code>null</code>
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the column is disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public void setSortColumn (TableColumn column) {
+ checkWidget ();
+ if (column != null && column.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ //TODO
+// if (sortColumn != null && !sortColumn.isDisposed ()) {
+// sortColumn.setSortDirection (SWT.NONE);
+// }
+// sortColumn = column;
+// if (sortColumn != null && sortDirection != SWT.NONE) {
+// sortColumn.setSortDirection (sortDirection);
+// }
+}
+
+/**
+ * Sets the direction of the sort indicator for the receiver. The value
+ * can be one of <code>UP</code>, <code>DOWN</code> or <code>NONE</code>.
+ *
+ * @param direction the direction of the sort indicator
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public void setSortDirection (int direction) {
+ checkWidget ();
+ if ((direction & (SWT.UP | SWT.DOWN)) == 0 && direction != SWT.NONE) return;
+ //TODO
+// sortDirection = direction;
+// if (sortColumn != null && !sortColumn.isDisposed ()) {
+// sortColumn.setSortDirection (direction);
+// }
+}
+
+/**
+ * Sets the zero-relative index of the item which is currently
+ * at the top of the receiver. This index can change when items
+ * are scrolled or new items are added and removed.
+ *
+ * @param index the index of the top item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setTopIndex (int index) {
+ checkWidget ();
+ //TODO
+}
+
+/**
+ * Shows the column. If the column is already showing in the receiver,
+ * this method simply returns. Otherwise, the columns are scrolled until
+ * the column is visible.
+ *
+ * @param column the column to be shown
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the column is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the column has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void showColumn (TableColumn column) {
+ checkWidget ();
+ if (column == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (column.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (column.parent != this) return;
+ int index = indexOf (column);
+ if (!(0 <= index && index < columnCount)) return;
+ //TODO
+}
+
+/**
+ * Shows the item. If the item is already showing in the receiver,
+ * this method simply returns. Otherwise, the items are scrolled until
+ * the item is visible.
+ *
+ * @param item the item to be shown
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the item is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Table#showSelection()
+ */
+public void showItem (TableItem item) {
+ checkWidget ();
+ if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (item.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ OS.ListBox_ScrollIntoView (handle, item.handle);
+}
+
+/**
+ * Shows the selection. If the selection is already showing in the receiver,
+ * this method simply returns. Otherwise, the items are scrolled until
+ * the selection is visible.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Table#showItem(TableItem)
+ */
+public void showSelection () {
+ checkWidget ();
+ int itemCollection = OS.ItemsControl_Items (handle);
+ int list = OS.ListBox_SelectedItems (handle);
+ int enumerator = OS.IList_GetEnumerator (list);
+ if (OS.IEnumerator_MoveNext (enumerator)) {
+ int item = OS.IEnumerator_Current (enumerator);
+ OS.ListBox_ScrollIntoView (handle, item);
+ OS.GCHandle_Free (item);
+ }
+ OS.GCHandle_Free (enumerator);
+ OS.GCHandle_Free (list);
+ OS.GCHandle_Free (itemCollection);
+}
+
+int topHandle () {
+ return parentingHandle;
+}
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TableColumn.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TableColumn.java
new file mode 100644
index 0000000000..3f599cec79
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TableColumn.java
@@ -0,0 +1,570 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.events.*;
+
+/**
+ * Instances of this class represent a column in a table widget.
+ * <p><dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>LEFT, RIGHT, CENTER</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd> Move, Resize, Selection</dd>
+ * </dl>
+ * </p><p>
+ * Note: Only one of the styles LEFT, RIGHT and CENTER may be specified.
+ * </p><p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ */
+public class TableColumn extends Item {
+ static final int IMAGE_PART = 0;
+ static final int TEXT_PART = 1;
+ int headerHandle;
+ int stringPtr;
+ boolean moveable, resizable;
+ Table parent;
+
+
+/**
+ * Constructs a new instance of this class given its parent
+ * (which must be a <code>Table</code>) and a style value
+ * describing its behavior and appearance. The item is added
+ * to the end of the items maintained by its parent.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#LEFT
+ * @see SWT#RIGHT
+ * @see SWT#CENTER
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public TableColumn (Table parent, int style) {
+ this (parent, checkStyle (style), -1);
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * (which must be a <code>Table</code>), a style value
+ * describing its behavior and appearance, and the index
+ * at which to place it in the items maintained by its parent.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ * @param index the zero-relative index to store the receiver in its parent
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#LEFT
+ * @see SWT#RIGHT
+ * @see SWT#CENTER
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public TableColumn (Table parent, int style, int index) {
+ super (parent, checkStyle (style));
+// resizable = true;
+ this.parent = parent;
+ parent.createItem (this, index);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the control is moved or resized, by sending
+ * it one of the messages defined in the <code>ControlListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ControlListener
+ * @see #removeControlListener
+ */
+public void addControlListener(ControlListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Resize,typedListener);
+ addListener (SWT.Move,typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the control is selected, by sending
+ * it one of the messages defined in the <code>SelectionListener</code>
+ * interface.
+ * <p>
+ * <code>widgetSelected</code> is called when the column header is selected.
+ * <code>widgetDefaultSelected</code> is not called.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #removeSelectionListener
+ * @see SelectionEvent
+ */
+public void addSelectionListener (SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Selection,typedListener);
+ addListener (SWT.DefaultSelection,typedListener);
+}
+
+static int checkStyle (int style) {
+ return checkBits (style, SWT.LEFT, SWT.CENTER, SWT.RIGHT, 0, 0, 0);
+}
+
+int ConvertImage (int value, int targetType, int parameter, int culture) {
+ return image != null ? image.handle : 0;
+}
+
+int ConvertText (int value, int targetType, int parameter, int culture) {
+ int result = 0;
+ if (text != null) {
+ result = stringPtr;
+ if (result == 0) {
+ result = stringPtr = createDotNetString (text, false);
+ }
+ }
+ return result;
+}
+
+protected void checkSubclass () {
+ if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
+}
+
+void createHandle () {
+ handle = OS.gcnew_GridViewColumn ();
+ if (handle == 0) SWT.error (SWT.ERROR_NO_HANDLES);
+ headerHandle = OS.gcnew_GridViewColumnHeader ();
+ int content = OS.gcnew_IntPtr (jniRef);
+ OS.GridViewColumn_Header (handle, headerHandle);
+ OS.GridViewColumnHeader_Content (headerHandle, content);
+ OS.GCHandle_Free (content);
+}
+
+void destroyWidget () {
+ parent.destroyItem (this);
+ super.destroyWidget ();
+}
+
+/**
+ * Returns a value which describes the position of the
+ * text or image in the receiver. The value will be one of
+ * <code>LEFT</code>, <code>RIGHT</code> or <code>CENTER</code>.
+ *
+ * @return the alignment
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getAlignment () {
+ checkWidget ();
+ if ((style & SWT.LEFT) != 0) return SWT.LEFT;
+ if ((style & SWT.CENTER) != 0) return SWT.CENTER;
+ if ((style & SWT.RIGHT) != 0) return SWT.RIGHT;
+ return SWT.LEFT;
+}
+
+String getNameText () {
+ return getText ();
+}
+
+/**
+ * Returns the receiver's parent, which must be a <code>Table</code>.
+ *
+ * @return the receiver's parent
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Table getParent () {
+ checkWidget ();
+ return parent;
+}
+
+/**
+ * Gets the moveable attribute. A column that is
+ * not moveable cannot be reordered by the user
+ * by dragging the header but may be reordered
+ * by the programmer.
+ *
+ * @return the moveable attribute
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Table#getColumnOrder()
+ * @see Table#setColumnOrder(int[])
+ * @see TableColumn#setMoveable(boolean)
+ * @see SWT#Move
+ *
+ * @since 3.1
+ */
+public boolean getMoveable () {
+ checkWidget ();
+ return moveable;
+}
+
+/**
+ * Gets the resizable attribute. A column that is
+ * not resizable cannot be dragged by the user but
+ * may be resized by the programmer.
+ *
+ * @return the resizable attribute
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getResizable () {
+ checkWidget ();
+ return resizable;
+}
+
+/**
+ * Returns the receiver's tool tip text, or null if it has
+ * not been set.
+ *
+ * @return the receiver's tool tip text
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public String getToolTipText () {
+ checkWidget ();
+ int strPtr = OS.FrameworkElement_ToolTip (headerHandle);
+ String string = createJavaString (strPtr);
+ OS.GCHandle_Free (strPtr);
+ return string;
+}
+
+/**
+ * Gets the width of the receiver.
+ *
+ * @return the width
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getWidth () {
+ checkWidget ();
+ return (int) OS.GridViewColumn_ActualWidth(handle);
+}
+
+int findPart (int part) {
+ if (!OS.FrameworkElement_IsLoaded (headerHandle)) OS.UIElement_UpdateLayout (headerHandle);
+ int contentPresenterType = OS.ContentPresenter_typeid ();
+ int contentPresenter = findStackPanel (headerHandle, contentPresenterType);
+ OS.GCHandle_Free (contentPresenterType);
+ int result = OS.VisualTreeHelper_GetChild (contentPresenter, part);
+ OS.GCHandle_Free (contentPresenter);
+ return result;
+}
+
+int findStackPanel (int element, int contentPresenterType) {
+ int type = OS.Object_GetType (element);
+ boolean found = OS.Object_Equals (contentPresenterType, type);
+ OS.GCHandle_Free(type);
+ if (found) return OS.VisualTreeHelper_GetChild (element, 0);
+ int count = OS.VisualTreeHelper_GetChildrenCount (element);
+ for (int i = 0; i < count; i++) {
+ int child = OS.VisualTreeHelper_GetChild (element, i);
+ int result = findStackPanel (child, contentPresenterType);
+ OS.GCHandle_Free (child);
+ if (result != 0) return result;
+ }
+ return 0;
+}
+
+/**
+ * Causes the receiver to be resized to its preferred size.
+ * For a composite, this involves computing the preferred size
+ * from its layout, if there is one.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ */
+public void pack () {
+ checkWidget ();
+ int index = parent.indexOf (this);
+ if (index == -1) return;
+ int widthProperty = OS.GridViewColumn_WidthProperty ();
+ OS.DependencyObject_ClearValue (handle, widthProperty);
+ OS.GCHandle_Free (widthProperty);
+ OS.UIElement_UpdateLayout (headerHandle);
+}
+
+void releaseHandle () {
+ super.releaseHandle ();
+ if (handle != 0) OS.GCHandle_Free (handle);
+ handle = 0;
+ OS.GCHandle_Free (headerHandle);
+ parent = null;
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the control is moved or resized.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ControlListener
+ * @see #addControlListener
+ */
+public void removeControlListener (ControlListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Move, listener);
+ eventTable.unhook (SWT.Resize, listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the control is selected.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #addSelectionListener
+ */
+public void removeSelectionListener(SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Selection, listener);
+ eventTable.unhook (SWT.DefaultSelection,listener);
+}
+
+/**
+ * Controls how text and images will be displayed in the receiver.
+ * The argument should be one of <code>LEFT</code>, <code>RIGHT</code>
+ * or <code>CENTER</code>.
+ *
+ * @param alignment the new alignment
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setAlignment (int alignment) {
+ checkWidget ();
+ if ((alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER)) == 0) return;
+ int index = parent.indexOf (this);
+ if (index == -1 || index == 0) return;
+ style &= ~(SWT.LEFT | SWT.RIGHT | SWT.CENTER);
+ style |= alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER);
+ //TODO
+}
+
+public void setImage (Image image) {
+ checkWidget ();
+ super.setImage (image);
+ // TODO
+}
+
+/**
+ * Sets the moveable attribute. A column that is
+ * moveable can be reordered by the user by dragging
+ * the header. A column that is not moveable cannot be
+ * dragged by the user but may be reordered
+ * by the programmer.
+ *
+ * @param moveable the moveable attribute
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Table#setColumnOrder(int[])
+ * @see Table#getColumnOrder()
+ * @see TableColumn#getMoveable()
+ * @see SWT#Move
+ *
+ * @since 3.1
+ */
+public void setMoveable (boolean moveable) {
+ checkWidget ();
+ this.moveable = moveable;
+ parent.updateMoveable ();
+}
+
+/**
+ * Sets the resizable attribute. A column that is
+ * resizable can be resized by the user dragging the
+ * edge of the header. A column that is not resizable
+ * cannot be dragged by the user but may be resized
+ * by the programmer.
+ *
+ * @param resizable the resize attribute
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setResizable (boolean resizable) {
+ checkWidget ();
+ this.resizable = resizable;
+}
+
+void setSortDirection (int direction) {
+ //TODO
+}
+
+public void setText (String string) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (string.equals (text)) return;
+ text = string;
+ if (stringPtr != 0) {
+ OS.GCHandle_Free (stringPtr);
+ stringPtr = 0;
+ }
+ if (OS.FrameworkElement_IsLoaded(headerHandle)) {
+ int part = findPart (TEXT_PART);
+ int property = OS.TextBlock_TextProperty ();
+ int bindingExpression = OS.FrameworkElement_GetBindingExpression (part, property);
+ OS.BindingExpression_UpdateTarget (bindingExpression);
+ OS.GCHandle_Free (part);
+ OS.GCHandle_Free (property);
+ OS.GCHandle_Free (bindingExpression);
+ }
+}
+
+/**
+ * Sets the receiver's tool tip text to the argument, which
+ * may be null indicating that no tool tip text should be shown.
+ *
+ * @param string the new tool tip text (or null)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public void setToolTipText (String string) {
+ checkWidget ();
+ int strPtr = createDotNetString (string, false);
+ OS.FrameworkElement_ToolTip (headerHandle, strPtr);
+ OS.GCHandle_Free (strPtr);
+}
+
+/**
+ * Sets the width of the receiver.
+ *
+ * @param width the new width
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setWidth (int width) {
+ checkWidget ();
+ OS.GridViewColumn_Width (handle, width);
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TableItem.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TableItem.java
new file mode 100644
index 0000000000..15259b4c6d
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TableItem.java
@@ -0,0 +1,1087 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Instances of this class represent a selectable user interface object
+ * that represents an item in a table.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>(none)</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * <p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ */
+
+public class TableItem extends Item {
+ Table parent;
+ String [] strings;
+ int [] stringHandle;
+ Image [] images;
+
+ boolean checked, grayed, cached;
+// int imageIndent, background = -1, foreground = -1, font = -1;
+// int [] cellBackground, cellForeground, cellFont;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * (which must be a <code>Table</code>) and a style value
+ * describing its behavior and appearance. The item is added
+ * to the end of the items maintained by its parent.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public TableItem (Table parent, int style) {
+ this (parent, style, -1);
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * (which must be a <code>Table</code>), a style value
+ * describing its behavior and appearance, and the index
+ * at which to place it in the items maintained by its parent.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ * @param index the zero-relative index to store the receiver in its parent
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public TableItem (Table parent, int style, int index) {
+ this (parent, style, index, 0);
+}
+
+TableItem (Table parent, int style, int index, int handle) {
+ super (parent, style);
+ this.parent = parent;
+ this.handle = handle;
+ if (handle == 0) {
+ parent.createItem (this, index);
+ } else {
+ createWidget ();
+ }
+}
+
+protected void checkSubclass () {
+ if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
+}
+
+void createHandle () {
+ if (handle == 0) {
+ handle = OS.gcnew_ListViewItem ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ }
+ int content = OS.gcnew_IntPtr (jniRef);
+ OS.ContentControl_Content (handle, content);
+ OS.GCHandle_Free (content);
+}
+
+void clear () {
+ text = "";
+ image = null;
+ if (stringHandle != null) {
+ for (int i = 0; i < stringHandle.length; i++) {
+ if (stringHandle [i] != 0) OS.GCHandle_Free (stringHandle [i]);
+ }
+ }
+ stringHandle = null;
+ strings = null;
+ images = null;
+ checked = grayed = false;
+// background = foreground = font = -1;
+// cellBackground = cellForeground = cellFont = null;
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = false;
+ int count = Math.max (1, parent.columnCount);
+ for (int i = 0; i < count; i++) {
+ resetText (i);
+ resetImage (i);
+ }
+}
+
+void deregister () {
+ display.removeWidget (handle);
+}
+
+void destroyWidget () {
+ parent.destroyItem (this);
+ super.destroyWidget ();
+}
+
+int findRowPresenter (int current, int rowPresenterType) {
+ int type = OS.Object_GetType (current);
+ boolean found = OS.Object_Equals (rowPresenterType, type);
+ OS.GCHandle_Free (type);
+ if (found) return current;
+ int childCount = OS.VisualTreeHelper_GetChildrenCount (current);
+ for (int i = 0; i < childCount; i++) {
+ int child = OS.VisualTreeHelper_GetChild (current, i);
+ int result = findRowPresenter (child, rowPresenterType);
+ if (child != result) OS.GCHandle_Free (child);
+ if (result != 0) return result;
+ }
+ return 0;
+}
+
+int findPart (int column, String partName) {
+ if (!OS.FrameworkElement_IsLoaded (handle)) OS.UIElement_UpdateLayout (handle);
+ if (!OS.FrameworkElement_IsLoaded (handle)) return 0;
+ int rowPresenterType = OS.GridViewRowPresenter_typeid ();
+ int rowPresenter = findRowPresenter (handle, rowPresenterType);
+ int contentPresenter = OS.VisualTreeHelper_GetChild (rowPresenter, column);
+ int columns = OS.GridView_Columns (parent.gridViewHandle);
+ int columnHandle = OS.GridViewColumnCollection_default (columns, column);
+ int cellTemplate = OS.GridViewColumn_CellTemplate (columnHandle);
+ int name = createDotNetString (partName, false);
+ int result = OS.FrameworkTemplate_FindName (cellTemplate, name, contentPresenter);
+ OS.GCHandle_Free (rowPresenterType);
+ OS.GCHandle_Free (rowPresenter);
+ OS.GCHandle_Free (contentPresenter);
+ OS.GCHandle_Free (columns);
+ OS.GCHandle_Free (columnHandle);
+ OS.GCHandle_Free (cellTemplate);
+ OS.GCHandle_Free (name);
+ return result;
+}
+
+/**
+ * Returns the receiver's background color.
+ *
+ * @return the background color
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.0
+ */
+public Color getBackground () {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ //TODO
+ return parent.getBackground();
+// if (background == -1) return parent.getBackground ();
+// return Color.win32_new (display, background);
+}
+
+/**
+ * Returns the background color at the given column index in the receiver.
+ *
+ * @param index the column index
+ * @return the background color
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public Color getBackground (int index) {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ int count = Math.max (1, parent.getColumnCount ());
+ if (0 > index || index > count - 1) return getBackground ();
+ //TODO
+ return parent.getBackground();
+// int pixel = cellBackground != null ? cellBackground [index] : -1;
+// return pixel == -1 ? getBackground () : Color.win32_new (display, pixel);
+}
+
+/**
+ * Returns a rectangle describing the receiver's size and location
+ * relative to its parent.
+ *
+ * @return the receiver's bounding rectangle
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public Rectangle getBounds () {
+ checkWidget();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ int parentHandle = parent.topHandle ();
+ int point = OS.gcnew_Point (0, 0);
+ if (point == 0) error (SWT.ERROR_NO_HANDLES);
+ int location = OS.UIElement_TranslatePoint (handle, point, parentHandle);
+ int x = (int) OS.Point_X (location);
+ int y = (int) OS.Point_Y (location);
+ OS.GCHandle_Free (point);
+ OS.GCHandle_Free (location);
+ int width = (int) OS.FrameworkElement_ActualWidth (handle);
+ int height = (int) OS.FrameworkElement_ActualHeight (handle);
+ return new Rectangle (x, y, width, height);
+}
+
+/**
+ * Returns a rectangle describing the receiver's size and location
+ * relative to its parent at a column in the table.
+ *
+ * @param index the index that specifies the column
+ * @return the receiver's bounding column rectangle
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Rectangle getBounds (int index) {
+ checkWidget();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ if (!(0 <= index && index < parent.columnCount)) return new Rectangle (0, 0, 0, 0);
+ int rowPresenterType = OS.GridViewRowPresenter_typeid ();
+ int rowPresenter = findRowPresenter (handle, rowPresenterType);
+ int contentPresenter = OS.VisualTreeHelper_GetChild (rowPresenter, index);
+ int point = OS.gcnew_Point (0, 0);
+ if (point == 0) error (SWT.ERROR_NO_HANDLES);
+ int parentHandle = parent.topHandle ();
+ int location = OS.UIElement_TranslatePoint (contentPresenter, point, parentHandle);
+ int x = (int) OS.Point_X (location);
+ int y = (int) OS.Point_Y (location);
+ int width = (int) OS.FrameworkElement_ActualWidth (contentPresenter);
+ int height = (int) OS.FrameworkElement_ActualHeight (handle);
+ OS.GCHandle_Free (rowPresenter);
+ OS.GCHandle_Free (rowPresenterType);
+ OS.GCHandle_Free (point);
+ OS.GCHandle_Free (location);
+ OS.GCHandle_Free (contentPresenter);
+ return new Rectangle (x, y, width, height);
+}
+
+/**
+ * Returns <code>true</code> if the receiver is checked,
+ * and false otherwise. When the parent does not have
+ * the <code>CHECK</code> style, return false.
+ *
+ * @return the checked state of the checkbox
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getChecked () {
+ checkWidget();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ if ((parent.style & SWT.CHECK) == 0) return false;
+ return checked;
+}
+
+/**
+ * Returns the font that the receiver will use to paint textual information for this item.
+ *
+ * @return the receiver's font
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public Font getFont () {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ //TODO
+ return parent.getFont ();
+// return font == -1 ? parent.getFont () : Font.win32_new (display, font);
+}
+
+/**
+ * Returns the font that the receiver will use to paint textual information
+ * for the specified cell in this item.
+ *
+ * @param index the column index
+ * @return the receiver's font
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public Font getFont (int index) {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ int count = Math.max (1, parent.getColumnCount ());
+ if (0 > index || index > count -1) return getFont ();
+ //TODO
+ return parent.getFont ();
+// int hFont = (cellFont != null) ? cellFont [index] : font;
+// return hFont == -1 ? getFont () : Font.win32_new (display, hFont);
+}
+
+/**
+ * Returns the foreground color that the receiver will use to draw.
+ *
+ * @return the receiver's foreground color
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.0
+ */
+public Color getForeground () {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ //TODO
+ return parent.getForeground ();
+// if (foreground == -1) return parent.getForeground ();
+// return Color.win32_new (display, foreground);
+}
+
+/**
+ *
+ * Returns the foreground color at the given column index in the receiver.
+ *
+ * @param index the column index
+ * @return the foreground color
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public Color getForeground (int index) {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ int count = Math.max (1, parent.getColumnCount ());
+ if (0 > index || index > count -1) return getForeground ();
+ //TODO
+ return parent.getForeground ();
+// int pixel = cellForeground != null ? cellForeground [index] : -1;
+// return pixel == -1 ? getForeground () : Color.win32_new (display, pixel);
+}
+
+/**
+ * Returns <code>true</code> if the receiver is grayed,
+ * and false otherwise. When the parent does not have
+ * the <code>CHECK</code> style, return false.
+ *
+ * @return the grayed state of the checkbox
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getGrayed () {
+ checkWidget();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ if ((parent.style & SWT.CHECK) == 0) return false;
+ return grayed;
+}
+
+public Image getImage () {
+ checkWidget();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ return getImage (0);
+}
+
+/**
+ * Returns the image stored at the given column index in the receiver,
+ * or null if the image has not been set or if the column does not exist.
+ *
+ * @param index the column index
+ * @return the image stored at the given column index in the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Image getImage (int index) {
+ checkWidget();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ if (images != null) {
+ if (0 <= index && index < images.length) return images [index];
+ }
+ return null;
+}
+
+/**
+ * Returns a rectangle describing the size and location
+ * relative to its parent of an image at a column in the
+ * table. An empty rectangle is returned if index exceeds
+ * the index of the table's last column.
+ *
+ * @param index the index that specifies the column
+ * @return the receiver's bounding image rectangle
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Rectangle getImageBounds (int index) {
+ checkWidget();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ if (!(0 <= index && index < parent.columnCount)) return new Rectangle (0, 0, 0, 0);
+ int parentHandle = parent.topHandle ();
+ int part = findPart (index, Table.IMAGE_PART_NAME);
+ int point = OS.gcnew_Point (0, 0);
+ if (point == 0) error (SWT.ERROR_NO_HANDLES);
+ int location = OS.UIElement_TranslatePoint (part, point, parentHandle);
+ int x = (int) OS.Point_X (location);
+ int y = (int) OS.Point_Y (location);
+ OS.GCHandle_Free (point);
+ OS.GCHandle_Free (location);
+ int width = (int) OS.FrameworkElement_ActualWidth (part);
+ int height = (int) OS.FrameworkElement_ActualHeight (part);
+ OS.GCHandle_Free (part);
+ return new Rectangle (x, y, width, height);
+}
+
+/**
+ * Gets the image indent.
+ *
+ * @return the indent
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getImageIndent () {
+ checkWidget();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ //TODO
+ return 0;
+// return imageIndent;
+}
+
+String getNameText () {
+ if ((parent.style & SWT.VIRTUAL) != 0) {
+ if (!cached) return "*virtual*"; //$NON-NLS-1$
+ }
+ return super.getNameText ();
+}
+
+/**
+ * Returns the receiver's parent, which must be a <code>Table</code>.
+ *
+ * @return the receiver's parent
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Table getParent () {
+ checkWidget();
+ return parent;
+}
+
+public String getText () {
+ checkWidget();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ return getText (0);
+}
+
+/**
+ * Returns the text stored at the given column index in the receiver,
+ * or empty string if the text has not been set.
+ *
+ * @param index the column index
+ * @return the text stored at the given column index in the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String getText (int index) {
+ checkWidget();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ if (strings != null) {
+ if (0 <= index && index < strings.length) {
+ String string = strings [index];
+ return string != null ? string : "";
+ }
+ }
+ return "";
+}
+
+Control getWidgetControl () {
+ return parent;
+}
+
+void register () {
+ display.addWidget (handle, this);
+}
+
+void releaseHandle () {
+ super.releaseHandle ();
+ if (handle != 0) OS.GCHandle_Free (handle);
+ handle = 0;
+ parent = null;
+}
+
+void releaseWidget () {
+ super.releaseWidget ();
+ if (stringHandle != null) {
+ for (int i = 0; i < stringHandle.length; i++) {
+ if (stringHandle [i] != 0) OS.GCHandle_Free (stringHandle [i]);
+ }
+ }
+ stringHandle = null;
+ strings = null;
+ images = null;
+}
+
+public void resetCheck () {
+ int part = findPart (0, Table.CHECKBOX_PART_NAME);
+ if (part == 0) return;
+ parent.ignoreSelection = true;
+ OS.ToggleButton_IsChecked (part, checked);
+ parent.ignoreSelection = false;
+ OS.GCHandle_Free (part);
+}
+
+void resetImage (int index) {
+ if (OS.FrameworkElement_IsLoaded (handle)) {
+ int part = findPart (index, Table.IMAGE_PART_NAME);
+ int property = OS.Image_SourceProperty ();
+ int bindingExpression = OS.FrameworkElement_GetBindingExpression (part, property);
+ OS.BindingExpression_UpdateTarget (bindingExpression);
+ OS.GCHandle_Free (part);
+ OS.GCHandle_Free (property);
+ OS.GCHandle_Free (bindingExpression);
+ }
+}
+
+void resetText (int index) {
+ if (OS.FrameworkElement_IsLoaded (handle)) {
+ int part = findPart (index, Table.TEXT_PART_NAME);
+ int property = OS.TextBlock_TextProperty ();
+ int bindingExpression = OS.FrameworkElement_GetBindingExpression (part, property);
+ OS.BindingExpression_UpdateTarget (bindingExpression);
+ OS.GCHandle_Free (part);
+ OS.GCHandle_Free (property);
+ OS.GCHandle_Free (bindingExpression);
+ }
+}
+
+/**
+ * Sets the receiver's background color to the color specified
+ * by the argument, or to the default system color for the item
+ * if the argument is null.
+ *
+ * @param color the new color (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.0
+ */
+public void setBackground (Color color) {
+ checkWidget ();
+ if (color != null && color.isDisposed ()) {
+ SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+// int pixel = -1;
+ //TODO
+// if (color != null) {
+// parent.setCustomDraw (true);
+// pixel = color.handle;
+// }
+// if (background == pixel) return;
+// background = pixel;
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
+// redraw ();
+}
+
+/**
+ * Sets the background color at the given column index in the receiver
+ * to the color specified by the argument, or to the default system color for the item
+ * if the argument is null.
+ *
+ * @param index the column index
+ * @param color the new color (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void setBackground (int index, Color color) {
+ checkWidget ();
+ if (color != null && color.isDisposed ()) {
+ SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+ int count = Math.max (1, parent.getColumnCount ());
+ if (0 > index || index > count - 1) return;
+// int pixel = -1;
+ //TODO
+// if (color != null) {
+// parent.setCustomDraw (true);
+// pixel = color.handle;
+// }
+// if (cellBackground == null) {
+// cellBackground = new int [count];
+// for (int i = 0; i < count; i++) {
+// cellBackground [i] = -1;
+// }
+// }
+// if (cellBackground [index] == pixel) return;
+// cellBackground [index] = pixel;
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
+// redraw (index, true, true);
+}
+
+/**
+ * Sets the checked state of the checkbox for this item. This state change
+ * only applies if the Table was created with the SWT.CHECK style.
+ *
+ * @param checked the new checked state of the checkbox
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setChecked (boolean checked) {
+ checkWidget();
+ if ((parent.style & SWT.CHECK) == 0) return;
+ if (this.checked == checked) return;
+ this.checked = checked;
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
+ resetCheck();
+}
+
+/**
+ * Sets the font that the receiver will use to paint textual information
+ * for this item to the font specified by the argument, or to the default font
+ * for that kind of control if the argument is null.
+ *
+ * @param font the new font (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void setFont (Font font){
+ checkWidget ();
+ if (font != null && font.isDisposed ()) {
+ SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+// int hFont = -1;
+// if (font != null) {
+// parent.setCustomDraw (true);
+// hFont = font.handle;
+// }
+// if (this.font == hFont) return;
+// this.font = hFont;
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
+// /*
+// * Bug in Windows. Despite the fact that every item in the
+// * table always has LPSTR_TEXTCALLBACK, Windows caches the
+// * bounds for the selected items. This means that
+// * when you change the string to be something else, Windows
+// * correctly asks you for the new string but when the item
+// * is selected, the selection draws using the bounds of the
+// * previous item. The fix is to reset LPSTR_TEXTCALLBACK
+// * even though it has not changed, causing Windows to flush
+// * cached bounds.
+// */
+// if ((parent.style & SWT.VIRTUAL) == 0 && cached) {
+// int itemIndex = parent.indexOf (this);
+// if (itemIndex != -1) {
+// int hwnd = parent.handle;
+// LVITEM lvItem = new LVITEM ();
+// lvItem.mask = OS.LVIF_TEXT;
+// lvItem.iItem = itemIndex;
+// lvItem.pszText = OS.LPSTR_TEXTCALLBACK;
+// OS.SendMessage (hwnd, OS.LVM_SETITEM, 0, lvItem);
+// cached = false;
+// }
+// }
+// parent.setScrollWidth (this, false);
+// redraw ();
+}
+
+/**
+ * Sets the font that the receiver will use to paint textual information
+ * for the specified cell in this item to the font specified by the
+ * argument, or to the default font for that kind of control if the
+ * argument is null.
+ *
+ * @param index the column index
+ * @param font the new font (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void setFont (int index, Font font) {
+ checkWidget ();
+ if (font != null && font.isDisposed ()) {
+ SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+ int count = Math.max (1, parent.getColumnCount ());
+ if (0 > index || index > count - 1) return;
+ //TODO
+// int hFont = -1;
+// if (font != null) {
+// parent.setCustomDraw (true);
+// hFont = font.handle;
+// }
+// if (cellFont == null) {
+// cellFont = new int [count];
+// for (int i = 0; i < count; i++) {
+// cellFont [i] = -1;
+// }
+// }
+// if (cellFont [index] == hFont) return;
+// cellFont [index] = hFont;
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
+// if (index == 0) {
+// /*
+// * Bug in Windows. Despite the fact that every item in the
+// * table always has LPSTR_TEXTCALLBACK, Windows caches the
+// * bounds for the selected items. This means that
+// * when you change the string to be something else, Windows
+// * correctly asks you for the new string but when the item
+// * is selected, the selection draws using the bounds of the
+// * previous item. The fix is to reset LPSTR_TEXTCALLBACK
+// * even though it has not changed, causing Windows to flush
+// * cached bounds.
+// */
+// if ((parent.style & SWT.VIRTUAL) == 0 && cached) {
+// int itemIndex = parent.indexOf (this);
+// if (itemIndex != -1) {
+// int hwnd = parent.handle;
+// LVITEM lvItem = new LVITEM ();
+// lvItem.mask = OS.LVIF_TEXT;
+// lvItem.iItem = itemIndex;
+// lvItem.pszText = OS.LPSTR_TEXTCALLBACK;
+// OS.SendMessage (hwnd, OS.LVM_SETITEM, 0, lvItem);
+// cached = false;
+// }
+// }
+// parent.setScrollWidth (this, false);
+// }
+// redraw (index, true, false);
+}
+
+/**
+ * Sets the receiver's foreground color to the color specified
+ * by the argument, or to the default system color for the item
+ * if the argument is null.
+ *
+ * @param color the new color (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.0
+ */
+public void setForeground (Color color){
+ checkWidget ();
+ if (color != null && color.isDisposed ()) {
+ SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+ //TODO
+// int pixel = -1;
+// if (color != null) {
+// parent.setCustomDraw (true);
+// pixel = color.handle;
+// }
+// if (foreground == pixel) return;
+// foreground = pixel;
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
+// redraw ();
+}
+
+/**
+ * Sets the foreground color at the given column index in the receiver
+ * to the color specified by the argument, or to the default system color for the item
+ * if the argument is null.
+ *
+ * @param index the column index
+ * @param color the new color (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void setForeground (int index, Color color){
+ checkWidget ();
+ if (color != null && color.isDisposed ()) {
+ SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+ int count = Math.max (1, parent.getColumnCount ());
+ if (0 > index || index > count - 1) return;
+ //TODO
+// int pixel = -1;
+// if (color != null) {
+// parent.setCustomDraw (true);
+// pixel = color.handle;
+// }
+// if (cellForeground == null) {
+// cellForeground = new int [count];
+// for (int i = 0; i < count; i++) {
+// cellForeground [i] = -1;
+// }
+// }
+// if (cellForeground [index] == pixel) return;
+// cellForeground [index] = pixel;
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
+// redraw (index, true, false);
+}
+
+/**
+ * Sets the grayed state of the checkbox for this item. This state change
+ * only applies if the Table was created with the SWT.CHECK style.
+ *
+ * @param grayed the new grayed state of the checkbox;
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setGrayed (boolean grayed) {
+ checkWidget();
+ if ((parent.style & SWT.CHECK) == 0) return;
+ if (this.grayed == grayed) return;
+ this.grayed = grayed;
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
+}
+
+/**
+ * Sets the image for multiple columns in the table.
+ *
+ * @param images the array of new images
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the array of images is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if one of the images has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setImage (Image [] images) {
+ checkWidget();
+ if (images == null) error (SWT.ERROR_NULL_ARGUMENT);
+ for (int i=0; i<images.length; i++) {
+ setImage (i, images [i]);
+ }
+}
+
+/**
+ * Sets the receiver's image at a column.
+ *
+ * @param index the column index
+ * @param image the new image
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setImage (int index, Image image) {
+ checkWidget();
+ if (image != null && image.isDisposed ()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ int count = Math.max (1, parent.getColumnCount ());
+ if (0 > index || index > count - 1) return;
+ if (images == null) {
+ images = new Image [count];
+ }
+ images [index] = image;
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
+ resetImage (index);
+}
+
+public void setImage (Image image) {
+ checkWidget ();
+ setImage (0, image);
+}
+
+/**
+ * Sets the indent of the first column's image, expressed in terms of the image's width.
+ *
+ * @param indent the new indent
+ *
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @deprecated this functionality is not supported on most platforms
+ */
+public void setImageIndent (int indent) {
+ checkWidget();
+}
+
+/**
+ * Sets the text for multiple columns in the table.
+ *
+ * @param strings the array of new strings
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setText (String [] strings) {
+ checkWidget();
+ if (strings == null) error (SWT.ERROR_NULL_ARGUMENT);
+ for (int i=0; i<strings.length; i++) {
+ String string = strings [i];
+ if (string != null) setText (i, string);
+ }
+}
+
+/**
+ * Sets the receiver's text at a column
+ *
+ * @param index the column index
+ * @param string the new text
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setText (int index, String string) {
+ checkWidget();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int count = Math.max(1, parent.getColumnCount ());
+ if (0 > index || index > count - 1) return;
+
+ if (strings == null) {
+ strings = new String [count];
+ }
+ if (string.equals (strings [index])) return;
+ strings [index] = string;
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
+ if (stringHandle != null && stringHandle [index] != 0) {
+ OS.GCHandle_Free (stringHandle [index]);
+ stringHandle [index] = 0;
+ }
+ resetText (index);
+}
+
+public void setText (String string) {
+ checkWidget();
+ setText (0, string);
+}
+
+
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Text.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Text.java
new file mode 100644
index 0000000000..46ddd4bbf5
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Text.java
@@ -0,0 +1,1353 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.events.*;
+
+/**
+ * Instances of this class are selectable user interface
+ * objects that allow the user to enter and modify text.
+ * <p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>CENTER, LEFT, MULTI, PASSWORD, SINGLE, RIGHT, READ_ONLY, WRAP</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>DefaultSelection, Modify, Verify</dd>
+ * </dl>
+ * <p>
+ * Note: Only one of the styles MULTI and SINGLE may be specified.
+ * </p><p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ */
+public class Text extends Scrollable {
+ boolean doubleClick;
+
+ /**
+ * The maximum number of characters that can be entered
+ * into a text widget.
+ * <p>
+ * Note that this value is platform dependent, based upon
+ * the native widget implementation.
+ * </p>
+ */
+ public static final int LIMIT;
+
+ /**
+ * The delimiter used by multi-line text widgets. When text
+ * is queried and from the widget, it will be delimited using
+ * this delimiter.
+ */
+ public static final String DELIMITER;
+
+ /*
+ * This code is intentionally commented.
+ */
+// static final char PASSWORD;
+
+ /*
+ * These values can be different on different platforms.
+ * Therefore they are not initialized in the declaration
+ * to stop the compiler from inlining.
+ */
+ static {
+ LIMIT = 0x7FFFFFFF;
+ DELIMITER = "\r\n";
+ }
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#SINGLE
+ * @see SWT#MULTI
+ * @see SWT#READ_ONLY
+ * @see SWT#WRAP
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Text (Composite parent, int style) {
+ super (parent, checkStyle (style));
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the receiver's text is modified, by sending
+ * it one of the messages defined in the <code>ModifyListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ModifyListener
+ * @see #removeModifyListener
+ */
+public void addModifyListener (ModifyListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Modify, typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the control is selected, by sending
+ * it one of the messages defined in the <code>SelectionListener</code>
+ * interface.
+ * <p>
+ * <code>widgetSelected</code> is not called for texts.
+ * <code>widgetDefaultSelected</code> is typically called when ENTER is pressed in a single-line text.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #removeSelectionListener
+ * @see SelectionEvent
+ */
+public void addSelectionListener (SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Selection, typedListener);
+ addListener (SWT.DefaultSelection, typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the receiver's text is verified, by sending
+ * it one of the messages defined in the <code>VerifyListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see VerifyListener
+ * @see #removeVerifyListener
+ */
+public void addVerifyListener (VerifyListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Verify, typedListener);
+}
+
+/**
+ * Appends a string.
+ * <p>
+ * The new text is appended to the text at
+ * the end of the widget.
+ * </p>
+ *
+ * @param string the string to be appended
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void append (String string) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if ((style & SWT.PASSWORD) != 0) return;
+ int strPtr = createDotNetString (string, false);
+ OS.TextBoxBase_AppendText (handle, strPtr);
+ OS.TextBoxBase_ScrollToEnd (handle);
+ OS.GCHandle_Free (strPtr);
+}
+
+static int checkStyle (int style) {
+ if ((style & SWT.SINGLE) != 0 && (style & SWT.MULTI) != 0) {
+ style &= ~SWT.MULTI;
+ }
+ style = checkBits (style, SWT.LEFT, SWT.CENTER, SWT.RIGHT, 0, 0, 0);
+ if ((style & SWT.SINGLE) != 0) style &= ~(SWT.H_SCROLL | SWT.V_SCROLL | SWT.WRAP);
+ if ((style & SWT.WRAP) != 0) {
+ style |= SWT.MULTI;
+ style &= ~SWT.H_SCROLL;
+ }
+ if ((style & SWT.MULTI) != 0) style &= ~SWT.PASSWORD;
+ if ((style & (SWT.SINGLE | SWT.MULTI)) != 0) return style;
+ if ((style & (SWT.H_SCROLL | SWT.V_SCROLL)) != 0) return style | SWT.MULTI;
+ return style | SWT.SINGLE;
+}
+
+/**
+ * Clears the selection.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void clearSelection () {
+ checkWidget ();
+ if ((style & SWT.PASSWORD) != 0)
+ OS.TextBox_SelectionLength (handle, 0);
+}
+
+/**
+ * Copies the selected text.
+ * <p>
+ * The current selection is copied to the clipboard.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void copy () {
+ checkWidget ();
+ if ((style & SWT.PASSWORD) != 0)
+ OS.TextBoxBase_Copy (handle);
+}
+
+void createHandle () {
+ if ((style & SWT.PASSWORD) != 0) {
+ handle = OS.gcnew_PasswordBox ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ return;
+ }
+ handle = OS.gcnew_TextBox ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ if ((style & SWT.MULTI) != 0) {
+ OS.TextBoxBase_AcceptsReturn (handle, true);
+ OS.TextBoxBase_AcceptsTab (handle, true);
+ if ((style & SWT.WRAP) != 0) OS.TextBox_TextWrapping (handle, OS.TextWrapping_Wrap);
+ }
+ if ((style & SWT.READ_ONLY) != 0) OS.TextBoxBase_IsReadOnly (handle, true);
+ if ((style & SWT.CENTER) != 0) OS.Control_HorizontalContentAlignment (handle, OS.HorizontalAlignment_Center);
+ if ((style & SWT.RIGHT) != 0) OS.Control_HorizontalContentAlignment (handle, OS.HorizontalAlignment_Right);
+ if ((style & SWT.V_SCROLL) != 0) OS.TextBoxBase_VerticalScrollBarVisibility (handle, OS.ScrollBarVisibility_Visible);
+ if ((style & SWT.H_SCROLL) != 0) OS.TextBoxBase_HorizontalScrollBarVisibility (handle, OS.ScrollBarVisibility_Visible);
+}
+
+void createWidget () {
+ super.createWidget ();
+ doubleClick = true;
+// setTabStops (8);
+}
+
+/**
+ * Cuts the selected text.
+ * <p>
+ * The current selection is first copied to the
+ * clipboard and then deleted from the widget.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void cut () {
+ checkWidget ();
+ if ((style & SWT.READ_ONLY) != 0) return;
+ if ((style & SWT.PASSWORD) != 0) return;
+ OS.TextBoxBase_Cut (handle);
+}
+
+/**
+ * Returns the line number of the caret.
+ * <p>
+ * The line number of the caret is returned.
+ * </p>
+ *
+ * @return the line number
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getCaretLineNumber () {
+ checkWidget ();
+ if ((style & SWT.SINGLE) != 0) return 0;
+ if ((style & SWT.PASSWORD) != 0) return 0;
+ int caretIndex = OS.TextBox_CaretIndex (handle);
+ return OS.TextBox_GetLineIndexFromCharacterIndex (handle, caretIndex);
+}
+
+/**
+ * Returns a point describing the receiver's location relative
+ * to its parent (or its display if its parent is null).
+ * <p>
+ * The location of the caret is returned.
+ * </p>
+ *
+ * @return a point, the location of the caret
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Point getCaretLocation () {
+ checkWidget ();
+ if ((style & SWT.PASSWORD) != 0) return new Point (0, 0);
+ int caretIndex = OS.TextBox_CaretIndex (handle);
+ int rect = OS.TextBox_GetRectFromCharacterIndex (handle, caretIndex);
+ Point result = new Point ((int)OS.Rect_X (rect), (int)OS.Rect_Y (rect));
+ OS.GCHandle_Free (rect);
+ return result;
+}
+
+/**
+ * Returns the character position of the caret.
+ * <p>
+ * Indexing is zero based.
+ * </p>
+ *
+ * @return the position of the caret
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getCaretPosition () {
+ checkWidget ();
+ if ((style & SWT.PASSWORD) != 0) return 0;
+ return OS.TextBox_CaretIndex (handle);
+}
+
+/**
+ * Returns the number of characters.
+ *
+ * @return number of characters in the widget
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getCharCount () {
+ checkWidget ();
+ int text;
+ if ((style & SWT.PASSWORD) != 0) {
+ text = OS.PasswordBox_Password (handle);
+ } else {
+ text = OS.TextBox_Text (handle);
+ }
+ int length = OS.String_Length (text);
+ OS.GCHandle_Free (text);
+ return length;
+}
+
+/**
+ * Returns the double click enabled flag.
+ * <p>
+ * The double click flag enables or disables the
+ * default action of the text widget when the user
+ * double clicks.
+ * </p>
+ *
+ * @return whether or not double click is enabled
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getDoubleClickEnabled () {
+ checkWidget ();
+ return doubleClick;
+}
+
+/**
+ * Returns the echo character.
+ * <p>
+ * The echo character is the character that is
+ * displayed when the user enters text or the
+ * text is changed by the programmer.
+ * </p>
+ *
+ * @return the echo character
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #setEchoChar
+ */
+public char getEchoChar () {
+ checkWidget ();
+ if ((style & SWT.PASSWORD) == 0) return 0;
+ return OS.PasswordBox_PasswordChar (handle);
+}
+
+/**
+ * Returns the editable state.
+ *
+ * @return whether or not the receiver is editable
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getEditable () {
+ checkWidget ();
+ if ((style & SWT.PASSWORD) != 0) return true;
+ return OS.TextBoxBase_IsReadOnly (handle);
+}
+
+/**
+ * Returns the number of lines.
+ *
+ * @return the number of lines in the widget
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getLineCount () {
+ checkWidget ();
+ if ((style & SWT.PASSWORD) != 0) return 1;
+ return OS.TextBox_LineCount (handle);
+}
+
+/**
+ * Returns the line delimiter.
+ *
+ * @return a string that is the line delimiter
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #DELIMITER
+ */
+public String getLineDelimiter () {
+ checkWidget ();
+ return DELIMITER;
+}
+
+/**
+ * Returns the height of a line.
+ *
+ * @return the height of a row of text
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getLineHeight () {
+ checkWidget ();
+ //FIXME
+ return 10;
+}
+
+/**
+ * Returns the orientation of the receiver, which will be one of the
+ * constants <code>SWT.LEFT_TO_RIGHT</code> or <code>SWT.RIGHT_TO_LEFT</code>.
+ *
+ * @return the orientation style
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public int getOrientation () {
+ checkWidget();
+ return style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
+}
+
+/**
+ * Returns a <code>Point</code> whose x coordinate is the
+ * character position representing the start of the selected
+ * text, and whose y coordinate is the character position
+ * representing the end of the selection. An "empty" selection
+ * is indicated by the x and y coordinates having the same value.
+ * <p>
+ * Indexing is zero based. The range of a selection is from
+ * 0..N where N is the number of characters in the widget.
+ * </p>
+ *
+ * @return a point representing the selection start and end
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Point getSelection () {
+ checkWidget ();
+ if ((style & SWT.PASSWORD) != 0) return new Point (0, 0);
+ int start = OS.TextBox_SelectionStart (handle);
+ int length = OS.TextBox_SelectionLength (handle);
+ return new Point (start, start+length);
+}
+
+/**
+ * Returns the number of selected characters.
+ *
+ * @return the number of selected characters.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getSelectionCount () {
+ checkWidget ();
+ Point selection = getSelection ();
+ return selection.y - selection.x;
+}
+
+/**
+ * Gets the selected text, or an empty string if there is no current selection.
+ *
+ * @return the selected text
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String getSelectionText () {
+ checkWidget ();
+ if ((style & SWT.PASSWORD) != 0) return "";
+ int content = OS.TextBox_SelectedText (handle);
+ String string = createJavaString (content);
+ OS.GCHandle_Free (content);
+ return string;
+}
+
+/**
+ * Returns the number of tabs.
+ * <p>
+ * Tab stop spacing is specified in terms of the
+ * space (' ') character. The width of a single
+ * tab stop is the pixel width of the spaces.
+ * </p>
+ *
+ * @return the number of tab characters
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getTabs () {
+ checkWidget ();
+ //FIXME
+ return 8;
+}
+
+/**
+ * Returns the widget text.
+ * <p>
+ * The text for a text widget is the characters in the widget, or
+ * an empty string if this has never been set.
+ * </p>
+ *
+ * @return the widget text
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String getText () {
+ checkWidget();
+ int text;
+ if ((style & SWT.PASSWORD) != 0) {
+ text = OS.PasswordBox_Password (handle);
+ } else {
+ text = OS.TextBox_Text (handle);
+ }
+ String string = createJavaString (text);
+ OS.GCHandle_Free (text);
+ return string;
+}
+
+/**
+ * Returns a range of text. Returns an empty string if the
+ * start of the range is greater than the end.
+ * <p>
+ * Indexing is zero based. The range of
+ * a selection is from 0..N-1 where N is
+ * the number of characters in the widget.
+ * </p>
+ *
+ * @param start the start of the range
+ * @param end the end of the range
+ * @return the range of text
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String getText (int start, int end) {
+ checkWidget ();
+ if (!(start <= end && 0 <= end)) return "";
+ String text = getText ();
+ int length = text.length();
+ start = Math.max (0, start);
+ end = Math.min (end, length - 1);
+ /*
+ * NOTE: The current implementation uses substring ()
+ * which can reference a potentially large character
+ * array.
+ */
+ return text.substring (start, end + 1);
+}
+
+/**
+ * Returns the maximum number of characters that the receiver is capable of holding.
+ * <p>
+ * If this has not been changed by <code>setTextLimit()</code>,
+ * it will be the constant <code>Text.LIMIT</code>.
+ * </p>
+ *
+ * @return the text limit
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #LIMIT
+ */
+public int getTextLimit () {
+ checkWidget ();
+ if ((style & SWT.PASSWORD) != 0) return OS.PasswordBox_MaxLength (handle);
+ return OS.TextBox_MaxLength (handle);
+}
+
+/**
+ * Returns the zero-relative index of the line which is currently
+ * at the top of the receiver.
+ * <p>
+ * This index can change when lines are scrolled or new lines are added or removed.
+ * </p>
+ *
+ * @return the index of the top line
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getTopIndex () {
+ checkWidget ();
+ if ((style & SWT.SINGLE) != 0) return 0;
+ if ((style & SWT.PASSWORD) != 0) return 0;
+ return OS.TextBox_GetFirstVisibleLineIndex (handle);
+}
+
+/**
+ * Returns the top pixel.
+ * <p>
+ * The top pixel is the pixel position of the line
+ * that is currently at the top of the widget. On
+ * some platforms, a text widget can be scrolled by
+ * pixels instead of lines so that a partial line
+ * is displayed at the top of the widget.
+ * </p><p>
+ * The top pixel changes when the widget is scrolled.
+ * The top pixel does not include the widget trimming.
+ * </p>
+ *
+ * @return the pixel position of the top line
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getTopPixel () {
+ checkWidget ();
+ //FIXME
+ return 0;
+}
+
+void HandleKeyDown (int sender, int e) {
+ if (!checkEvent (e)) return;
+ super.HandleKeyDown (sender, e);
+ if ((style & SWT.SINGLE) != 0) {
+ int key = OS.KeyEventArgs_Key (e);
+ if (key == OS.Key_Return) postEvent (SWT.DefaultSelection);
+ }
+}
+
+void HandlePreviewExecutedRoutedEvent (int sender, int e) {
+ if (!checkEvent (e)) return;
+ int command = OS.ExecutedRoutedEventArgs_Command (e);
+ boolean doVerify = false;
+ String input = null;
+ if (OS.Object_Equals (command, OS.ApplicationCommands_Paste)) {
+ doVerify = true;
+ int clipboardText = OS.Clipboard_GetText ();
+ input = createJavaString(clipboardText);
+ OS.GCHandle_Free(clipboardText);
+ } else if (OS.Object_Equals (command, OS.ApplicationCommands_Cut)){
+ doVerify = true;
+ input = getSelectionText ();
+ } else if (OS.Object_Equals(command, OS.ApplicationCommands_Redo)) {
+ //FIXME
+ //doVerify = true;
+ OS.ExecutedRoutedEventArgs_Handled (e, true);
+ } else if (OS.Object_Equals(command, OS.ApplicationCommands_Undo)) {
+ //FIXME
+ //doVerify = true;
+ OS.ExecutedRoutedEventArgs_Handled (e, true);
+ } else if (OS.Object_Equals (command, OS.EditingCommands_Backspace)) {
+ doVerify = true;
+ input = "";
+ } else if (OS.Object_Equals (command, OS.EditingCommands_Delete)) {
+ doVerify = true;
+ input = "";
+ } else if (OS.Object_Equals(command, OS.EditingCommands_DeleteNextWord)) {
+ //FIXME
+ //doVerify = true;
+ OS.ExecutedRoutedEventArgs_Handled (e, true);
+ } else if (OS.Object_Equals(command, OS.EditingCommands_DeletePreviousWord)) {
+ //FIXME
+ //doVerify = true;
+ OS.ExecutedRoutedEventArgs_Handled (e, true);
+ }
+ OS.GCHandle_Free(command);
+ /*
+ * FIXME - should do this first, but for now we want to swallow
+ * all Redo, Undo, DeleteNextWord and DeletePreviousWord to
+ * prevent those from changing the TextBox w/o Verify events
+ */
+ if (!hooks (SWT.Verify)) return;
+ if (!doVerify) return;
+ String text = verifyText (input);
+ if (text != null && !text.equals (input)) {
+ int strPtr = createDotNetString (text, false);
+ OS.TextBox_SelectedText (handle, strPtr);
+ OS.GCHandle_Free (strPtr);
+ int start = OS.TextBox_SelectionStart (handle);
+ int length = OS.TextBox_SelectionLength (handle);
+ OS.TextBox_Select (handle, start+length, 0);
+ OS.TextBox_SelectionLength (handle, 0);
+ text = null;
+ }
+ if (text == null) OS.ExecutedRoutedEventArgs_Handled (e, true);
+}
+
+void HandlePreviewTextInput (int sender, int e) {
+ if (!checkEvent (e)) return;
+ int textPtr = OS.TextCompositionEventArgs_Text (e);
+ String input = createJavaString(textPtr);
+ OS.GCHandle_Free (textPtr);
+ String text = verifyText (input);
+ if (text != null && !text.equals (input)) {
+ textPtr = createDotNetString (text, false);
+ OS.TextBox_SelectedText (handle, textPtr);
+ OS.GCHandle_Free (textPtr);
+ int start = OS.TextBox_SelectionStart (handle);
+ int length = OS.TextBox_SelectionLength (handle);
+ OS.TextBox_Select (handle, start+length, 0);
+ OS.TextBox_SelectionLength (handle, 0);
+ text = null;
+ }
+ if (text == null) OS.TextCompositionEventArgs_Handled (e, true);
+}
+
+void HandleTextChanged (int sender, int e) {
+ if (!checkEvent (e)) return;
+ sendEvent (SWT.Modify);
+}
+
+void hookEvents () {
+ super.hookEvents();
+ if ((style & SWT.PASSWORD) != 0) {
+ int handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleTextChanged");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.PasswordBox_PasswordChanged (handle, handler);
+ OS.GCHandle_Free(handler);
+ return;
+ }
+
+ int handler = OS.gcnew_TextCompositionEventHandler (jniRef, "HandlePreviewTextInput");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.UIElement_PreviewTextInput (handle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_ExecutedRoutedEventHandler (jniRef, "HandlePreviewExecutedRoutedEvent");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.CommandManager_AddPreviewExecutedHandler (handle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_TextChangedEventHandler (jniRef, "HandleTextChanged");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.TextBoxBase_TextChanged (handle, handler);
+ OS.GCHandle_Free(handler);
+}
+
+/**
+ * Inserts a string.
+ * <p>
+ * The old selection is replaced with the new text.
+ * </p>
+ *
+ * @param string the string
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is <code>null</code></li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void insert (String string) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if ((style & SWT.PASSWORD) != 0) return;
+ if (hooks (SWT.Verify) || filters (SWT.Verify)) {
+ string = verifyText (string);
+ if (string == null) return;
+ }
+ int strPtr = createDotNetString (string, false);
+ OS.TextBox_SelectedText (handle, strPtr);
+ OS.GCHandle_Free (strPtr);
+ int end = OS.TextBox_SelectionStart (handle) + OS.TextBox_SelectionLength (handle);
+ OS.TextBox_Select (handle, end, 0);
+}
+
+/**
+ * Pastes text from clipboard.
+ * <p>
+ * The selected text is deleted from the widget
+ * and new text inserted from the clipboard.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void paste () {
+ checkWidget ();
+ if ((style & SWT.READ_ONLY) != 0) {
+ OS.PasswordBox_Paste (handle);
+ return;
+ }
+ OS.TextBoxBase_Paste (handle);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the receiver's text is modified.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ModifyListener
+ * @see #addModifyListener
+ */
+public void removeModifyListener (ModifyListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Modify, listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the control is selected.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #addSelectionListener
+ */
+public void removeSelectionListener (SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Selection, listener);
+ eventTable.unhook (SWT.DefaultSelection,listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the control is verified.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see VerifyListener
+ * @see #addVerifyListener
+ */
+public void removeVerifyListener (VerifyListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Verify, listener);
+}
+
+/**
+ * Selects all the text in the receiver.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void selectAll () {
+ checkWidget ();
+ if ((style & SWT.PASSWORD) != 0) return;
+ OS.TextBoxBase_SelectAll (handle);
+}
+
+/**
+ * Sets the double click enabled flag.
+ * <p>
+ * The double click flag enables or disables the
+ * default action of the text widget when the user
+ * double clicks.
+ * </p><p>
+ * Note: This operation is a hint and is not supported on
+ * platforms that do not have this concept.
+ * </p>
+ *
+ * @param doubleClick the new double click flag
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setDoubleClickEnabled (boolean doubleClick) {
+ checkWidget ();
+ this.doubleClick = doubleClick;
+}
+
+/**
+ * Sets the echo character.
+ * <p>
+ * The echo character is the character that is
+ * displayed when the user enters text or the
+ * text is changed by the programmer. Setting
+ * the echo character to '\0' clears the echo
+ * character and redraws the original text.
+ * If for any reason the echo character is invalid,
+ * or if the platform does not allow modification
+ * of the echo character, the default echo character
+ * for the platform is used.
+ * </p>
+ *
+ * @param echo the new echo character
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setEchoChar (char echo) {
+ checkWidget ();
+ if ((style & SWT.PASSWORD) == 0) return;
+ OS.PasswordBox_PasswordChar (handle, echo);
+}
+
+/**
+ * Sets the editable state.
+ *
+ * @param editable the new editable state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setEditable (boolean editable) {
+ checkWidget ();
+ style &= ~SWT.READ_ONLY;
+ if (!editable) style |= SWT.READ_ONLY;
+ if ((style & SWT.PASSWORD) != 0) return;
+ OS.TextBoxBase_IsReadOnly (handle, !editable);
+}
+
+void setFont (int font, double size) {
+ super.setFont (font, size);
+ //FIXME
+// setTabStops (tabs);
+}
+
+/**
+ * Sets the orientation of the receiver, which must be one
+ * of the constants <code>SWT.LEFT_TO_RIGHT</code> or <code>SWT.RIGHT_TO_LEFT</code>.
+ * <p>
+ * Note: This operation is a hint and is not supported on
+ * platforms that do not have this concept.
+ * </p>
+ *
+ * @param orientation new orientation style
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+public void setOrientation (int orientation) {
+ checkWidget();
+ int flags = SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT;
+ if ((orientation & flags) == 0 || (orientation & flags) == flags) return;
+ style &= ~flags;
+ style |= orientation & flags;
+ //FIXME FrameworkElement.FlowDirection ??
+}
+
+/**
+ * Sets the selection.
+ * <p>
+ * Indexing is zero based. The range of
+ * a selection is from 0..N where N is
+ * the number of characters in the widget.
+ * </p><p>
+ * Text selections are specified in terms of
+ * caret positions. In a text widget that
+ * contains N characters, there are N+1 caret
+ * positions, ranging from 0..N. This differs
+ * from other functions that address character
+ * position such as getText () that use the
+ * regular array indexing rules.
+ * </p>
+ *
+ * @param start new caret position
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSelection (int start) {
+ checkWidget ();
+ if ((style & SWT.PASSWORD) != 0) return;
+ OS.TextBox_CaretIndex (handle, start);
+}
+
+/**
+ * Sets the selection to the range specified
+ * by the given start and end indices.
+ * <p>
+ * Indexing is zero based. The range of
+ * a selection is from 0..N where N is
+ * the number of characters in the widget.
+ * </p><p>
+ * Text selections are specified in terms of
+ * caret positions. In a text widget that
+ * contains N characters, there are N+1 caret
+ * positions, ranging from 0..N. This differs
+ * from other functions that address character
+ * position such as getText () that use the
+ * usual array indexing rules.
+ * </p>
+ *
+ * @param start the start of the range
+ * @param end the end of the range
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSelection (int start, int end) {
+ checkWidget ();
+ if ((style & SWT.PASSWORD) != 0) return;
+ int first = Math.max (Math.min (start, end), 0);
+ int last = Math.min (Math.max (start, end), getCharCount ());
+ OS.TextBox_Select (handle, first, last-first);
+}
+
+/**
+ * Sets the selection to the range specified
+ * by the given point, where the x coordinate
+ * represents the start index and the y coordinate
+ * represents the end index.
+ * <p>
+ * Indexing is zero based. The range of
+ * a selection is from 0..N where N is
+ * the number of characters in the widget.
+ * </p><p>
+ * Text selections are specified in terms of
+ * caret positions. In a text widget that
+ * contains N characters, there are N+1 caret
+ * positions, ranging from 0..N. This differs
+ * from other functions that address character
+ * position such as getText () that use the
+ * usual array indexing rules.
+ * </p>
+ *
+ * @param selection the point
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSelection (Point selection) {
+ checkWidget ();
+ if (selection == null) error (SWT.ERROR_NULL_ARGUMENT);
+ setSelection (selection.x, selection.y);
+}
+
+/**
+ * Sets the number of tabs.
+ * <p>
+ * Tab stop spacing is specified in terms of the
+ * space (' ') character. The width of a single
+ * tab stop is the pixel width of the spaces.
+ * </p>
+ *
+ * @param tabs the number of tabs
+ *
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setTabs (int tabs) {
+ checkWidget ();
+ if (tabs < 0) return;
+ //FIXME
+// setTabStops (this.tabs = tabs);
+}
+
+/**
+ * Sets the contents of the receiver to the given string. If the receiver has style
+ * SINGLE and the argument contains multiple lines of text, the result of this
+ * operation is undefined and may vary from platform to platform.
+ *
+ * @param string the new text
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setText (String string) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (hooks (SWT.Verify) || filters (SWT.Verify)) {
+ string = verifyText (string);
+ if (string == null) return;
+ }
+ int ptr = createDotNetString (string, false);
+ if ((style & SWT.PASSWORD) != 0) {
+ OS.PasswordBox_Password (handle, ptr);
+ } else {
+ OS.TextBox_Text (handle, ptr);
+ }
+ OS.GCHandle_Free (ptr);
+}
+
+/**
+ * Sets the maximum number of characters that the receiver
+ * is capable of holding to be the argument.
+ * <p>
+ * Instead of trying to set the text limit to zero, consider
+ * creating a read-only text widget.
+ * </p><p>
+ * To reset this value to the default, use <code>setTextLimit(Text.LIMIT)</code>.
+ * Specifying a limit value larger than <code>Text.LIMIT</code> sets the
+ * receiver's limit to <code>Text.LIMIT</code>.
+ * </p>
+ *
+ * @param limit new text limit
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_CANNOT_BE_ZERO - if the limit is zero</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #LIMIT
+ */
+public void setTextLimit (int limit) {
+ checkWidget ();
+ if (limit == 0) error (SWT.ERROR_CANNOT_BE_ZERO);
+ if (limit < 0) limit = LIMIT;
+ limit = Math.min (limit, LIMIT);
+ if ((style & SWT.PASSWORD) != 0) {
+ OS.PasswordBox_MaxLength (handle, limit);
+ } else {
+ OS.TextBox_MaxLength (handle, limit);
+ }
+}
+
+/**
+ * Sets the zero-relative index of the line which is currently
+ * at the top of the receiver. This index can change when lines
+ * are scrolled or new lines are added and removed.
+ *
+ * @param index the index of the top item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setTopIndex (int index) {
+ checkWidget ();
+ if ((style & SWT.SINGLE) != 0) return;
+ if ((style & SWT.PASSWORD) != 0) return;
+ //FIXME: LineCount returns -1 until widget is realized
+ int count = OS.TextBox_LineCount (handle);
+ index = Math.min (Math.max (index, 0), count - 1);
+ int topIndex = OS.TextBox_GetFirstVisibleLineIndex (handle);
+ //FIXME ScrollToLine != top index
+ OS.TextBox_ScrollToLine (handle, index - topIndex);
+}
+
+/**
+ * Shows the selection.
+ * <p>
+ * If the selection is already showing
+ * in the receiver, this method simply returns. Otherwise,
+ * lines are scrolled until the selection is visible.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void showSelection () {
+ checkWidget ();
+ if ((style & SWT.PASSWORD) != 0) return;
+ double offset = OS.TextBoxBase_VerticalOffset (handle);
+ OS.TextBoxBase_ScrollToVerticalOffset (handle, offset);
+}
+
+int traversalCode (int key, int event) {
+ int bits = super.traversalCode (key, event);
+ if ((style & SWT.READ_ONLY) != 0) return bits;
+ if ((style & SWT.MULTI) != 0) {
+ bits &= ~SWT.TRAVERSE_RETURN;
+ if (key == OS.Key_Tab && event != 0) {
+ int keyboardDevice = OS.KeyboardEventArgs_KeyboardDevice(event);
+ int modifiers = OS.KeyboardDevice_Modifiers(keyboardDevice);
+ OS.GCHandle_Free(keyboardDevice);
+ boolean next = (modifiers & OS.ModifierKeys_Shift) == 0;
+ if (next && (modifiers & OS.ModifierKeys_Control) == 0) {
+ bits &= ~(SWT.TRAVERSE_TAB_NEXT | SWT.TRAVERSE_TAB_PREVIOUS);
+ }
+ }
+ }
+ return bits;
+}
+
+String verifyText (String text) {
+ int start = OS.TextBox_SelectionStart (handle);
+ int length = OS.TextBox_SelectionLength (handle);
+ Event event = new Event ();
+ event.text = text;
+ event.start = start;
+ /*
+ * FIXME: end can be greater than start+length+1
+ * when Deleting special characters.
+ * Note that backspace deletes one character at
+ * a time.
+ */
+ event.end = start+length+1;
+ sendEvent (SWT.Verify, event);
+ if (!event.doit) return null;
+ return event.text;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ToolBar.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ToolBar.java
new file mode 100644
index 0000000000..f7abec01ad
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ToolBar.java
@@ -0,0 +1,456 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.wpf.*;
+
+/**
+ * Instances of this class support the layout of selectable
+ * tool bar items.
+ * <p>
+ * The item children that may be added to instances of this class
+ * must be of type <code>ToolItem</code>.
+ * </p><p>
+ * Note that although this class is a subclass of <code>Composite</code>,
+ * it does not make sense to add <code>Control</code> children to it,
+ * or set a layout on it.
+ * </p><p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>FLAT, WRAP, RIGHT, HORIZONTAL, VERTICAL, SHADOW_OUT</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * <p>
+ * Note: Only one of the styles HORIZONTAL and VERTICAL may be specified.
+ * </p><p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ */
+public class ToolBar extends Composite {
+ int parentingHandle, trayHandle;
+ int itemCount;
+ Control [] children;
+ int childCount;
+
+ //TEMPORARY CODE
+ static boolean IsVertical;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#FLAT
+ * @see SWT#WRAP
+ * @see SWT#RIGHT
+ * @see SWT#HORIZONTAL
+ * @see SWT#SHADOW_OUT
+ * @see SWT#VERTICAL
+ * @see Widget#checkSubclass()
+ * @see Widget#getStyle()
+ */
+public ToolBar (Composite parent, int style) {
+ super (parent, checkStyle (style));
+
+ /*
+ * Ensure that either of HORIZONTAL or VERTICAL is set.
+ * NOTE: HORIZONTAL and VERTICAL have the same values
+ * as H_SCROLL and V_SCROLL so it is necessary to first
+ * clear these bits to avoid scroll bars and then reset
+ * the bits using the original style supplied by the
+ * programmer.
+ */
+ if ((style & SWT.VERTICAL) != 0) {
+ this.style |= SWT.VERTICAL;
+ } else {
+ this.style |= SWT.HORIZONTAL;
+ }
+}
+
+static int checkStyle (int style) {
+ IsVertical = (style & SWT.V_SCROLL) != 0;
+ /*
+ * Even though it is legal to create this widget
+ * with scroll bars, they serve no useful purpose
+ * because they do not automatically scroll the
+ * widget's client area. The fix is to clear
+ * the SWT style.
+ */
+ return style & ~(SWT.H_SCROLL | SWT.V_SCROLL);
+}
+
+void addChild (Control widget) {
+ super.addChild (widget);
+ if (childCount == children.length) {
+ Control [] newChildren = new Control [childCount + 4];
+ System.arraycopy(children, 0, newChildren, 0, childCount);
+ children = newChildren;
+ }
+ children [childCount++] = widget;
+}
+
+int backgroundProperty () {
+ return OS.Control_BackgroundProperty ();
+}
+
+protected void checkSubclass () {
+ if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
+}
+
+public Point computeSize (int wHint, int hHint, boolean changed) {
+ checkWidget ();
+ return super.computeSize (trayHandle, wHint, hHint, changed);
+}
+
+void createHandle () {
+ parentingHandle = OS.gcnew_Canvas ();
+ if (parentingHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ trayHandle = OS.gcnew_ToolBarTray();
+ if (trayHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ if (IsVertical) OS.ToolBarTray_Orientation (trayHandle, OS.Orientation_Vertical);
+ int children = OS.Panel_Children (parentingHandle);
+ OS.UIElementCollection_Add (children, trayHandle);
+ OS.GCHandle_Free (children);
+ handle = OS.gcnew_ToolBar ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ //FIXME: FLAT, WRAP, RIGHT, SHADOW_OUT
+ int toolBars = OS.ToolBarTray_ToolBars (trayHandle);
+ OS.IList_Add (toolBars, handle);
+ OS.GCHandle_Free (toolBars);
+ OS.ToolBarTray_IsLocked (trayHandle, true);
+}
+
+
+void createItem (ToolItem item, int index) {
+ if (!(0 <= index && index <= itemCount)) error (SWT.ERROR_INVALID_RANGE);
+ item.createWidget();
+ int items = OS.ItemsControl_Items (handle);
+ OS.ItemCollection_Insert(items, index, item.topHandle ());
+ int count = OS.ItemCollection_Count (items);
+ OS.GCHandle_Free (items);
+ if (itemCount == count) error (SWT.ERROR_ITEM_NOT_ADDED);
+ itemCount++;
+}
+
+void createWidget () {
+ super.createWidget();
+ children = new Control [4];
+}
+
+void deregister () {
+ super.deregister ();
+ display.removeWidget (trayHandle);
+ display.removeWidget (parentingHandle);
+}
+
+int defaultBackground () {
+ if ((style & SWT.FLAT) != 0) {
+ return OS.Colors_Transparent;
+ }
+ return 0;
+}
+
+void destroyItem (ToolItem item) {
+ int items = OS.ItemsControl_Items (handle);
+ OS.ItemCollection_Remove (items, item.topHandle ());
+ int count = OS.ItemCollection_Count (items);
+ OS.GCHandle_Free (items);
+ if (itemCount == count) error (SWT.ERROR_ITEM_NOT_REMOVED);
+ itemCount--;
+}
+
+Control [] _getChildren () {
+ // return children in reverse order.
+ Control[] result = new Control [childCount];
+ for (int i =0; i < childCount; i++) {
+ result [childCount - i - 1] = children [i];
+ }
+ return result;
+}
+
+ToolItem getItem (int items, int index) {
+ int item = OS.ItemCollection_GetItemAt (items, index);
+ ToolItem result = (ToolItem) display.getWidget (item);
+ OS.GCHandle_Free (item);
+ return result;
+}
+
+/**
+ * Returns the item at the given, zero-relative index in the
+ * receiver. Throws an exception if the index is out of range.
+ *
+ * @param index the index of the item to return
+ * @return the item at the given index
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public ToolItem getItem (int index) {
+ checkWidget ();
+ if (index < 0 || index >= itemCount) error (SWT.ERROR_INVALID_RANGE);
+ int items = OS.ItemsControl_Items (handle);
+ ToolItem result = getItem (items, index);
+ OS.GCHandle_Free (items);
+ return result;
+}
+
+/**
+ * Returns the item at the given point in the receiver
+ * or null if no such item exists. The point is in the
+ * coordinate system of the receiver.
+ *
+ * @param point the point used to locate the item
+ * @return the item at the given point
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public ToolItem getItem (Point point) {
+ checkWidget ();
+ if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
+ ToolItem [] items = getItems ();
+ for (int i=0; i<items.length; i++) {
+ Rectangle rect = items [i].getBounds ();
+ if (rect.contains (point)) return items [i];
+ }
+ return null;
+}
+
+/**
+ * Returns the number of items contained in the receiver.
+ *
+ * @return the number of items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getItemCount () {
+ checkWidget ();
+ return itemCount;
+}
+
+/**
+ * Returns an array of <code>ToolItem</code>s which are the items
+ * in the receiver.
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its list of items, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ *
+ * @return the items in the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public ToolItem [] getItems () {
+ checkWidget ();
+ ToolItem [] result = new ToolItem [itemCount];
+ int items = OS.ItemsControl_Items (handle);
+ for (int i = 0; i < itemCount; i++) {
+ result[i] = getItem (items, i);
+ }
+ OS.GCHandle_Free (items);
+ return result;
+}
+
+/**
+ * Returns the number of rows in the receiver. When
+ * the receiver has the <code>WRAP</code> style, the
+ * number of rows can be greater than one. Otherwise,
+ * the number of rows is always one.
+ *
+ * @return the number of items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getRowCount () {
+ checkWidget ();
+ //FIXME: when WRAP implemented
+ return 1;
+}
+
+boolean hasItems () {
+ return true;
+}
+
+void HandleLoaded (int sender, int e) {
+ if (!checkEvent (e)) return;
+ int template = OS.Control_Template (handle);
+ int name = createDotNetString ("OverflowButton", false);
+ int thumb = OS.FrameworkTemplate_FindName (template, name, handle);
+ if (thumb != 0) {
+ OS.UIElement_Visibility (thumb, OS.Visibility_Collapsed);
+ OS.GCHandle_Free (thumb);
+ }
+ OS.GCHandle_Free (name);
+ OS.GCHandle_Free (template);
+}
+
+void hookEvents() {
+ super.hookEvents ();
+ int handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleLoaded");
+ OS.FrameworkElement_Loaded (handle, handler);
+ OS.GCHandle_Free (handler);
+}
+
+/**
+ * Searches the receiver's list starting at the first item
+ * (index 0) until an item is found that is equal to the
+ * argument, and returns the index of that item. If no item
+ * is found, returns -1.
+ *
+ * @param item the search item
+ * @return the index of the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the tool item is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the tool item has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int indexOf (ToolItem item) {
+ checkWidget ();
+ if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (item.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
+ int items = OS.ItemsControl_Items (handle);
+ int index = OS.ItemCollection_IndexOf (items, item.topHandle ());
+ OS.GCHandle_Free (items);
+ return index;
+}
+
+boolean mnemonicHit (char key) {
+ //TODO
+ return false;
+}
+
+boolean mnemonicMatch (char key) {
+// for (int i=0; i<itemCount; i++) {
+// if (mnemonicMatch (items [i].textHandle, key)) return true;
+// }
+ return false;
+}
+
+int parentingHandle () {
+ return parentingHandle;
+}
+
+void register () {
+ super.register ();
+ display.addWidget (trayHandle, this);
+ display.addWidget (parentingHandle, this);
+}
+
+void releaseChildren (boolean destroy) {
+ int items = OS.ItemsControl_Items (handle);
+ for (int i=0; i<itemCount; i++) {
+ ToolItem item = getItem (items, i);
+ if (item != null && !item.isDisposed ()) item.release (false);
+ }
+ OS.GCHandle_Free (items);
+ super.releaseChildren (destroy);
+}
+
+void removeChild (Control control) {
+ super.removeChild (control);
+ int index = 0;
+ while (index < childCount) {
+ if (children [index] == control) break;
+ index++;
+ }
+ if (index == childCount) return;
+ System.arraycopy(children, index+1, children, index, --childCount - index);
+ children [childCount] = null;
+}
+
+void releaseHandle () {
+ super.releaseHandle ();
+ if (trayHandle != 0) OS.GCHandle_Free (trayHandle);
+ trayHandle = 0;
+ if (parentingHandle != 0) OS.GCHandle_Free (parentingHandle);
+ parentingHandle = 0;
+}
+
+void removeControl (Control control) {
+ super.removeControl (control);
+ int items = OS.ItemsControl_Items (handle);
+ for (int i=0; i<itemCount; i++) {
+ ToolItem item = getItem (items, i);
+ if (item.control == control) item.setControl (null);
+ }
+}
+
+int setBounds (int x, int y, int width, int height, int flags) {
+ int result = super.setBounds (x, y, width, height, flags);
+ if ((result & RESIZED) != 0) {
+ OS.FrameworkElement_Height (trayHandle, height);
+ OS.FrameworkElement_Width (trayHandle, width);
+ }
+ return result;
+}
+
+void setForegroundBrush (int brush) {
+ if (brush != 0) {
+ OS.Control_Foreground (handle, brush);
+ } else {
+ int property = OS.Control_ForegroundProperty ();
+ OS.DependencyObject_ClearValue (handle, property);
+ OS.GCHandle_Free (property);
+ }
+}
+
+int topHandle() {
+ return parentingHandle;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ToolItem.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ToolItem.java
new file mode 100644
index 0000000000..67c21b6710
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ToolItem.java
@@ -0,0 +1,820 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.events.*;
+
+/**
+ * Instances of this class represent a selectable user interface object
+ * that represents a button in a tool bar.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>PUSH, CHECK, RADIO, SEPARATOR, DROP_DOWN</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Selection</dd>
+ * </dl>
+ * <p>
+ * Note: Only one of the styles CHECK, PUSH, RADIO, SEPARATOR and DROP_DOWN
+ * may be specified.
+ * </p><p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ */
+public class ToolItem extends Item {
+ int imageHandle, textHandle, arrowHandle;
+ ToolBar parent;
+ Control control;
+ String toolTipText;
+ Image disabledImage, hotImage;
+ boolean ignoreSelection;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * (which must be a <code>ToolBar</code>) and a style value
+ * describing its behavior and appearance. The item is added
+ * to the end of the items maintained by its parent.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#PUSH
+ * @see SWT#CHECK
+ * @see SWT#RADIO
+ * @see SWT#SEPARATOR
+ * @see SWT#DROP_DOWN
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public ToolItem (ToolBar parent, int style) {
+ super (parent, checkStyle (style));
+ this.parent = parent;
+ parent.createItem (this, parent.getItemCount ());
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * (which must be a <code>ToolBar</code>), a style value
+ * describing its behavior and appearance, and the index
+ * at which to place it in the items maintained by its parent.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ * @param index the zero-relative index to store the receiver in its parent
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#PUSH
+ * @see SWT#CHECK
+ * @see SWT#RADIO
+ * @see SWT#SEPARATOR
+ * @see SWT#DROP_DOWN
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public ToolItem (ToolBar parent, int style, int index) {
+ super (parent, checkStyle (style));
+ this.parent = parent;
+ parent.createItem (this, index);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the control is selected, by sending
+ * it one of the messages defined in the <code>SelectionListener</code>
+ * interface.
+ * <p>
+ * When <code>widgetSelected</code> is called when the mouse is over the arrow portion of a drop-down tool,
+ * the event object detail field contains the value <code>SWT.ARROW</code>.
+ * <code>widgetDefaultSelected</code> is not called.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #removeSelectionListener
+ * @see SelectionEvent
+ */
+public void addSelectionListener(SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Selection,typedListener);
+ addListener (SWT.DefaultSelection,typedListener);
+}
+
+static int checkStyle (int style) {
+ return checkBits (style, SWT.PUSH, SWT.CHECK, SWT.RADIO, SWT.SEPARATOR, SWT.DROP_DOWN, 0);
+}
+
+protected void checkSubclass () {
+ if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
+}
+
+int createArrow () {
+ int geometry = OS.gcnew_StreamGeometry ();
+ int context = OS.StreamGeometry_Open (geometry);
+ int start = OS.gcnew_Point (0, 1);
+ int point = OS.gcnew_Point (3, 4);
+ int end = OS.gcnew_Point (6, 1);
+ OS.StreamGeometryContext_BeginFigure (context, start, true, true);
+ OS.StreamGeometryContext_LineTo (context, point, true, true);
+ OS.StreamGeometryContext_LineTo (context, end, true, true);
+ OS.StreamGeometryContext_Close (context);
+ int path = OS.gcnew_Path ();
+ OS.Path_Data (path, geometry);
+ int padding = OS.gcnew_Thickness (3, 0, 0, 0);
+ OS.FrameworkElement_Margin (path, padding);
+ int brush = OS.Brushes_Black ();
+ OS.Path_Fill (path, brush);
+ OS.FrameworkElement_Width (path, 6);
+ OS.FrameworkElement_Height (path, 6);
+ OS.FrameworkElement_HorizontalAlignment (path, OS.HorizontalAlignment_Center);
+ OS.FrameworkElement_VerticalAlignment (path, OS.VerticalAlignment_Center);
+ OS.GCHandle_Free (padding);
+ OS.GCHandle_Free (start);
+ OS.GCHandle_Free (point);
+ OS.GCHandle_Free (end);
+ OS.GCHandle_Free (brush);
+ OS.GCHandle_Free (context);
+ OS.GCHandle_Free (geometry);
+ return path;
+}
+
+void createHandle () {
+ if ((style & SWT.SEPARATOR) != 0) {
+ handle = OS.gcnew_Separator ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ return;
+ }
+ int bits = SWT.RADIO | SWT.CHECK | SWT.PUSH | SWT.DROP_DOWN;
+ switch (style & bits) {
+ case SWT.RADIO:
+ handle = OS.gcnew_RadioButton();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ break;
+ case SWT.CHECK:
+ handle = OS.gcnew_CheckBox();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ break;
+ case SWT.DROP_DOWN:
+ handle = OS.gcnew_Button();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ break;
+ case SWT.PUSH:
+ default:
+ handle = OS.gcnew_Button();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ break;
+ }
+ OS.ToolBar_SetOverflowMode (handle, OS.OverflowMode_Never);
+ imageHandle = OS.gcnew_Image ();
+ if (imageHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.Image_Stretch (imageHandle, OS.Stretch_None);
+ OS.UIElement_Visibility (imageHandle, OS.Visibility_Collapsed);
+ textHandle = OS.gcnew_AccessText ();
+ if (textHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.FrameworkElement_VerticalAlignment (textHandle, OS.VerticalAlignment_Center);
+ OS.FrameworkElement_HorizontalAlignment (textHandle, OS.HorizontalAlignment_Center);
+ int panel = OS.gcnew_StackPanel ();
+ if (panel == 0) error (SWT.ERROR_NO_HANDLES);
+ int orientation = (parent.style & SWT.RIGHT) != 0 ? OS.Orientation_Horizontal : OS.Orientation_Vertical;
+ OS.StackPanel_Orientation (panel, orientation);
+ int thickness = OS.gcnew_Thickness (1, 1, 1, 1);
+ if (thickness == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.FrameworkElement_Margin (panel, thickness);
+ OS.GCHandle_Free (thickness);
+ int children = OS.Panel_Children (panel);
+ OS.UIElementCollection_Add (children, imageHandle);
+ OS.UIElementCollection_Add (children, textHandle);
+ if ((style & SWT.DROP_DOWN) != 0) {
+ arrowHandle = createArrow ();
+ if ((parent.style & SWT.RIGHT) != 0) {
+ OS.UIElementCollection_Add (children, arrowHandle);
+ } else {
+ int newPanel = OS.gcnew_StackPanel ();
+ OS.StackPanel_Orientation (newPanel, OS.Orientation_Horizontal);
+ int horizontalChildren = OS.Panel_Children (newPanel);
+ OS.UIElementCollection_Add (horizontalChildren, panel);
+ OS.UIElementCollection_Add (horizontalChildren, arrowHandle);
+ OS.GCHandle_Free (horizontalChildren);
+ OS.GCHandle_Free (panel);
+ panel = newPanel;
+ }
+ }
+ OS.ContentControl_Content (handle, panel);
+ OS.GCHandle_Free (children);
+ OS.GCHandle_Free (panel);
+}
+
+void deregister () {
+ display.removeWidget (handle);
+}
+
+void destroyWidget () {
+ parent.destroyItem (this);
+ releaseHandle ();
+}
+
+/**
+ * Returns a rectangle describing the receiver's size and location
+ * relative to its parent.
+ *
+ * @return the receiver's bounding rectangle
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Rectangle getBounds () {
+ checkWidget ();
+ int parentHandle = parent.handle;
+ int topHandle = control == null ? topHandle () : control.topHandle ();
+ int point = OS.gcnew_Point (0, 0);
+ if (point == 0) error (SWT.ERROR_NO_HANDLES);
+ int location = OS.UIElement_TranslatePoint (topHandle, point, parentHandle);
+ int x = (int) OS.Point_X (location);
+ int y = (int) OS.Point_Y (location);
+ OS.GCHandle_Free (point);
+ OS.GCHandle_Free (location);
+ int width = (int) OS.FrameworkElement_ActualWidth (topHandle);
+ int height = (int) OS.FrameworkElement_ActualHeight (topHandle);
+ return new Rectangle (x, y, width, height);
+}
+
+/**
+ * Returns the control that is used to fill the bounds of
+ * the item when the item is a <code>SEPARATOR</code>.
+ *
+ * @return the control
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Control getControl () {
+ checkWidget ();
+ return control;
+}
+
+/**
+ * Returns the receiver's disabled image if it has one, or null
+ * if it does not.
+ * <p>
+ * The disabled image is displayed when the receiver is disabled.
+ * </p>
+ *
+ * @return the receiver's disabled image
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Image getDisabledImage () {
+ checkWidget ();
+ return disabledImage;
+}
+
+/**
+ * Returns <code>true</code> if the receiver is enabled, and
+ * <code>false</code> otherwise. A disabled control is typically
+ * not selectable from the user interface and draws with an
+ * inactive or "grayed" look.
+ *
+ * @return the receiver's enabled state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #isEnabled
+ */
+public boolean getEnabled () {
+ checkWidget ();
+ return OS.UIElement_IsEnabled (handle);
+}
+
+/**
+ * Returns the receiver's hot image if it has one, or null
+ * if it does not.
+ * <p>
+ * The hot image is displayed when the mouse enters the receiver.
+ * </p>
+ *
+ * @return the receiver's hot image
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Image getHotImage () {
+ checkWidget ();
+ return hotImage;
+}
+
+/**
+ * Returns the receiver's parent, which must be a <code>ToolBar</code>.
+ *
+ * @return the receiver's parent
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public ToolBar getParent () {
+ checkWidget ();
+ return parent;
+}
+
+/**
+ * Returns <code>true</code> if the receiver is selected,
+ * and false otherwise.
+ * <p>
+ * When the receiver is of type <code>CHECK</code> or <code>RADIO</code>,
+ * it is selected when it is checked (which some platforms draw as a
+ * pushed in button). If the receiver is of any other type, this method
+ * returns false.
+ * </p>
+ *
+ * @return the selection state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getSelection () {
+ checkWidget ();
+ if ((style & (SWT.CHECK | SWT.RADIO)) == 0) return false;
+ return OS.ToggleButton_IsChecked(handle);
+}
+
+/**
+ * Returns the receiver's tool tip text, or null if it has not been set.
+ *
+ * @return the receiver's tool tip text
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String getToolTipText () {
+ checkWidget ();
+ return toolTipText;
+}
+
+Control getWidgetControl () {
+ return parent;
+}
+
+/**
+ * Gets the width of the receiver.
+ *
+ * @return the width
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getWidth () {
+ checkWidget ();
+ return (int) OS.FrameworkElement_ActualWidth (topHandle ());
+}
+
+void HandleChecked (int sender, int e) {
+ if (!checkEvent (e)) return;
+ if (ignoreSelection) return;
+ postEvent (SWT.Selection);
+}
+
+void HandleClick (int sender, int e) {
+ if (!checkEvent (e)) return;
+ if (ignoreSelection) return;
+ Event event = new Event ();
+ if ((style & SWT.DROP_DOWN) != 0) {
+ int mousePos = OS.Mouse_GetPosition (handle);
+ int zero = OS.gcnew_Point (0, 0);
+ int arrowPos = OS.UIElement_TranslatePoint (arrowHandle, zero, handle);
+ if (OS.Point_X (mousePos) > OS.Point_X (arrowPos)) {
+ event.detail = SWT.DROP_DOWN;
+ int location = OS.UIElement_TranslatePoint (handle, zero, parent.handle);
+ event.x = (int) OS.Point_X (location);
+ event.y = (int) OS.Point_Y (location);
+ OS.GCHandle_Free (location);
+ }
+ OS.GCHandle_Free (arrowPos);
+ OS.GCHandle_Free (zero);
+ OS.GCHandle_Free (mousePos);
+ }
+ postEvent (SWT.Selection, event);
+}
+
+void HandleUnchecked (int sender, int e) {
+ if (!checkEvent (e)) return;
+ if (ignoreSelection) return;
+ postEvent (SWT.Selection);
+}
+
+void HandleMouseEnter (int sender, int e) {
+ if (!checkEvent (e)) return;
+ updateImages (getEnabled () && parent.getEnabled ());
+}
+
+void HandleMouseLeave (int sender, int e) {
+ if (!checkEvent (e)) return;
+ updateImages (getEnabled () && parent.getEnabled ());
+}
+
+void hookEvents() {
+ super.hookEvents ();
+ if ((style & SWT.SEPARATOR) != 0) return;
+ if ((style & (SWT.RADIO | SWT.CHECK)) != 0) {
+ int handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleChecked");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.ToggleButton_Checked (handle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleUnchecked");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.ToggleButton_Unchecked (handle, handler);
+ OS.GCHandle_Free (handler);
+ } else {
+ int handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleClick");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.ButtonBase_Click (handle, handler);
+ OS.GCHandle_Free (handler);
+ }
+ int handler = OS.gcnew_MouseEventHandler (jniRef, "HandleMouseEnter");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.UIElement_MouseEnter (handle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_MouseEventHandler (jniRef, "HandleMouseLeave");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.UIElement_MouseLeave (handle, handler);
+ OS.GCHandle_Free (handler);
+}
+
+/**
+ * Returns <code>true</code> if the receiver is enabled and all
+ * of the receiver's ancestors are enabled, and <code>false</code>
+ * otherwise. A disabled control is typically not selectable from the
+ * user interface and draws with an inactive or "grayed" look.
+ *
+ * @return the receiver's enabled state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #getEnabled
+ */
+public boolean isEnabled () {
+ checkWidget ();
+ return getEnabled () && parent.isEnabled ();
+}
+
+void register () {
+ display.addWidget (handle, this);
+}
+
+void releaseWidget () {
+ super.releaseWidget ();
+ control = null;
+ toolTipText = null;
+ image = disabledImage = hotImage = null;
+ deregister ();
+}
+
+void releaseHandle () {
+ super.releaseHandle ();
+ if (handle != 0) OS.GCHandle_Free (handle);
+ handle = 0;
+ if (imageHandle != 0) {
+ OS.GCHandle_Free (imageHandle);
+ imageHandle = 0;
+ }
+ if (textHandle != 0) {
+ OS.GCHandle_Free (textHandle);
+ textHandle = 0;
+ }
+ if (arrowHandle != 0) {
+ OS.GCHandle_Free (arrowHandle);
+ arrowHandle = 0;
+ }
+ parent = null;
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the control is selected.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #addSelectionListener
+ */
+public void removeSelectionListener(SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Selection, listener);
+ eventTable.unhook (SWT.DefaultSelection,listener);
+}
+
+/**
+ * Sets the control that is used to fill the bounds of
+ * the item when the item is a <code>SEPARATOR</code>.
+ *
+ * @param control the new control
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li>
+ * <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setControl (Control control) {
+ checkWidget ();
+ if (control != null) {
+ if (control.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (control.parent != parent) error (SWT.ERROR_INVALID_PARENT);
+ }
+ if ((style & SWT.SEPARATOR) == 0) return;
+ //TODO
+// Control oldControl = this.control, newControl = control;
+// this.control = control;
+// int parentHandle = parent.parentingHandle ();
+// int parentChildren = OS.Panel_Children (parentHandle);
+// if (oldControl != null) {
+// int topHandle = oldControl.topHandle ();
+// OS.UIElementCollection_Remove (parentChildren, topHandle);
+// }
+// OS.GCHandle_Free (parentChildren);
+//
+// parent.setControl (this, newControl);
+ this.control = control;
+}
+
+/**
+ * Enables the receiver if the argument is <code>true</code>,
+ * and disables it otherwise.
+ * <p>
+ * A disabled control is typically
+ * not selectable from the user interface and draws with an
+ * inactive or "grayed" look.
+ * </p>
+ *
+ * @param enabled the new enabled state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setEnabled (boolean enabled) {
+ checkWidget ();
+ OS.UIElement_IsEnabled (handle, enabled);
+ updateImages (enabled && parent.getEnabled ());
+}
+
+/**
+ * Sets the receiver's disabled image to the argument, which may be
+ * null indicating that no disabled image should be displayed.
+ * <p>
+ * The disbled image is displayed when the receiver is disabled.
+ * </p>
+ *
+ * @param image the disabled image to display on the receiver (may be null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setDisabledImage (Image image) {
+ checkWidget ();
+ if ((style & SWT.SEPARATOR) != 0) return;
+ if (image != null && image.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ disabledImage = image;
+ updateImages (getEnabled () && parent.getEnabled ());
+}
+
+/**
+ * Sets the receiver's hot image to the argument, which may be
+ * null indicating that no hot image should be displayed.
+ * <p>
+ * The hot image is displayed when the mouse enters the receiver.
+ * </p>
+ *
+ * @param image the hot image to display on the receiver (may be null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setHotImage (Image image) {
+ checkWidget ();
+ if ((style & SWT.SEPARATOR) != 0) return;
+ if (image != null && image.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ hotImage = image;
+ updateImages (getEnabled () && parent.getEnabled ());
+}
+
+public void setImage (Image image) {
+ checkWidget ();
+ if ((style & SWT.SEPARATOR) != 0) return;
+ if (image != null && image.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ super.setImage (image);
+ updateImages (getEnabled () && parent.getEnabled ());
+}
+
+/**
+ * Sets the selection state of the receiver.
+ * <p>
+ * When the receiver is of type <code>CHECK</code> or <code>RADIO</code>,
+ * it is selected when it is checked (which some platforms draw as a
+ * pushed in button).
+ * </p>
+ *
+ * @param selected the new selection state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSelection (boolean selected) {
+ checkWidget ();
+ if ((style & (SWT.CHECK | SWT.RADIO)) == 0) return;
+ ignoreSelection = true;
+ OS.ToggleButton_IsChecked (handle, selected);
+ ignoreSelection = false;
+}
+
+/**
+ * Sets the receiver's text. The string may include
+ * the mnemonic character.
+ * </p>
+ * <p>
+ * Mnemonics are indicated by an '&amp;' that causes the next
+ * character to be the mnemonic. When the user presses a
+ * key sequence that matches the mnemonic, a selection
+ * event occurs. On most platforms, the mnemonic appears
+ * underlined but may be emphasised in a platform specific
+ * manner. The mnemonic indicator character '&amp;' can be
+ * escaped by doubling it in the string, causing a single
+ * '&amp;' to be displayed.
+ * </p>
+ *
+ * @param string the new text
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setText (String string) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if ((style & SWT.SEPARATOR) != 0) return;
+ if (string.equals (text)) return;
+ super.setText (string);
+ int strPtr = createDotNetString (string, true);
+ if (strPtr == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.AccessText_Text (textHandle, strPtr);
+ OS.GCHandle_Free (strPtr);
+ OS.UIElement_Visibility (textHandle, string.length() == 0 && image != null ? OS.Visibility_Collapsed : OS.Visibility_Visible);
+ int spacing = image != null && text.length () != 0 ? 3 : 0;
+ int margin = (parent.style & SWT.RIGHT) != 0 ? OS.gcnew_Thickness (0, 0, spacing, 0) : OS.gcnew_Thickness (0, 0, 0, spacing);
+ OS.FrameworkElement_Margin (imageHandle, margin);
+ OS.GCHandle_Free (margin);
+}
+
+/**
+ * Sets the receiver's tool tip text to the argument, which
+ * may be null indicating that no tool tip text should be shown.
+ *
+ * @param string the new tool tip text (or null)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setToolTipText (String string) {
+ checkWidget ();
+ toolTipText = string;
+}
+
+/**
+ * Sets the width of the receiver, for <code>SEPARATOR</code> ToolItems.
+ *
+ * @param width the new width
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setWidth (int width) {
+ checkWidget ();
+ int controlHandle = control != null ? control.handle : handle;
+ OS.FrameworkElement_Width (controlHandle, width);
+}
+
+void updateImages (boolean enabled) {
+ if ((style & SWT.SEPARATOR) != 0) return;
+ Image next = image;
+ if (image != null && !enabled && disabledImage != null) next = disabledImage;
+ if (image != null && enabled && hotImage != null && OS.UIElement_IsMouseOver (handle)) next = hotImage;
+ OS.Image_Source (imageHandle, next != null ? next.handle : 0);
+ OS.UIElement_Visibility (imageHandle, next != null ? OS.Visibility_Visible : OS.Visibility_Collapsed);
+ OS.UIElement_Visibility (textHandle, next != null && text.length () == 0 ? OS.Visibility_Collapsed : OS.Visibility_Visible);
+ int spacing = next != null && text.length () != 0 ? 3 : 0;
+ int margin = (parent.style & SWT.RIGHT) != 0 ? OS.gcnew_Thickness (0, 0, spacing, 0) : OS.gcnew_Thickness (0, 0, 0, spacing);
+ if (margin == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.FrameworkElement_Margin (imageHandle, margin);
+ OS.GCHandle_Free (margin);
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Tracker.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Tracker.java
new file mode 100644
index 0000000000..8b8a965afb
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Tracker.java
@@ -0,0 +1,877 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.events.*;
+
+/**
+ * Instances of this class implement rubber banding rectangles that are
+ * drawn onto a parent <code>Composite</code> or <code>Display</code>.
+ * These rectangles can be specified to respond to mouse and key events
+ * by either moving or resizing themselves accordingly. Trackers are
+ * typically used to represent window geometries in a lightweight manner.
+ *
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>LEFT, RIGHT, UP, DOWN, RESIZE</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Move, Resize</dd>
+ * </dl>
+ * <p>
+ * Note: Rectangle move behavior is assumed unless RESIZE is specified.
+ * </p><p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ */
+public class Tracker extends Widget {
+ Control parent;
+ boolean tracking, cancelled, stippled;
+ Rectangle [] rectangles, proportions;
+ Rectangle bounds;
+ int resizeCursor, clientCursor, cursorOrientation = SWT.NONE;
+ int oldX, oldY;
+ int [] rectShapes;
+ int canvasHandle;
+
+ /*
+ * The following values mirror step sizes on Windows
+ */
+ final static int STEPSIZE_SMALL = 1;
+ final static int STEPSIZE_LARGE = 9;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a widget which will be the parent of the new instance (cannot be null)
+ * @param style the style of widget to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#LEFT
+ * @see SWT#RIGHT
+ * @see SWT#UP
+ * @see SWT#DOWN
+ * @see SWT#RESIZE
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Tracker (Composite parent, int style) {
+ super (parent, checkStyle (style));
+ this.parent = parent;
+}
+
+/**
+ * Constructs a new instance of this class given the display
+ * to create it on and a style value describing its behavior
+ * and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p><p>
+ * Note: Currently, null can be passed in for the display argument.
+ * This has the effect of creating the tracker on the currently active
+ * display if there is one. If there is no current display, the
+ * tracker is created on a "default" display. <b>Passing in null as
+ * the display argument is not considered to be good coding style,
+ * and may not be supported in a future release of SWT.</b>
+ * </p>
+ *
+ * @param display the display to create the tracker on
+ * @param style the style of control to construct
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#LEFT
+ * @see SWT#RIGHT
+ * @see SWT#UP
+ * @see SWT#DOWN
+ */
+public Tracker (Display display, int style) {
+ if (display == null) display = Display.getCurrent ();
+ if (display == null) display = Display.getDefault ();
+ if (!display.isValidThread ()) {
+ error (SWT.ERROR_THREAD_INVALID_ACCESS);
+ }
+ this.style = checkStyle (style);
+ this.display = display;
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the control is moved or resized, by sending
+ * it one of the messages defined in the <code>ControlListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ControlListener
+ * @see #removeControlListener
+ */
+public void addControlListener (ControlListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Resize, typedListener);
+ addListener (SWT.Move, typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when keys are pressed and released on the system keyboard, by sending
+ * it one of the messages defined in the <code>KeyListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see KeyListener
+ * @see #removeKeyListener
+ */
+public void addKeyListener (KeyListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.KeyUp,typedListener);
+ addListener (SWT.KeyDown,typedListener);
+}
+
+Point adjustMoveCursor () {
+ int newX = bounds.x + bounds.width / 2;
+ int newY = bounds.y;
+ if (parent != null) {
+ int point = OS.gcnew_Point (newX, newY);
+ int result = OS.Visual_PointToScreen (handle, point);
+ newX = (int) OS.Point_X(result);
+ newY = (int) OS.Point_Y(result);
+ OS.GCHandle_Free (point);
+ OS.GCHandle_Free (result);
+ }
+ OS.SetCursorPos (newX, newY);
+ return new Point (newX, newY);
+}
+
+Point adjustResizeCursor () {
+ int newX, newY;
+ if ((cursorOrientation & SWT.LEFT) != 0) {
+ newX = bounds.x;
+ } else if ((cursorOrientation & SWT.RIGHT) != 0) {
+ newX = bounds.x + bounds.width;
+ } else {
+ newX = bounds.x + bounds.width / 2;
+ }
+ if ((cursorOrientation & SWT.UP) != 0) {
+ newY = bounds.y;
+ } else if ((cursorOrientation & SWT.DOWN) != 0) {
+ newY = bounds.y + bounds.height;
+ } else {
+ newY = bounds.y + bounds.height / 2;
+ }
+
+ if (parent != null) {
+ int point = OS.gcnew_Point (newX, newY);
+ int result = OS.Visual_PointToScreen (handle, point);
+ newX = (int) OS.Point_X(result);
+ newY = (int) OS.Point_Y(result);
+ OS.GCHandle_Free (point);
+ OS.GCHandle_Free (result);
+ }
+ OS.SetCursorPos (newX, newY);
+
+ /*
+ * If the client has not provided a custom cursor then determine
+ * the appropriate resize cursor.
+ */
+ if (clientCursor == 0) {
+ int newCursor = 0;
+ switch (cursorOrientation) {
+ case SWT.UP:
+ newCursor = OS.Cursors_SizeNS();
+ break;
+ case SWT.DOWN:
+ newCursor = OS.Cursors_SizeNS();
+ break;
+ case SWT.LEFT:
+ newCursor = OS.Cursors_SizeWE();
+ break;
+ case SWT.RIGHT:
+ newCursor = OS.Cursors_SizeWE();
+ break;
+ case SWT.LEFT | SWT.UP:
+ newCursor = OS.Cursors_SizeNWSE();
+ break;
+ case SWT.RIGHT | SWT.DOWN:
+ newCursor = OS.Cursors_SizeNWSE();
+ break;
+ case SWT.LEFT | SWT.DOWN:
+ newCursor = OS.Cursors_SizeNESW();
+ break;
+ case SWT.RIGHT | SWT.UP:
+ newCursor = OS.Cursors_SizeNESW();
+ break;
+ default:
+ newCursor = OS.Cursors_SizeAll();
+ break;
+ }
+ OS.FrameworkElement_Cursor (handle, newCursor);
+ if (resizeCursor != 0) {
+ OS.GCHandle_Free (resizeCursor);
+ }
+ resizeCursor = newCursor;
+ }
+ return new Point (newX, newY);
+}
+
+static int checkStyle (int style) {
+ if ((style & (SWT.LEFT | SWT.RIGHT | SWT.UP | SWT.DOWN)) == 0) {
+ style |= SWT.LEFT | SWT.RIGHT | SWT.UP | SWT.DOWN;
+ }
+ return style;
+}
+
+/**
+ * Stops displaying the tracker rectangles. Note that this is not considered
+ * to be a cancelation by the user.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void close () {
+ checkWidget ();
+ tracking = false;
+}
+
+Rectangle computeBounds () {
+ int xMin = rectangles [0].x;
+ int yMin = rectangles [0].y;
+ int xMax = rectangles [0].x + rectangles [0].width;
+ int yMax = rectangles [0].y + rectangles [0].height;
+
+ for (int i = 1; i < rectangles.length; i++) {
+ if (rectangles [i].x < xMin) xMin = rectangles [i].x;
+ if (rectangles [i].y < yMin) yMin = rectangles [i].y;
+ int rectRight = rectangles [i].x + rectangles [i].width;
+ if (rectRight > xMax) xMax = rectRight;
+ int rectBottom = rectangles [i].y + rectangles [i].height;
+ if (rectBottom > yMax) yMax = rectBottom;
+ }
+
+ return new Rectangle (xMin, yMin, xMax - xMin, yMax - yMin);
+}
+
+Rectangle [] computeProportions (Rectangle [] rects) {
+ Rectangle [] result = new Rectangle [rects.length];
+ bounds = computeBounds ();
+ for (int i = 0; i < rects.length; i++) {
+ int x = 0, y = 0, width = 0, height = 0;
+ if (bounds.width != 0) {
+ x = (rects [i].x - bounds.x) * 100 / bounds.width;
+ width = rects [i].width * 100 / bounds.width;
+ } else {
+ width = 100;
+ }
+ if (bounds.height != 0) {
+ y = (rects [i].y - bounds.y) * 100 / bounds.height;
+ height = rects [i].height * 100 / bounds.height;
+ } else {
+ height = 100;
+ }
+ result [i] = new Rectangle (x, y, width, height);
+ }
+ return result;
+}
+
+/**
+ * Draw the rectangles displayed by the tracker.
+ */
+void drawRectangles () {
+ for (int i = 0; i < rectShapes.length; i++) {
+ Rectangle rect = rectangles [i];
+ int child = rectShapes [i];
+ OS.Canvas_SetLeft (child, rect.x);
+ OS.Canvas_SetTop (child, rect.y);
+ OS.FrameworkElement_Width (child, rect.width);
+ OS.FrameworkElement_Height (child, rect.height);
+ }
+}
+
+/**
+ * Returns the bounds that are being drawn, expressed relative to the parent
+ * widget. If the parent is a <code>Display</code> then these are screen
+ * coordinates.
+ *
+ * @return the bounds of the Rectangles being drawn
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Rectangle [] getRectangles () {
+ checkWidget();
+ int length = 0;
+ if (rectangles != null) length = rectangles.length;
+ Rectangle [] result = new Rectangle [length];
+ for (int i = 0; i < length; i++) {
+ Rectangle current = rectangles [i];
+ result [i] = new Rectangle (current.x, current.y, current.width, current.height);
+ }
+ return result;
+}
+
+/**
+ * Returns <code>true</code> if the rectangles are drawn with a stippled line, <code>false</code> otherwise.
+ *
+ * @return the stippled effect of the rectangles
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getStippled () {
+ checkWidget ();
+ return stippled;
+}
+
+void HandleKeyUp (int sender, int e) {
+ if (!sendKeyEvent(SWT.KeyUp, e, false)) return;
+}
+
+void HandleKeyDown (int sender, int e) {
+ if (!sendKeyEvent(SWT.KeyDown, e, false)) return;
+
+ boolean ctrlDown = (OS.Keyboard_Modifiers() & OS.ModifierKeys_Control) != 0;
+ int stepSize = ctrlDown ? STEPSIZE_SMALL : STEPSIZE_LARGE;
+ int key = OS.KeyEventArgs_Key(e);
+ int xChange = 0, yChange = 0;
+ switch (key) {
+ case OS.Key_System:
+ case OS.Key_Escape:
+ cancelled = true;
+ tracking = false;
+ break;
+ case OS.Key_Return:
+ tracking = false;
+ break;
+ case OS.Key_Left:
+ xChange = -stepSize;
+ break;
+ case OS.Key_Right:
+ xChange = stepSize;
+ break;
+ case OS.Key_Up:
+ yChange = -stepSize;
+ break;
+ case OS.Key_Down:
+ yChange = stepSize;
+ break;
+ }
+ if (xChange != 0 || yChange != 0) {
+ Event event = new Event ();
+ event.x = oldX + xChange;
+ event.y = oldY + yChange;
+ Point cursorPos;
+ if ((style & SWT.RESIZE) != 0) {
+ resizeRectangles (xChange, yChange);
+ sendEvent (SWT.Resize, event);
+ if (isDisposed ()) {
+ cancelled = true;
+ return;
+ }
+ drawRectangles ();
+ cursorPos = adjustResizeCursor ();
+ } else {
+ moveRectangles (xChange, yChange);
+ sendEvent (SWT.Move, event);
+ if (isDisposed ()) {
+ cancelled = true;
+ return;
+ }
+ drawRectangles ();
+ cursorPos = adjustMoveCursor ();
+ }
+ oldX = cursorPos.x;
+ oldY = cursorPos.y;
+ }
+}
+
+void HandleMouseUp (int sender, int e) {
+ if (!sendMouseEvent(SWT.MouseUp, e, false)) return;
+ tracking = false;
+}
+
+void HandleMouseDown (int sender, int e) {
+ if (!sendMouseEvent(SWT.MouseDown, e, false)) return;
+ tracking = false;
+}
+
+void HandleMouseMove (int sender, int e) {
+ if (!sendMouseEvent(SWT.MouseMove, e, false)) return;
+ int point = OS.MouseEventArgs_GetPosition (e, handle);
+ int newX = (int) OS.Point_X (point);
+ int newY = (int) OS.Point_Y (point);
+ OS.GCHandle_Free (point);
+ if (newX != oldX || newY != oldY) {
+ Event event = new Event ();
+ event.x = newX;
+ event.y = newY;
+ if ((style & SWT.RESIZE) != 0) {
+ resizeRectangles (newX - oldX, newY - oldY);
+ sendEvent (SWT.Resize, event);
+ if (isDisposed ()) {
+ cancelled = true;
+ }
+ drawRectangles ();
+ Point cursorPos = adjustResizeCursor ();
+ if (cursorPos != null) {
+ newX = cursorPos.x;
+ newY = cursorPos.y;
+ }
+ } else {
+ moveRectangles (newX - oldX, newY - oldY);
+ sendEvent (SWT.Move, event);
+ if (isDisposed ()) {
+ cancelled = true;
+ }
+ drawRectangles ();
+ }
+ oldX = newX;
+ oldY = newY;
+ }
+}
+
+void moveRectangles (int xChange, int yChange) {
+ if (xChange < 0 && ((style & SWT.LEFT) == 0)) xChange = 0;
+ if (xChange > 0 && ((style & SWT.RIGHT) == 0)) xChange = 0;
+ if (yChange < 0 && ((style & SWT.UP) == 0)) yChange = 0;
+ if (yChange > 0 && ((style & SWT.DOWN) == 0)) yChange = 0;
+ if (xChange == 0 && yChange == 0) return;
+ bounds.x += xChange; bounds.y += yChange;
+ for (int i = 0; i < rectangles.length; i++) {
+ rectangles [i].x += xChange;
+ rectangles [i].y += yChange;
+ }
+}
+
+/**
+ * Displays the Tracker rectangles for manipulation by the user. Returns when
+ * the user has either finished manipulating the rectangles or has cancelled the
+ * Tracker.
+ *
+ * @return <code>true</code> if the user did not cancel the Tracker, <code>false</code> otherwise
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean open () {
+ checkWidget ();
+ if (rectangles == null) return false;
+ if (rectangles.length == 0) return false;
+ cancelled = false;
+ tracking = true;
+
+ /*
+ * If exactly one of UP/DOWN is specified as a style then set the cursor
+ * orientation accordingly (the same is done for LEFT/RIGHT styles below).
+ */
+ int vStyle = style & (SWT.UP | SWT.DOWN);
+ if (vStyle == SWT.UP || vStyle == SWT.DOWN) {
+ cursorOrientation |= vStyle;
+ }
+ int hStyle = style & (SWT.LEFT | SWT.RIGHT);
+ if (hStyle == SWT.LEFT || hStyle == SWT.RIGHT) {
+ cursorOrientation |= hStyle;
+ }
+
+ handle = OS.gcnew_Window ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ canvasHandle = OS.gcnew_Canvas ();
+ if (canvasHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.ContentControl_Content (handle, canvasHandle);
+ if (parent != null) {
+ Rectangle bounds = parent.getBounds ();// wrong
+ OS.Window_Left (handle, bounds.x);
+ OS.Window_Top (handle, bounds.y);
+ OS.FrameworkElement_Width (handle, bounds.width);
+ OS.FrameworkElement_Height (handle, bounds.height);
+ } else {
+ OS.Window_Left (handle, 0);
+ OS.Window_Top (handle, 0);
+ OS.FrameworkElement_Width (handle, OS.SystemParameters_PrimaryScreenWidth ());
+ OS.FrameworkElement_Height (handle, OS.SystemParameters_PrimaryScreenHeight ());
+ }
+ OS.Window_ShowInTaskbar (handle, false);
+ OS.Window_AllowsTransparency (handle, true);
+ OS.Window_ResizeMode (handle, OS.ResizeMode_NoResize);
+ OS.Window_WindowStyle (handle, OS.WindowStyle_None);
+ if (clientCursor != 0) OS.FrameworkElement_Cursor (handle, clientCursor);
+ int color = OS.Colors_Black;
+ int brush = OS.gcnew_SolidColorBrush (color);
+ OS.Brush_Opacity (brush, 0.01);
+ OS.Control_Background (handle, brush);
+ OS.GCHandle_Free (brush);
+
+ int children = OS.Panel_Children (canvasHandle);
+ int stroke = stippled ? 3 : 1;
+ brush = stippled ? OS.Brushes_Navy() : OS.Brushes_Black();
+ rectShapes = new int[rectangles.length];
+ for (int i = 0; i < rectShapes.length; i++) {
+ int child = rectShapes [i] = OS.gcnew_Rectangle ();
+ OS.UIElementCollection_Add (children, child);
+ OS.Shape_StrokeThickness(child, stroke);
+ OS.Shape_Stroke(child, brush);
+ }
+ OS.GCHandle_Free(brush);
+ drawRectangles ();
+
+ jniRef = OS.NewGlobalRef (this);
+ if (jniRef == 0) SWT.error (SWT.ERROR_NO_HANDLES);
+ int handler = OS.gcnew_KeyEventHandler (jniRef, "HandleKeyDown");
+ OS.UIElement_KeyDown (handle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_KeyEventHandler (jniRef, "HandleKeyUp");
+ OS.UIElement_KeyUp (handle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_MouseEventHandler (jniRef, "HandleMouseMove");
+ OS.UIElement_MouseMove (handle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_MouseButtonEventHandler (jniRef, "HandleMouseUp");
+ OS.UIElement_MouseUp (handle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_MouseButtonEventHandler (jniRef, "HandleMouseDown");
+ OS.UIElement_MouseDown (handle, handler);
+ OS.GCHandle_Free (handler);
+
+ OS.UIElement_Focus (handle);
+ OS.Window_Show (handle);
+
+ boolean mouseDown = OS.Mouse_LeftButton() == OS.MouseButtonState_Pressed;
+ Point cursorPos;
+ if (mouseDown) {
+ int point = OS.Mouse_GetPosition (handle);
+ cursorPos = new Point ((int) OS.Point_X (point), (int) OS.Point_Y (point));
+ OS.GCHandle_Free (point);
+ } else {
+ if ((style & SWT.RESIZE) != 0) {
+ cursorPos = adjustResizeCursor ();
+ } else {
+ cursorPos = adjustMoveCursor ();
+ }
+ }
+ oldX = cursorPos.x;
+ oldY = cursorPos.y;
+
+ /* Tracker behaves like a Dialog with its own OS event loop. */
+ Display display = Display.getCurrent();
+ while (tracking && !cancelled) {
+ if (!display.readAndDispatch()) {
+ display.readAndDispatch();
+ }
+ }
+
+ for (int i = 0; i < rectShapes.length; i++) {
+ int child = rectShapes [i];
+ OS.UIElementCollection_Remove (children, child);
+ OS.GCHandle_Free (child);
+ }
+ OS.GCHandle_Free (children);
+ if (resizeCursor != 0) {
+ OS.GCHandle_Free (resizeCursor);
+ resizeCursor = 0;
+ }
+ OS.Window_Close (handle);
+ OS.GCHandle_Free (canvasHandle);
+ OS.GCHandle_Free (handle);
+ jniRef = 0;
+ OS.DeleteGlobalRef (jniRef);
+ handle = 0;
+ rectShapes = null;
+ tracking = false;
+
+ return !cancelled;
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the control is moved or resized.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ControlListener
+ * @see #addControlListener
+ */
+public void removeControlListener (ControlListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Resize, listener);
+ eventTable.unhook (SWT.Move, listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when keys are pressed and released on the system keyboard.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see KeyListener
+ * @see #addKeyListener
+ */
+public void removeKeyListener(KeyListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.KeyUp, listener);
+ eventTable.unhook (SWT.KeyDown, listener);
+}
+
+void resizeRectangles (int xChange, int yChange) {
+ /*
+ * If the cursor orientation has not been set in the orientation of
+ * this change then try to set it here.
+ */
+ if (xChange < 0 && ((style & SWT.LEFT) != 0) && ((cursorOrientation & SWT.RIGHT) == 0)) {
+ cursorOrientation |= SWT.LEFT;
+ }
+ if (xChange > 0 && ((style & SWT.RIGHT) != 0) && ((cursorOrientation & SWT.LEFT) == 0)) {
+ cursorOrientation |= SWT.RIGHT;
+ }
+ if (yChange < 0 && ((style & SWT.UP) != 0) && ((cursorOrientation & SWT.DOWN) == 0)) {
+ cursorOrientation |= SWT.UP;
+ }
+ if (yChange > 0 && ((style & SWT.DOWN) != 0) && ((cursorOrientation & SWT.UP) == 0)) {
+ cursorOrientation |= SWT.DOWN;
+ }
+
+ /*
+ * If the bounds will flip about the x or y axis then apply the adjustment
+ * up to the axis (ie.- where bounds width/height becomes 0), change the
+ * cursor's orientation accordingly, and flip each Rectangle's origin (only
+ * necessary for > 1 Rectangles)
+ */
+ if ((cursorOrientation & SWT.LEFT) != 0) {
+ if (xChange > bounds.width) {
+ if ((style & SWT.RIGHT) == 0) return;
+ cursorOrientation |= SWT.RIGHT;
+ cursorOrientation &= ~SWT.LEFT;
+ bounds.x += bounds.width;
+ xChange -= bounds.width;
+ bounds.width = 0;
+ if (proportions.length > 1) {
+ for (int i = 0; i < proportions.length; i++) {
+ Rectangle proportion = proportions [i];
+ proportion.x = 100 - proportion.x - proportion.width;
+ }
+ }
+ }
+ } else if ((cursorOrientation & SWT.RIGHT) != 0) {
+ if (bounds.width < -xChange) {
+ if ((style & SWT.LEFT) == 0) return;
+ cursorOrientation |= SWT.LEFT;
+ cursorOrientation &= ~SWT.RIGHT;
+ xChange += bounds.width;
+ bounds.width = 0;
+ if (proportions.length > 1) {
+ for (int i = 0; i < proportions.length; i++) {
+ Rectangle proportion = proportions [i];
+ proportion.x = 100 - proportion.x - proportion.width;
+ }
+ }
+ }
+ }
+ if ((cursorOrientation & SWT.UP) != 0) {
+ if (yChange > bounds.height) {
+ if ((style & SWT.DOWN) == 0) return;
+ cursorOrientation |= SWT.DOWN;
+ cursorOrientation &= ~SWT.UP;
+ bounds.y += bounds.height;
+ yChange -= bounds.height;
+ bounds.height = 0;
+ if (proportions.length > 1) {
+ for (int i = 0; i < proportions.length; i++) {
+ Rectangle proportion = proportions [i];
+ proportion.y = 100 - proportion.y - proportion.height;
+ }
+ }
+ }
+ } else if ((cursorOrientation & SWT.DOWN) != 0) {
+ if (bounds.height < -yChange) {
+ if ((style & SWT.UP) == 0) return;
+ cursorOrientation |= SWT.UP;
+ cursorOrientation &= ~SWT.DOWN;
+ yChange += bounds.height;
+ bounds.height = 0;
+ if (proportions.length > 1) {
+ for (int i = 0; i < proportions.length; i++) {
+ Rectangle proportion = proportions [i];
+ proportion.y = 100 - proportion.y - proportion.height;
+ }
+ }
+ }
+ }
+
+ // apply the bounds adjustment
+ if ((cursorOrientation & SWT.LEFT) != 0) {
+ bounds.x += xChange;
+ bounds.width -= xChange;
+ } else if ((cursorOrientation & SWT.RIGHT) != 0) {
+ bounds.width += xChange;
+ }
+ if ((cursorOrientation & SWT.UP) != 0) {
+ bounds.y += yChange;
+ bounds.height -= yChange;
+ } else if ((cursorOrientation & SWT.DOWN) != 0) {
+ bounds.height += yChange;
+ }
+
+ Rectangle [] newRects = new Rectangle [rectangles.length];
+ for (int i = 0; i < rectangles.length; i++) {
+ Rectangle proportion = proportions[i];
+ newRects[i] = new Rectangle (
+ proportion.x * bounds.width / 100 + bounds.x,
+ proportion.y * bounds.height / 100 + bounds.y,
+ proportion.width * bounds.width / 100,
+ proportion.height * bounds.height / 100);
+ }
+ rectangles = newRects;
+}
+
+/**
+ * Sets the <code>Cursor</code> of the Tracker. If this cursor is <code>null</code>
+ * then the cursor reverts to the default.
+ *
+ * @param newCursor the new <code>Cursor</code> to display
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setCursor(Cursor newCursor) {
+ checkWidget();
+ clientCursor = 0;
+ if (newCursor != null) {
+ clientCursor = newCursor.handle;
+ if (handle != 0) {
+ OS.FrameworkElement_Cursor (handle, clientCursor);
+ }
+ }
+}
+
+/**
+ * Specifies the rectangles that should be drawn, expressed relative to the parent
+ * widget. If the parent is a Display then these are screen coordinates.
+ *
+ * @param rectangles the bounds of the rectangles to be drawn
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the set of rectangles is null or contains a null rectangle</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setRectangles (Rectangle [] rectangles) {
+ checkWidget ();
+ if (rectangles == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int length = rectangles.length;
+ this.rectangles = new Rectangle [length];
+ for (int i = 0; i < length; i++) {
+ Rectangle current = rectangles [i];
+ if (current == null) error (SWT.ERROR_NULL_ARGUMENT);
+ this.rectangles [i] = new Rectangle (current.x, current.y, current.width, current.height);
+ }
+ proportions = computeProportions (rectangles);
+}
+
+/**
+ * Changes the appearance of the line used to draw the rectangles.
+ *
+ * @param stippled <code>true</code> if rectangle should appear stippled
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setStippled (boolean stippled) {
+ checkWidget ();
+ this.stippled = stippled;
+ if (handle != 0) {
+ //TODO CHANGE RECT BRUSH
+ }
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Tree.java
new file mode 100644
index 0000000000..364c029d2a
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Tree.java
@@ -0,0 +1,1974 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.events.*;
+
+/**
+ * Instances of this class provide a selectable user interface object
+ * that displays a hierarchy of items and issues notification when an
+ * item in the hierarchy is selected.
+ * <p>
+ * The item children that may be added to instances of this class
+ * must be of type <code>TreeItem</code>.
+ * </p><p>
+ * Style <code>VIRTUAL</code> is used to create a <code>Tree</code> whose
+ * <code>TreeItem</code>s are to be populated by the client on an on-demand basis
+ * instead of up-front. This can provide significant performance improvements for
+ * trees that are very large or for which <code>TreeItem</code> population is
+ * expensive (for example, retrieving values from an external source).
+ * </p><p>
+ * Here is an example of using a <code>Tree</code> with style <code>VIRTUAL</code>:
+ * <code><pre>
+ * final Tree tree = new Tree(parent, SWT.VIRTUAL | SWT.BORDER);
+ * tree.setItemCount(20);
+ * tree.addListener(SWT.SetData, new Listener() {
+ * public void handleEvent(Event event) {
+ * TreeItem item = (TreeItem)event.item;
+ * TreeItem parentItem = item.getParentItem();
+ * String text = null;
+ * if (parentItem == null) {
+ * text = "node " + tree.indexOf(item);
+ * } else {
+ * text = parentItem.getText() + " - " + parentItem.indexOf(item);
+ * }
+ * item.setText(text);
+ * System.out.println(text);
+ * item.setItemCount(10);
+ * }
+ * });
+ * </pre></code>
+ * </p><p>
+ * Note that although this class is a subclass of <code>Composite</code>,
+ * it does not make sense to add <code>Control</code> children to it,
+ * or set a layout on it.
+ * </p><p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>SINGLE, MULTI, CHECK, FULL_SELECTION, VIRTUAL</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Selection, DefaultSelection, Collapse, Expand, SetData, MeasureItem, EraseItem, PaintItem</dd>
+ * </dl>
+ * </p><p>
+ * Note: Only one of the styles SINGLE and MULTI may be specified.
+ * </p><p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ */
+public class Tree extends Composite {
+ int columns, parentingHandle;
+ int columnCount, itemCount;
+ byte headerVisibility = OS.Visibility_Collapsed;
+ boolean ignoreSelection;
+
+ static final String HEADER_PART_NAME = "SWT_PART_HEADER";
+ static final String CHECKBOX_PART_NAME = "SWT_PART_CHECKBOX";
+ static final String IMAGE_PART_NAME = "SWT_PART_IMAGE";
+ static final String TEXT_PART_NAME = "SWT_PART_TEXT";
+ static final String SCROLLVIEWER_PART_NAME = "SWT_PART_SCROLLVIEWER";
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#SINGLE
+ * @see SWT#MULTI
+ * @see SWT#CHECK
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Tree (Composite parent, int style) {
+ super (parent, checkStyle (style));
+}
+
+static int checkStyle (int style) {
+ /*
+ * To be compatible with Windows, force the H_SCROLL
+ * and V_SCROLL style bits. On Windows, it is not
+ * possible to create a table without scroll bars.
+ */
+ style |= SWT.H_SCROLL | SWT.V_SCROLL;
+ /* WPF is always FULL_SELECTION */
+ style |= SWT.FULL_SELECTION;
+ return checkBits (style, SWT.SINGLE, SWT.MULTI, 0, 0, 0, 0);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the receiver's selection changes, by sending
+ * it one of the messages defined in the <code>SelectionListener</code>
+ * interface.
+ * <p>
+ * When <code>widgetSelected</code> is called, the item field of the event object is valid.
+ * If the receiver has <code>SWT.CHECK</code> style set and the check selection changes,
+ * the event object detail field contains the value <code>SWT.CHECK</code>.
+ * <code>widgetDefaultSelected</code> is typically called when an item is double-clicked.
+ * The item field of the event object is valid for default selection, but the detail field is not used.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #removeSelectionListener
+ * @see SelectionEvent
+ */
+public void addSelectionListener (SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Selection, typedListener);
+ addListener (SWT.DefaultSelection, typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when an item in the receiver is expanded or collapsed
+ * by sending it one of the messages defined in the <code>TreeListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see TreeListener
+ * @see #removeTreeListener
+ */
+public void addTreeListener (TreeListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Expand, typedListener);
+ addListener (SWT.Collapse, typedListener);
+}
+
+int backgroundHandle () {
+ return parentingHandle;
+}
+
+boolean checkData (TreeItem item) {
+ if ((style & SWT.VIRTUAL) == 0) return true;
+ if (!item.cached) {
+ item.cached = true;
+ int parentItem = OS.FrameworkElement_Parent (item.handle);
+ int items = OS.ItemsControl_Items (parentItem);
+ int index = OS.ItemCollection_IndexOf (items, item.handle);
+ OS.GCHandle_Free (items);
+ OS.GCHandle_Free (parentItem);
+ Event event = new Event ();
+ event.item = item;
+ event.index = index;
+ sendEvent (SWT.SetData, event);
+ if (isDisposed () || item.isDisposed ()) return false;
+ }
+ return true;
+}
+
+protected void checkSubclass () {
+ if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
+}
+
+/**
+ * Clears the item at the given zero-relative index in the receiver.
+ * The text, icon and other attributes of the item are set to the default
+ * value. If the tree was created with the <code>SWT.VIRTUAL</code> style,
+ * these attributes are requested again as needed.
+ *
+ * @param index the index of the item to clear
+ * @param all <code>true</code> if all child items of the indexed item should be
+ * cleared recursively, and <code>false</code> otherwise
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SWT#VIRTUAL
+ * @see SWT#SetData
+ *
+ * @since 3.2
+ */
+public void clear (int index, boolean all) {
+ checkWidget ();
+}
+
+/**
+ * Clears all the items in the receiver. The text, icon and other
+ * attributes of the items are set to their default values. If the
+ * tree was created with the <code>SWT.VIRTUAL</code> style, these
+ * attributes are requested again as needed.
+ *
+ * @param all <code>true</code> if all child items should be cleared
+ * recursively, and <code>false</code> otherwise
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SWT#VIRTUAL
+ * @see SWT#SetData
+ *
+ * @since 3.2
+ */
+public void clearAll (boolean all) {
+ checkWidget ();
+// int hItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0);
+// if (hItem == 0) return;
+// TVITEM tvItem = new TVITEM ();
+// tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM;
+// clearAll (hItem, tvItem, all);
+ //FIXME
+}
+
+TreeItem converterItem (int value) {
+ int content = (int) OS.Point_X (value);
+ TreeItem item;
+ if (content > 0) {
+ item = (TreeItem) OS.JNIGetObject (content);
+ } else {
+ int parentJniRef = (int) OS.Point_Y (value);
+ int items;
+ if (parentJniRef == jniRef) {
+ items = OS.ItemsControl_Items (handle);
+ } else {
+ TreeItem parentItem = (TreeItem) OS.JNIGetObject (parentJniRef);
+ items = OS.ItemsControl_Items (parentItem.handle);
+ }
+ item = getItem (items, -content, true);
+ OS.GCHandle_Free (items);
+ }
+ checkData (item);
+ return item;
+}
+
+int converterColumnIndex (int parameter) {
+ int columnIndex = 0;
+ if (parameter != 0) {
+ TreeColumn column = (TreeColumn) OS.JNIGetObject (parameter);
+ columnIndex = indexOf (column);
+ }
+ return columnIndex;
+}
+
+int ConvertImage (int value, int targetType, int parameter, int culture) {
+ TreeItem item = converterItem (value);
+ int columnIndex = converterColumnIndex (parameter);
+ int result = 0;
+ if (item.images != null && item.images [columnIndex] != null) {
+ result = item.images [columnIndex].handle;
+ }
+ return result;
+}
+
+int ConvertText (int value, int targetType, int parameter, int culture) {
+ TreeItem item = converterItem (value);
+ int columnIndex = converterColumnIndex (parameter);
+ int result = 0;
+ if (item.strings != null) {
+ if (item.stringHandle != null && item.stringHandle [columnIndex] != 0) {
+ result = item.stringHandle [columnIndex];
+ } else {
+ if (item.stringHandle == null) {
+ int count = Math.max (1, columnCount);
+ item.stringHandle = new int [count];
+ }
+ item.stringHandle [columnIndex] = result = createDotNetString (item.strings [columnIndex], false);
+ }
+ }
+ return result;
+}
+
+
+int createCellTemplate (int columnJniRef, int index) {
+ int template = OS.gcnew_DataTemplate ();
+ int stackPanelType = OS.StackPanel_typeid ();
+ int stackPanelNode = OS.gcnew_FrameworkElementFactory (stackPanelType);
+ if (index == 0 && (style & SWT.CHECK) != 0) {
+ int checkBoxType = OS.CheckBox_typeid ();
+ int checkBoxName = createDotNetString (CHECKBOX_PART_NAME, false);
+ int checkBoxNode = OS.gcnew_FrameworkElementFactory (checkBoxType, checkBoxName);
+ int verticalAlignmentProperty = OS.FrameworkElement_VerticalAlignmentProperty ();
+ OS.FrameworkElementFactory_SetValueVerticalAlignment (checkBoxNode, verticalAlignmentProperty, OS.VerticalAlignment_Center);
+ int marginProperty = OS.FrameworkElement_MarginProperty ();
+ int thickness = OS.gcnew_Thickness (0,0,4,0);
+ OS.FrameworkElementFactory_SetValue (checkBoxNode, marginProperty, thickness);
+ int threeStateProperty = OS.ToggleButton_IsThreeStateProperty ();
+ OS.FrameworkElementFactory_SetValue (checkBoxNode, threeStateProperty, true);
+ OS.FrameworkElementFactory_AppendChild (stackPanelNode, checkBoxNode);
+ OS.GCHandle_Free (checkBoxName);
+ OS.GCHandle_Free (threeStateProperty);
+ OS.GCHandle_Free (thickness);
+ OS.GCHandle_Free (marginProperty);
+ OS.GCHandle_Free (verticalAlignmentProperty);
+ OS.GCHandle_Free (checkBoxNode);
+ OS.GCHandle_Free (checkBoxType);
+ }
+ int textType = OS.TextBlock_typeid ();
+ int textName = createDotNetString (TEXT_PART_NAME, false);
+ int textNode = OS.gcnew_FrameworkElementFactory (textType, textName);
+ int imageType = OS.Image_typeid ();
+ int imageName = createDotNetString (IMAGE_PART_NAME, false);
+ int imageNode = OS.gcnew_FrameworkElementFactory (imageType, imageName);
+ int marginProperty = OS.FrameworkElement_MarginProperty ();
+ int thickness = OS.gcnew_Thickness (0, 0, 4, 0);
+ OS.FrameworkElementFactory_SetValue (imageNode, marginProperty, thickness);
+ int orientationProperty = OS.StackPanel_OrientationProperty ();
+ OS.FrameworkElementFactory_SetValueOrientation (stackPanelNode, orientationProperty, OS.Orientation_Horizontal);
+ OS.FrameworkElementFactory_AppendChild (stackPanelNode, imageNode);
+ OS.FrameworkElementFactory_AppendChild (stackPanelNode, textNode);
+ OS.FrameworkTemplate_VisualTree (template, stackPanelNode);
+ //bindings
+ int textBinding = OS.gcnew_Binding ();
+ int textConverter = OS.gcnew_SWTCellConverter (jniRef, "ConvertText");
+ OS.Binding_Converter (textBinding, textConverter);
+ OS.Binding_ConverterParameter (textBinding, columnJniRef);
+ int textProperty = OS.TextBlock_TextProperty ();
+ OS.FrameworkElementFactory_SetBinding (textNode, textProperty, textBinding);
+ int imageBinding = OS.gcnew_Binding ();
+ int imageConverter = OS.gcnew_SWTCellConverter (jniRef, "ConvertImage");
+ OS.Binding_Converter (imageBinding, imageConverter);
+ OS.Binding_ConverterParameter (imageBinding, columnJniRef);
+ int imageProperty = OS.Image_SourceProperty ();
+ OS.FrameworkElementFactory_SetBinding (imageNode, imageProperty, imageBinding);
+ OS.GCHandle_Free (textBinding);
+ OS.GCHandle_Free (textConverter);
+ OS.GCHandle_Free (textProperty);
+ OS.GCHandle_Free (imageBinding);
+ OS.GCHandle_Free (imageConverter);
+ OS.GCHandle_Free (imageProperty);
+
+ OS.GCHandle_Free (imageName);
+ OS.GCHandle_Free (textName);
+ OS.GCHandle_Free (marginProperty);
+ OS.GCHandle_Free (thickness);
+ OS.GCHandle_Free (stackPanelType);
+ OS.GCHandle_Free (imageType);
+ OS.GCHandle_Free (textType);
+ OS.GCHandle_Free (stackPanelNode);
+ OS.GCHandle_Free (textNode);
+ OS.GCHandle_Free (imageNode);
+ OS.GCHandle_Free (orientationProperty);
+ return template;
+}
+
+void createDefaultColumn () {
+ int column = OS.gcnew_GridViewColumn ();
+ OS.GridViewColumnCollection_Insert (columns, 0, column);
+ int cellTemplate = createCellTemplate (0, 0);
+ OS.GridViewColumn_CellTemplate (column, cellTemplate);
+ OS.GCHandle_Free (column);
+ OS.GCHandle_Free (cellTemplate);
+}
+
+int createControlTemplate () {
+ int template = OS.gcnew_ControlTemplate ();
+ int borderType = OS.Border_typeid ();
+ int borderNode = OS.gcnew_FrameworkElementFactory (borderType);
+ int dockPanelType = OS.DockPanel_typeid ();
+ int dockPanelNode = OS.gcnew_FrameworkElementFactory (dockPanelType);
+ int headerType = OS.GridViewHeaderRowPresenter_typeid ();
+ int nameString = createDotNetString (HEADER_PART_NAME, false);
+ int headerNode = OS.gcnew_FrameworkElementFactory (headerType, nameString);
+ int scrollViewerType = OS.ScrollViewer_typeid ();
+ int scrollViewerName = createDotNetString (SCROLLVIEWER_PART_NAME, false);
+ int scrollViewerNode = OS.gcnew_FrameworkElementFactory (scrollViewerType, scrollViewerName);
+ int columnsProperty = OS.GridViewHeaderRowPresenter_ColumnsProperty ();
+ OS.FrameworkElementFactory_SetValue (headerNode, columnsProperty, columns);
+ int visibilityProperty = OS.UIElement_VisibilityProperty ();
+ OS.FrameworkElementFactory_SetValueVisibility (headerNode, visibilityProperty, headerVisibility);
+ int dockProperty = OS.DockPanel_DockProperty ();
+ OS.FrameworkElementFactory_SetValueDock (headerNode, dockProperty, OS.Dock_Top);
+ int itemsPresenterType = OS.ItemsPresenter_typeid ();
+ int itemsPresenterNode = OS.gcnew_FrameworkElementFactory (itemsPresenterType);
+ OS.FrameworkElementFactory_AppendChild (borderNode, dockPanelNode);
+ OS.FrameworkElementFactory_AppendChild (dockPanelNode, headerNode);
+ OS.FrameworkElementFactory_AppendChild (dockPanelNode, scrollViewerNode);
+ OS.FrameworkElementFactory_AppendChild (scrollViewerNode, itemsPresenterNode);
+ OS.FrameworkTemplate_VisualTree (template, borderNode);
+ OS.GCHandle_Free (scrollViewerType);
+ OS.GCHandle_Free (scrollViewerName);
+ OS.GCHandle_Free (scrollViewerNode);
+ OS.GCHandle_Free (nameString);
+ OS.GCHandle_Free (borderType);
+ OS.GCHandle_Free (borderNode);
+ OS.GCHandle_Free (dockPanelType);
+ OS.GCHandle_Free (dockPanelNode);
+ OS.GCHandle_Free (headerType);
+ OS.GCHandle_Free (headerNode);
+ OS.GCHandle_Free (columnsProperty);
+ OS.GCHandle_Free (visibilityProperty);
+ OS.GCHandle_Free (dockProperty);
+ OS.GCHandle_Free (itemsPresenterType);
+ OS.GCHandle_Free (itemsPresenterNode);
+ return template;
+}
+
+void createHandle () {
+ parentingHandle = OS.gcnew_Canvas ();
+ if (parentingHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ handle = OS.gcnew_TreeView ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ columns = OS.gcnew_GridViewColumnCollection ();
+ if (columns == 0) error (SWT.ERROR_NO_HANDLES);
+ createDefaultColumn ();
+ int template = createControlTemplate ();
+ OS.Control_Template (handle, template);
+ OS.GCHandle_Free (template);
+ OS.Canvas_SetLeft (handle, 0);
+ OS.Canvas_SetTop (handle, 0);
+ int children = OS.Panel_Children (parentingHandle);
+ OS.UIElementCollection_Add (children, handle);
+ OS.GCHandle_Free (children);
+}
+
+int createHeaderTemplate (int columnJniRef) {
+ int template = OS.gcnew_DataTemplate ();
+ int stackPanelType = OS.StackPanel_typeid ();
+ int stackPanelNode = OS.gcnew_FrameworkElementFactory (stackPanelType);
+ int textType = OS.TextBlock_typeid ();
+ int textName = createDotNetString (TEXT_PART_NAME, false);
+ int textNode = OS.gcnew_FrameworkElementFactory (textType, textName);
+ int imageType = OS.Image_typeid ();
+ int imageName = createDotNetString (IMAGE_PART_NAME, false);
+ int imageNode = OS.gcnew_FrameworkElementFactory (imageType, imageName);
+ int marginProperty = OS.FrameworkElement_MarginProperty ();
+ int thickness = OS.gcnew_Thickness (0,0,4,0);
+ OS.FrameworkElementFactory_SetValue (imageNode, marginProperty, thickness);
+ int orientationProperty = OS.StackPanel_OrientationProperty ();
+ OS.FrameworkElementFactory_SetValueOrientation (stackPanelNode, orientationProperty, OS.Orientation_Horizontal);
+ int stretchProperty = OS.Image_StretchProperty ();
+ OS.FrameworkElementFactory_SetValueStretch (imageNode, stretchProperty, OS.Stretch_None);
+ OS.FrameworkElementFactory_AppendChild (stackPanelNode, imageNode);
+ OS.FrameworkElementFactory_AppendChild (stackPanelNode, textNode);
+ OS.FrameworkTemplate_VisualTree (template, stackPanelNode);
+ //bindings
+ int textBinding = OS.gcnew_Binding ();
+ int textConverter = OS.gcnew_SWTCellConverter (columnJniRef, "ConvertText");
+ OS.Binding_Converter (textBinding, textConverter);
+ OS.Binding_ConverterParameter (textBinding, columnJniRef);
+ int textProperty = OS.TextBlock_TextProperty ();
+ OS.FrameworkElementFactory_SetBinding (textNode, textProperty, textBinding);
+ int imageBinding = OS.gcnew_Binding ();
+ int imageConverter = OS.gcnew_SWTCellConverter (columnJniRef, "ConvertImage");
+ OS.Binding_Converter (imageBinding, imageConverter);
+ OS.Binding_ConverterParameter (imageBinding, columnJniRef);
+ int imageProperty = OS.Image_SourceProperty ();
+ OS.FrameworkElementFactory_SetBinding (imageNode, imageProperty, imageBinding);
+ OS.GCHandle_Free (textBinding);
+ OS.GCHandle_Free (textConverter);
+ OS.GCHandle_Free (textProperty);
+ OS.GCHandle_Free (imageBinding);
+ OS.GCHandle_Free (imageConverter);
+ OS.GCHandle_Free (imageProperty);
+
+ OS.GCHandle_Free (imageType);
+ OS.GCHandle_Free (textName);
+ OS.GCHandle_Free (textType);
+ OS.GCHandle_Free (stackPanelType);
+ OS.GCHandle_Free (stackPanelNode);
+ OS.GCHandle_Free (textNode);
+ OS.GCHandle_Free (marginProperty);
+ OS.GCHandle_Free (thickness);
+ OS.GCHandle_Free (imageName);
+ OS.GCHandle_Free (imageNode);
+ OS.GCHandle_Free (orientationProperty);
+ OS.GCHandle_Free (stretchProperty);
+ return template;
+}
+
+void createItem (TreeColumn column, int index) {
+ if (!(0 <= index && index <= columnCount)) error (SWT.ERROR_INVALID_RANGE);
+ column.createWidget ();
+ int template = createHeaderTemplate (column.jniRef);
+ OS.GridViewColumn_HeaderTemplate (column.handle, template);
+ OS.GCHandle_Free (template);
+ template = createCellTemplate (column.jniRef, index);
+ OS.GridViewColumn_CellTemplate (column.handle, template);
+ OS.GCHandle_Free (template);
+ if (columnCount == 0) {
+ OS.GridViewColumnCollection_Clear (columns);
+ }
+ OS.GridViewColumnCollection_Insert (columns, index, column.handle);
+ int items = OS.ItemsControl_Items (handle);
+ for (int i=0; i<itemCount; i++) {
+ TreeItem item = getItem (items, i, false);
+ if (item != null) {
+ item.columnInserted (index);
+ }
+ }
+ OS.GCHandle_Free (items);
+ columnCount++;
+}
+
+void createItem (TreeItem item, TreeItem parentItem, int index) {
+ int itemCount = parentItem != null ? parentItem.itemCount : this.itemCount;
+ if (!(0 <= index && index <= itemCount)) error (SWT.ERROR_INVALID_RANGE);
+ item.createWidget ();
+ int parentHandle = parentItem != null ? parentItem.handle : handle;
+ int items = OS.ItemsControl_Items (parentHandle);
+ OS.ItemCollection_Insert (items, index, item.handle);
+ int count = OS.ItemCollection_Count (items);
+ OS.GCHandle_Free (items);
+ if (itemCount == count) error (SWT.ERROR_ITEM_NOT_ADDED);
+ if (parentItem != null) {
+ parentItem.itemCount++;
+ } else {
+ this.itemCount++;
+ }
+}
+
+int defaultBackground () {
+ return OS.Colors_White;
+}
+
+void deregister () {
+ super.deregister ();
+ display.removeWidget (parentingHandle);
+}
+
+/**
+ * Deselects all selected items in the receiver.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void deselectAll () {
+ checkWidget ();
+ //TODO multiselection...
+ int item = OS.TreeView_SelectedItem (handle);
+ if (item != 0) {
+ ignoreSelection = true;
+ OS.TreeViewItem_IsSelected (item, false);
+ ignoreSelection = false;
+ OS.GCHandle_Free (item);
+ }
+}
+
+void destroyItem (TreeColumn column) {
+ int index = OS.GridViewColumnCollection_IndexOf (columns, column.handle);
+ boolean removed = OS.GridViewColumnCollection_Remove (columns, column.handle);
+ if (!removed) error (SWT.ERROR_ITEM_NOT_REMOVED);
+ columnCount--;
+ if (columnCount == 0) {
+ createDefaultColumn ();
+ }
+ int items = OS.ItemsControl_Items (handle);
+ for (int i=0; i<itemCount; i++) {
+ TreeItem item = getItem (items, i, false);
+ if (item != null) {
+ item.columnRemoved (index);
+ }
+ }
+ OS.GCHandle_Free (items);
+}
+
+void destroyItem (TreeItem item) {
+ TreeItem parentItem = item.getParentItem ();
+ int itemCount = parentItem != null ? parentItem.itemCount : this.itemCount;
+ int parentHandle = parentItem != null ? parentItem.handle : handle;
+
+
+ int items = OS.ItemsControl_Items (parentHandle);
+ OS.ItemCollection_Remove (items, item.handle);
+ int count = OS.ItemCollection_Count (items);
+ OS.GCHandle_Free (items);
+ if (count == itemCount) error (SWT.ERROR_ITEM_NOT_REMOVED);
+ if (parentItem != null) {
+ parentItem.itemCount--;
+ } else {
+ this.itemCount--;
+ }
+}
+
+int findScrollViewer(int current, int scrollViewerType) {
+ int template = OS.Control_Template (handle);
+ int scrollViewerName = createDotNetString (SCROLLVIEWER_PART_NAME, false);
+ int scrollViewer = OS.FrameworkTemplate_FindName (template, scrollViewerName, handle);
+ OS.GCHandle_Free (scrollViewerName);
+ OS.GCHandle_Free (template);
+ return scrollViewer;
+}
+
+/**
+ * Returns the width in pixels of a grid line.
+ *
+ * @return the width of a grid line in pixels
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public int getGridLineWidth () {
+ checkWidget ();
+ //TODO
+ return 0;
+}
+
+/**
+ * Returns the height of the receiver's header
+ *
+ * @return the height of the header or zero if the header is not visible
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public int getHeaderHeight () {
+ checkWidget ();
+ //TODO
+ return 0;
+}
+
+/**
+ * Returns <code>true</code> if the receiver's header is visible,
+ * and <code>false</code> otherwise.
+ * <p>
+ * If one of the receiver's ancestors is not visible or some
+ * other condition makes the receiver not visible, this method
+ * may still indicate that it is considered visible even though
+ * it may not actually be showing.
+ * </p>
+ *
+ * @return the receiver's header's visibility state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public boolean getHeaderVisible () {
+ checkWidget ();
+ //TODO
+ return false;
+}
+
+/**
+ * Returns the column at the given, zero-relative index in the
+ * receiver. Throws an exception if the index is out of range.
+ * Columns are returned in the order that they were created.
+ * If no <code>TreeColumn</code>s were created by the programmer,
+ * this method will throw <code>ERROR_INVALID_RANGE</code> despite
+ * the fact that a single column of data may be visible in the tree.
+ * This occurs when the programmer uses the tree like a list, adding
+ * items but never creating a column.
+ *
+ * @param index the index of the column to return
+ * @return the column at the given index
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Tree#getColumnOrder()
+ * @see Tree#setColumnOrder(int[])
+ * @see TreeColumn#getMoveable()
+ * @see TreeColumn#setMoveable(boolean)
+ * @see SWT#Move
+ *
+ * @since 3.1
+ */
+public TreeColumn getColumn (int index) {
+ checkWidget ();
+ if (!(0 <= index && index < columnCount)) error (SWT.ERROR_INVALID_RANGE);
+ return _getColumn (index);
+}
+
+TreeColumn _getColumn (int index) {
+ if (columnCount == 0) return null;
+ int gridColumn = OS.GridViewColumnCollection_default (columns, index);
+ int header = OS.GridViewColumn_Header (gridColumn);
+ int content = OS.ContentControl_Content (header);
+ TreeColumn column = (TreeColumn) OS.JNIGetObject (OS.IntPtr_ToInt32 (content));
+ OS.GCHandle_Free (gridColumn);
+ OS.GCHandle_Free (header);
+ OS.GCHandle_Free (content);
+ return column;
+}
+
+/**
+ * Returns the number of columns contained in the receiver.
+ * If no <code>TreeColumn</code>s were created by the programmer,
+ * this value is zero, despite the fact that visually, one column
+ * of items may be visible. This occurs when the programmer uses
+ * the tree like a list, adding items but never creating a column.
+ *
+ * @return the number of columns
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public int getColumnCount () {
+ checkWidget ();
+ return columnCount;
+}
+
+/**
+ * Returns an array of zero-relative integers that map
+ * the creation order of the receiver's items to the
+ * order in which they are currently being displayed.
+ * <p>
+ * Specifically, the indices of the returned array represent
+ * the current visual order of the items, and the contents
+ * of the array represent the creation order of the items.
+ * </p><p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its list of items, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ *
+ * @return the current visual order of the receiver's items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Tree#setColumnOrder(int[])
+ * @see TreeColumn#getMoveable()
+ * @see TreeColumn#setMoveable(boolean)
+ * @see SWT#Move
+ *
+ * @since 3.2
+ */
+public int[] getColumnOrder () {
+ checkWidget ();
+ //TODO
+ int [] order = new int [columnCount];
+ for (int i=0; i<order.length; i++) order [i] = i;
+ return order;
+}
+
+/**
+ * Returns an array of <code>TreeColumn</code>s which are the
+ * columns in the receiver. Columns are returned in the order
+ * that they were created. If no <code>TreeColumn</code>s were
+ * created by the programmer, the array is empty, despite the fact
+ * that visually, one column of items may be visible. This occurs
+ * when the programmer uses the tree like a list, adding items but
+ * never creating a column.
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its list of items, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ *
+ * @return the items in the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Tree#getColumnOrder()
+ * @see Tree#setColumnOrder(int[])
+ * @see TreeColumn#getMoveable()
+ * @see TreeColumn#setMoveable(boolean)
+ * @see SWT#Move
+ *
+ * @since 3.1
+ */
+public TreeColumn [] getColumns () {
+ checkWidget ();
+ TreeColumn [] treeColumns = new TreeColumn [columnCount];
+ for (int i = 0; i < treeColumns.length; i++) {
+ treeColumns [i] = _getColumn (i);
+ }
+ return treeColumns;
+}
+
+/**
+ * Returns the item at the given, zero-relative index in the
+ * receiver. Throws an exception if the index is out of range.
+ *
+ * @param index the index of the item to return
+ * @return the item at the given index
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public TreeItem getItem (int index) {
+ checkWidget ();
+ if (index < 0 || index >= itemCount) error (SWT.ERROR_INVALID_RANGE);
+ int items = OS.ItemsControl_Items (handle);
+ TreeItem treeItem = getItem (items, index, true);
+ OS.GCHandle_Free (items);
+ return treeItem;
+}
+
+TreeItem getItem (int items, int index, boolean create) {
+ int item = OS.ItemCollection_GetItemAt (items, index);
+ int header = OS.HeaderedItemsControl_Header (item);
+ int content = OS.GridViewRowPresenter_Content (header);
+ int contentValue = (int) OS.Point_X (content);
+ TreeItem result = null;
+ if (contentValue > 0) {
+ result = (TreeItem) OS.JNIGetObject (contentValue);
+ OS.GCHandle_Free (item);
+ } else {
+ if (create) {
+ result = new TreeItem (this, null, SWT.NONE, index, item);
+ } else {
+ OS.GCHandle_Free (item);
+ }
+ }
+ OS.GCHandle_Free (content);
+ OS.GCHandle_Free (header);
+ return result;
+}
+
+/**
+ * Returns the item at the given point in the receiver
+ * or null if no such item exists. The point is in the
+ * coordinate system of the receiver.
+ * <p>
+ * The item that is returned represents an item that could be selected by the user.
+ * For example, if selection only occurs in items in the first column, then null is
+ * returned if the point is outside of the item.
+ * Note that the SWT.FULL_SELECTION style hint, which specifies the selection policy,
+ * determines the extent of the selection.
+ * </p>
+ *
+ * @param point the point used to locate the item
+ * @return the item at the given point, or null if the point is not in a selectable item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public TreeItem getItem (Point point) {
+ checkWidget ();
+ if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int pt = OS.gcnew_Point (point.x, point.y);
+ int input = OS.UIElement_InputHitTest (handle, pt);
+ Widget widget = display.getWidget (input);
+ OS.GCHandle_Free (input);
+ OS.GCHandle_Free (pt);
+ if (widget == this) return null;
+ return (TreeItem) widget;
+}
+
+/**
+ * Returns the number of items contained in the receiver
+ * that are direct item children of the receiver. The
+ * number that is returned is the number of roots in the
+ * tree.
+ *
+ * @return the number of items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getItemCount () {
+ checkWidget ();
+ return itemCount;
+}
+
+/**
+ * Returns the height of the area which would be used to
+ * display <em>one</em> of the items in the tree.
+ *
+ * @return the height of one item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getItemHeight () {
+ checkWidget ();
+ //FIXME what is the default size?
+ if (itemCount == 0) return 16;
+ int items = OS.ItemsControl_Items (handle);
+ int item = OS.ItemCollection_GetItemAt (items, 0);
+ double height = OS.FrameworkElement_ActualHeight (item);
+ OS.GCHandle_Free (item);
+ OS.GCHandle_Free (items);
+ return (int) height;
+}
+
+/**
+ * Returns a (possibly empty) array of items contained in the
+ * receiver that are direct item children of the receiver. These
+ * are the roots of the tree.
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its list of items, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ *
+ * @return the items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public TreeItem [] getItems () {
+ checkWidget ();
+ TreeItem [] result = new TreeItem [itemCount];
+ int items = OS.ItemsControl_Items (handle);
+ for (int i = 0; i < itemCount; i++) {
+ result [i] = getItem (items, i, true);
+ }
+ OS.GCHandle_Free (items);
+ return result;
+}
+
+/**
+ * Returns <code>true</code> if the receiver's lines are visible,
+ * and <code>false</code> otherwise.
+ * <p>
+ * If one of the receiver's ancestors is not visible or some
+ * other condition makes the receiver not visible, this method
+ * may still indicate that it is considered visible even though
+ * it may not actually be showing.
+ * </p>
+ *
+ * @return the visibility state of the lines
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public boolean getLinesVisible () {
+ checkWidget ();
+ //TODO
+ return false;
+}
+
+/**
+ * Returns the receiver's parent item, which must be a
+ * <code>TreeItem</code> or null when the receiver is a
+ * root.
+ *
+ * @return the receiver's parent item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public TreeItem getParentItem () {
+ checkWidget ();
+ return null;
+}
+
+/**
+ * Returns an array of <code>TreeItem</code>s that are currently
+ * selected in the receiver. The order of the items is unspecified.
+ * An empty array indicates that no items are selected.
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its selection, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ * @return an array representing the selection
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public TreeItem [] getSelection () {
+ checkWidget ();
+ //TODO
+// if ((style & SWT.SINGLE) != 0) {
+ int item = OS.TreeView_SelectedItem (handle);
+ if (item == 0) return new TreeItem [0];
+ TreeItem result = (TreeItem) display.getWidget (item);
+ OS.GCHandle_Free (item);
+ return new TreeItem [] {result};
+// }
+// result = new TreeItem [0];
+}
+
+/**
+ * Returns the number of selected items contained in the receiver.
+ *
+ * @return the number of selected items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getSelectionCount () {
+ checkWidget ();
+ //TODO
+// if ((style & SWT.SINGLE) != 0) {
+ int item = OS.TreeView_SelectedItem (handle);
+ if (item == 0) return 0;
+ OS.GCHandle_Free (item);
+ return 1;
+// }
+// return 0;
+}
+
+/**
+ * Returns the column which shows the sort indicator for
+ * the receiver. The value may be null if no column shows
+ * the sort indicator.
+ *
+ * @return the sort indicator
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #setSortColumn(TreeColumn)
+ *
+ * @since 3.2
+ */
+public TreeColumn getSortColumn () {
+ checkWidget ();
+ //TODO
+ return null;
+}
+
+/**
+ * Returns the direction of the sort indicator for the receiver.
+ * The value will be one of <code>UP</code>, <code>DOWN</code>
+ * or <code>NONE</code>.
+ *
+ * @return the sort direction
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #setSortDirection(int)
+ *
+ * @since 3.2
+ */
+public int getSortDirection () {
+ checkWidget ();
+ //TODO
+ return SWT.NONE;
+}
+
+/**
+ * Returns the item which is currently at the top of the receiver.
+ * This item can change when items are expanded, collapsed, scrolled
+ * or new items are added or removed.
+ *
+ * @return the item at the top of the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.1
+ */
+public TreeItem getTopItem () {
+ checkWidget ();
+ //TODO
+ return null;
+}
+
+boolean hasItems () {
+ return true;
+}
+
+void HandleChecked (int sender, int e) {
+ if (!checkEvent (e)) return;
+ int source = OS.RoutedEventArgs_Source (e);
+ TreeItem item = (TreeItem) display.getWidget (source);
+ OS.GCHandle_Free (source);
+ if (item.grayed) {
+ int checkbox = item.findPart (0, CHECKBOX_PART_NAME);
+ if (checkbox != 0) {
+ OS.ToggleButton_IsCheckedNullSetter (checkbox);
+ OS.GCHandle_Free (checkbox);
+ }
+ }
+ item.checked = true;
+ Event event = new Event ();
+ event.item = item;
+ event.detail = SWT.CHECK;
+ sendEvent (SWT.Selection, event);
+}
+
+void HandleCollapsed (int sender, int e) {
+ if (!checkEvent (e)) return;
+ int source = OS.RoutedEventArgs_Source (e);
+ if (OS.ItemsControl_HasItems (source)) {
+ Event event = new Event ();
+ event.item = (TreeItem) display.getWidget (source);;
+ sendEvent (SWT.Collapse, event);
+ }
+ OS.GCHandle_Free (source);
+}
+
+int HandleConvert (int value, int targetType, int parameter, int culture) {
+ int content = (int) OS.Point_X (value);
+ TreeItem item;
+ if (content > 0) {
+ item = (TreeItem) OS.JNIGetObject (content);
+ } else {
+ int parentJniRef = (int) OS.Point_Y (value);
+ int items;
+ if (parentJniRef == jniRef) {
+ items = OS.ItemsControl_Items (handle);
+ } else {
+ TreeItem parentItem = (TreeItem) OS.JNIGetObject (parentJniRef);
+ items = OS.ItemsControl_Items (parentItem.handle);
+ }
+ item = getItem (items, -content, true);
+ OS.GCHandle_Free (items);
+ }
+ checkData (item);
+
+ int columnIndex = 0;
+ if (parameter != 0) {
+ TreeColumn column = (TreeColumn) OS.JNIGetObject (parameter);
+ columnIndex = indexOf (column);
+ }
+ int imageSourceType = OS.ImageSource_typeid ();
+ int result = 0;
+ if (OS.Object_Equals (imageSourceType, targetType)) {
+ if (item.images != null && item.images [columnIndex] != null) {
+ result = item.images [columnIndex].handle;
+ }
+ } else {
+ if (item.strings != null) {
+ if (item.stringHandle != null && item.stringHandle [columnIndex] != 0) {
+ result = item.stringHandle [columnIndex];
+ } else {
+ if (item.stringHandle == null) {
+ int count = Math.max (1, columnCount);
+ item.stringHandle = new int [count];
+ }
+ item.stringHandle [columnIndex] = result = createDotNetString (item.strings [columnIndex], false);
+ }
+ }
+ }
+ OS.GCHandle_Free (imageSourceType);
+ return result;
+}
+
+void HandleExpanded (int sender, int e) {
+ if (!checkEvent (e)) return;
+ int source = OS.RoutedEventArgs_Source (e);
+ if (OS.ItemsControl_HasItems (source)) {
+ Event event = new Event ();
+ event.item = (TreeItem) display.getWidget (source);;
+ sendEvent (SWT.Expand, event);
+ }
+ OS.GCHandle_Free (source);
+}
+
+void HandleIndeterminate (int sender, int e) {
+ if (!checkEvent (e)) return;
+ int source = OS.RoutedEventArgs_Source (e);
+ TreeItem item = (TreeItem) display.getWidget (source);
+ OS.GCHandle_Free (source);
+ if (!item.grayed) {
+ int checkbox = item.findPart (0, CHECKBOX_PART_NAME);
+ if (checkbox != 0) {
+ OS.ToggleButton_IsChecked (checkbox, false);
+ OS.GCHandle_Free (checkbox);
+ }
+ }
+}
+
+void HandleKeyDown (int sender, int e) {
+ if (!checkEvent (e)) return;
+ super.HandleKeyDown (sender, e);
+ int key = OS.KeyEventArgs_Key (e);
+ if (key == OS.Key_Return) {
+ int source = OS.RoutedEventArgs_OriginalSource (e);
+ Widget widget = display.getWidget (source);
+ OS.GCHandle_Free (source);
+ if (widget == this || widget == null) return;
+ TreeItem item = (TreeItem)widget;
+ Event event = new Event ();
+ event.item = item;
+ postEvent (SWT.DefaultSelection, event);
+ }
+}
+
+void HandleLoaded (int sender, int e) {
+ if (!checkEvent (e)) return;
+ int template = OS.Control_Template (handle);
+ int nameString = createDotNetString (HEADER_PART_NAME, false);
+ int header = OS.FrameworkTemplate_FindName (template, nameString, handle);
+ if (header != 0) {
+ OS.UIElement_Visibility (header, headerVisibility);
+ OS.GCHandle_Free (header);
+ }
+ OS.GCHandle_Free (nameString);
+ OS.GCHandle_Free (template);
+}
+
+void HandleMouseDoubleClick (int sender, int e) {
+ if (!checkEvent (e)) return;
+ int source = OS.RoutedEventArgs_OriginalSource (e);
+ Widget widget = display.getWidget (source);
+ OS.GCHandle_Free (source);
+ if (widget == this || widget == null) return;
+ TreeItem item = (TreeItem)widget;
+ Event event = new Event ();
+ event.item = item;
+ postEvent (SWT.DefaultSelection, event);
+}
+
+void HandleSelectedItemChanged (int sender, int e) {
+ if (!checkEvent (e)) return;
+ if (ignoreSelection) return;
+ int selectedItem = OS.TreeView_SelectedItem (handle);
+ if (selectedItem == 0) return;
+ TreeItem item = (TreeItem)display.getWidget (selectedItem);
+ Event event = new Event ();
+ event.item = item;
+ postEvent (SWT.Selection, event);
+}
+
+void HandleUnchecked (int sender, int e) {
+ if (!checkEvent (e)) return;
+ int source = OS.RoutedEventArgs_Source (e);
+ TreeItem item = (TreeItem) display.getWidget (source);
+ OS.GCHandle_Free (source);
+ item.checked = false;
+ Event event = new Event ();
+ event.item = item;
+ event.detail = SWT.CHECK;
+ sendEvent (SWT.Selection, event);
+}
+
+void hookEvents() {
+ super.hookEvents ();
+ int handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleLoaded");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.FrameworkElement_Loaded (handle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_RoutedPropertyChangedEventHandlerObject (jniRef, "HandleSelectedItemChanged");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.TreeView_SelectedItemChanged (handle, handler);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_MouseButtonEventHandler (jniRef, "HandleMouseDoubleClick");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.Control_MouseDoubleClick (handle, handler);
+ OS.GCHandle_Free (handler);
+
+ /* Item events */
+ handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleExpanded");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ int event = OS.TreeViewItem_ExpandedEvent ();
+ OS.UIElement_AddHandler (handle, event, handler);
+ OS.GCHandle_Free (event);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleCollapsed");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ event = OS.TreeViewItem_CollapsedEvent ();
+ OS.UIElement_AddHandler (handle, event, handler);
+ OS.GCHandle_Free (event);
+ OS.GCHandle_Free (handler);
+ if ((style & SWT.CHECK) != 0) {
+ handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleChecked");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ event = OS.ToggleButton_CheckedEvent ();
+ OS.UIElement_AddHandler (handle, event, handler);
+ OS.GCHandle_Free (event);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleUnchecked");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ event = OS.ToggleButton_UncheckedEvent ();
+ OS.UIElement_AddHandler (handle, event, handler);
+ OS.GCHandle_Free (event);
+ OS.GCHandle_Free (handler);
+ handler = OS.gcnew_RoutedEventHandler (jniRef, "HandleIndeterminate");
+ if (handler == 0) error (SWT.ERROR_NO_HANDLES);
+ event = OS.ToggleButton_IndeterminateEvent ();
+ OS.UIElement_AddHandler (handle, event, handler);
+ OS.GCHandle_Free (event);
+ OS.GCHandle_Free (handler);
+ }
+}
+
+/**
+ * Searches the receiver's list starting at the first column
+ * (index 0) until a column is found that is equal to the
+ * argument, and returns the index of that column. If no column
+ * is found, returns -1.
+ *
+ * @param column the search column
+ * @return the index of the column
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public int indexOf (TreeColumn column) {
+ checkWidget ();
+ if (column == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int index = OS.GridViewColumnCollection_IndexOf (columns, column.handle);
+ return index;
+}
+
+/**
+ * Searches the receiver's list starting at the first item
+ * (index 0) until an item is found that is equal to the
+ * argument, and returns the index of that item. If no item
+ * is found, returns -1.
+ *
+ * @param item the search item
+ * @return the index of the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the tool item is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the tool item has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public int indexOf (TreeItem item) {
+ checkWidget ();
+ if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (item.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ int items = OS.ItemsControl_Items (handle);
+ int index = OS.ItemCollection_IndexOf (items, item.handle);
+ OS.GCHandle_Free (items);
+ return index;
+}
+
+int parentingHandle () {
+ return parentingHandle;
+}
+
+void register() {
+ super.register();
+ display.addWidget (parentingHandle, this);
+}
+
+void releaseChildren (boolean destroy) {
+ int items = OS.ItemsControl_Items (handle);
+ for (int i=0; i<itemCount; i++) {
+ TreeItem item = getItem (items, i, false);
+ if (item != null && !item.isDisposed ()) item.release (false);
+ }
+ OS.GCHandle_Free (items);
+ for (int i=0; i<columnCount; i++) {
+ TreeColumn column = _getColumn(i);
+ if (column != null && !column.isDisposed ()) {
+ column.release (false);
+ }
+ }
+ super.releaseChildren (destroy);
+}
+
+void releaseHandle () {
+ super.releaseHandle ();
+ if (columns != 0) OS.GCHandle_Free (columns);
+ columns = 0;
+ OS.GCHandle_Free (parentingHandle);
+ parentingHandle = 0;
+}
+
+/**
+ * Removes all of the items from the receiver.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void removeAll () {
+ checkWidget ();
+ int items = OS.ItemsControl_Items (handle);
+ for (int i = 0; i < itemCount; i++) {
+ TreeItem item = getItem (items, i, false);
+ if (item != null && !item.isDisposed ()) item.release (false);
+ }
+ OS.ItemCollection_Clear (items);
+ itemCount = OS.ItemCollection_Count (items);
+ OS.GCHandle_Free (items);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the receiver's selection changes.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #addSelectionListener
+ */
+public void removeSelectionListener (SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ eventTable.unhook (SWT.Selection, listener);
+ eventTable.unhook (SWT.DefaultSelection, listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when items in the receiver are expanded or collapsed.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see TreeListener
+ * @see #addTreeListener
+ */
+public void removeTreeListener(TreeListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Expand, listener);
+ eventTable.unhook (SWT.Collapse, listener);
+}
+
+int setBounds (int x, int y, int width, int height, int flags) {
+ int result = super.setBounds (x, y, width, height, flags);
+ if ((result & RESIZED) != 0) {
+ if (columnCount == 0) {
+ int column = OS.GridViewColumnCollection_default (columns, 0);
+ OS.GridViewColumn_Width (column, width);
+ OS.GCHandle_Free (column);
+ }
+ OS.FrameworkElement_Width (handle, width);
+ OS.FrameworkElement_Height (handle, height);
+ }
+ return result;
+}
+
+/**
+ * Display a mark indicating the point at which an item will be inserted.
+ * The drop insert item has a visual hint to show where a dragged item
+ * will be inserted when dropped on the tree.
+ *
+ * @param item the insert item. Null will clear the insertion mark.
+ * @param before true places the insert mark above 'item'. false places
+ * the insert mark below 'item'.
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setInsertMark (TreeItem item, boolean before) {
+ checkWidget ();
+ if (item != null && item.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ //TODO
+}
+
+/**
+ * Sets the number of root-level items contained in the receiver.
+ *
+ * @param count the number of items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public void setItemCount (int count) {
+ checkWidget ();
+ setItemCount (null, count);
+}
+
+void setItemCount (TreeItem parentItem, int count) {
+ int itemCount = parentItem != null ? parentItem.itemCount : this.itemCount;
+ count = Math.max (0, count);
+ if (count == itemCount) return;
+ int parentHandle = parentItem != null ? parentItem.handle : handle;
+ int index = count;
+ int items = OS.ItemsControl_Items (parentHandle);
+ while (index < itemCount) {
+ TreeItem item = getItem (items, index, false);
+ if (item != null) {
+ if (!item.isDisposed()) item.release (false);
+ } else {
+ OS.ItemCollection_RemoveAt (items, index);
+ }
+ index++;
+ }
+ if (OS.ItemCollection_Count (items) > count) error (SWT.ERROR_ITEM_NOT_REMOVED);
+ if ((style & SWT.VIRTUAL) != 0) {
+ for (int i=itemCount; i<count; i++) {
+ int item = OS.gcnew_TreeViewItem ();
+ if (item == 0) error (SWT.ERROR_NO_HANDLES);
+ int headerHandle = OS.gcnew_SWTTreeViewRowPresenter (handle);
+ if (headerHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.GridViewRowPresenterBase_Columns (headerHandle, columns);
+ OS.HeaderedItemsControl_Header (item, headerHandle);
+ int parentJniRef = parentItem != null ? parentItem.jniRef : jniRef;
+ int content = OS.gcnew_Point (-i, parentJniRef);
+ OS.GridViewRowPresenter_Content (headerHandle, content);
+ OS.GCHandle_Free (content);
+ OS.GCHandle_Free (headerHandle);
+ OS.ItemCollection_Add (items, item);
+ OS.GCHandle_Free (item);
+ }
+ } else {
+ for (int i=itemCount; i<count; i++) {
+ new TreeItem (this, parentItem, SWT.NONE, i, 0);
+ }
+ }
+ itemCount = OS.ItemCollection_Count (items);
+ OS.GCHandle_Free (items);
+ if (itemCount != count) error (SWT.ERROR_ITEM_NOT_ADDED);
+ if (parentItem != null) {
+ parentItem.itemCount = itemCount;
+ } else {
+ this.itemCount = itemCount;
+ }
+}
+
+/**
+ * Sets the height of the area which would be used to
+ * display <em>one</em> of the items in the tree.
+ *
+ * @return the height of one item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+/*public*/ void setItemHeight (int itemHeight) {
+ checkWidget ();
+ if (itemHeight < -1) error (SWT.ERROR_INVALID_ARGUMENT);
+ //TODO
+}
+
+/**
+ * Marks the receiver's lines as visible if the argument is <code>true</code>,
+ * and marks it invisible otherwise.
+ * <p>
+ * If one of the receiver's ancestors is not visible or some
+ * other condition makes the receiver not visible, marking
+ * it visible may not actually cause it to be displayed.
+ * </p>
+ *
+ * @param show the new visibility state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public void setLinesVisible (boolean show) {
+ checkWidget ();
+ //TODO
+}
+
+/**
+ * Selects all of the items in the receiver.
+ * <p>
+ * If the receiver is single-select, do nothing.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void selectAll () {
+ checkWidget ();
+ if ((style & SWT.SINGLE) != 0) return;
+ //TODO
+}
+
+/**
+ * Sets the order that the items in the receiver should
+ * be displayed in to the given argument which is described
+ * in terms of the zero-relative ordering of when the items
+ * were added.
+ *
+ * @param order the new order to display the items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the item order is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the item order is not the same length as the number of items</li>
+ * </ul>
+ *
+ * @see Tree#getColumnOrder()
+ * @see TreeColumn#getMoveable()
+ * @see TreeColumn#setMoveable(boolean)
+ * @see SWT#Move
+ *
+ * @since 3.2
+ */
+public void setColumnOrder (int [] order) {
+ checkWidget ();
+ if (order == null) error (SWT.ERROR_NULL_ARGUMENT);
+ //TODO
+}
+
+void setForegroundBrush (int brush) {
+ if (brush != 0) {
+ OS.Control_Foreground (handle, brush);
+ } else {
+ int property = OS.Control_ForegroundProperty ();
+ OS.DependencyObject_ClearValue (handle, property);
+ OS.GCHandle_Free (property);
+ }
+}
+
+/**
+ * Marks the receiver's header as visible if the argument is <code>true</code>,
+ * and marks it invisible otherwise.
+ * <p>
+ * If one of the receiver's ancestors is not visible or some
+ * other condition makes the receiver not visible, marking
+ * it visible may not actually cause it to be displayed.
+ * </p>
+ *
+ * @param show the new visibility state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public void setHeaderVisible (boolean show) {
+ checkWidget ();
+ headerVisibility = show ? OS.Visibility_Visible : OS.Visibility_Collapsed;
+ int template = OS.Control_Template (handle);
+ int nameString = createDotNetString (HEADER_PART_NAME, false);
+ int header = OS.FrameworkTemplate_FindName (template, nameString, handle);
+ if (header != 0) {
+ OS.UIElement_Visibility (header, headerVisibility);
+ OS.GCHandle_Free (header);
+ }
+ OS.GCHandle_Free (nameString);
+ OS.GCHandle_Free (template);
+}
+
+/**
+ * Sets the receiver's selection to the given item.
+ * The current selection is cleared before the new item is selected.
+ * <p>
+ * If the item is not in the receiver, then it is ignored.
+ * </p>
+ *
+ * @param item the item to select
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the item is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public void setSelection (TreeItem item) {
+ checkWidget ();
+ if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
+ setSelection (new TreeItem [] {item});
+}
+
+/**
+ * Sets the receiver's selection to be the given array of items.
+ * The current selection is cleared before the new items are selected.
+ * <p>
+ * Items that are not in the receiver are ignored.
+ * If the receiver is single-select and multiple items are specified,
+ * then all items are ignored.
+ * </p>
+ *
+ * @param items the array of items
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the array of items is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if one of the items has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Tree#deselectAll()
+ */
+public void setSelection (TreeItem [] items) {
+ checkWidget ();
+ if (items == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int length = items.length;
+ if (length == 0 || ((style & SWT.SINGLE) != 0 && length > 1)) {
+ deselectAll ();
+ return;
+ }
+ int [] handles = new int [length];
+ for (int i = 0; i < items.length; i++) {
+ TreeItem item = items [i];
+ if (item.isDisposed ()) error (SWT.ERROR_WIDGET_DISPOSED);
+ handles [i] = item.handle;
+ }
+ ignoreSelection = true;
+ for (int i = 0; i < handles.length; i++) {
+ OS.TreeViewItem_IsSelected (handles [i], true);
+ }
+ ignoreSelection = false;
+}
+
+/**
+ * Sets the column used by the sort indicator for the receiver. A null
+ * value will clear the sort indicator. The current sort column is cleared
+ * before the new column is set.
+ *
+ * @param column the column used by the sort indicator or <code>null</code>
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the column is disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public void setSortColumn (TreeColumn column) {
+ checkWidget ();
+ //TODO
+}
+
+/**
+ * Sets the direction of the sort indicator for the receiver. The value
+ * can be one of <code>UP</code>, <code>DOWN</code> or <code>NONE</code>.
+ *
+ * @param direction the direction of the sort indicator
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public void setSortDirection (int direction) {
+ checkWidget ();
+ //TODO
+}
+
+/**
+ * Sets the item which is currently at the top of the receiver.
+ * This item can change when items are expanded, collapsed, scrolled
+ * or new items are added or removed.
+ *
+ * @param item the item to be shown
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the item is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Tree#getTopItem()
+ *
+ * @since 2.1
+ */
+public void setTopItem (TreeItem item) {
+ checkWidget ();
+ if (item == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+ if (item.isDisposed ()) SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+ //TODO
+}
+
+/**
+ * Shows the column. If the column is already showing in the receiver,
+ * this method simply returns. Otherwise, the columns are scrolled until
+ * the column is visible.
+ *
+ * @param column the column to be shown
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the item is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public void showColumn (TreeColumn column) {
+ checkWidget ();
+ if (column == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (column.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ if (column.parent != this) return;
+ int index = indexOf (column);
+ if (index == -1) return;
+ //TODO
+}
+
+/**
+ * Shows the item. If the item is already showing in the receiver,
+ * this method simply returns. Otherwise, the items are scrolled
+ * and expanded until the item is visible.
+ *
+ * @param item the item to be shown
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the item is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Tree#showSelection()
+ */
+public void showItem (TreeItem item) {
+ checkWidget ();
+ if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (item.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ //TODO
+}
+
+/**
+ * Shows the selection. If the selection is already showing in the receiver,
+ * this method simply returns. Otherwise, the items are scrolled until
+ * the selection is visible.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Tree#showItem(TreeItem)
+ */
+public void showSelection () {
+ checkWidget ();
+ //TODO
+}
+
+int topHandle () {
+ return parentingHandle;
+}
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TreeColumn.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TreeColumn.java
new file mode 100644
index 0000000000..5fa1ceedc0
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TreeColumn.java
@@ -0,0 +1,611 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.events.*;
+
+/**
+ * Instances of this class represent a column in a tree widget.
+ * <p><dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>LEFT, RIGHT, CENTER</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd> Move, Resize, Selection</dd>
+ * </dl>
+ * </p><p>
+ * Note: Only one of the styles LEFT, RIGHT and CENTER may be specified.
+ * </p><p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ *
+ * @since 3.1
+ */
+public class TreeColumn extends Item {
+ Tree parent;
+ //TODO - get header handle when needed instead of keeping reference
+ int headerHandle;
+ int stringPtr;
+ boolean moveable, resizable;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * (which must be a <code>Tree</code>) and a style value
+ * describing its behavior and appearance. The item is added
+ * to the end of the items maintained by its parent.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#LEFT
+ * @see SWT#RIGHT
+ * @see SWT#CENTER
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public TreeColumn (Tree parent, int style) {
+ this (checkNull(parent), checkStyle (style), parent.columnCount);
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * (which must be a <code>Tree</code>), a style value
+ * describing its behavior and appearance, and the index
+ * at which to place it in the items maintained by its parent.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ * @param index the zero-relative index to store the receiver in its parent
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#LEFT
+ * @see SWT#RIGHT
+ * @see SWT#CENTER
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public TreeColumn (Tree parent, int style, int index) {
+ super (parent, checkStyle (style));
+ resizable = true;
+ this.parent = parent;
+ parent.createItem (this, index);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the control is moved or resized, by sending
+ * it one of the messages defined in the <code>ControlListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ControlListener
+ * @see #removeControlListener
+ */
+public void addControlListener(ControlListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Resize,typedListener);
+ addListener (SWT.Move,typedListener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the control is selected, by sending
+ * it one of the messages defined in the <code>SelectionListener</code>
+ * interface.
+ * <p>
+ * <code>widgetSelected</code> is called when the column header is selected.
+ * <code>widgetDefaultSelected</code> is not called.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #removeSelectionListener
+ * @see SelectionEvent
+ */
+public void addSelectionListener (SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Selection,typedListener);
+ addListener (SWT.DefaultSelection,typedListener);
+}
+
+static Tree checkNull (Tree tree) {
+ if (tree == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+ return tree;
+}
+
+static int checkStyle (int style) {
+ return checkBits (style, SWT.LEFT, SWT.CENTER, SWT.RIGHT, 0, 0, 0);
+}
+
+protected void checkSubclass () {
+ if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
+}
+
+int ConvertImage (int value, int targetType, int parameter, int culture) {
+ return image != null ? image.handle : 0;
+}
+
+int ConvertText (int value, int targetType, int parameter, int culture) {
+ int result = 0;
+ if (text != null) {
+ result = stringPtr;
+ if (result == 0) {
+ result = stringPtr = createDotNetString (text, false);
+ }
+ }
+ return result;
+}
+
+void createHandle () {
+ handle = OS.gcnew_GridViewColumn ();
+ if (handle == 0) SWT.error (SWT.ERROR_NO_HANDLES);
+ headerHandle = OS.gcnew_GridViewColumnHeader ();
+ int content = OS.gcnew_IntPtr (jniRef);
+ OS.GridViewColumn_Header (handle, headerHandle);
+ OS.GridViewColumnHeader_Content (headerHandle, content);
+ OS.GridViewColumn_Width(handle, 0);
+ OS.GCHandle_Free (content);
+}
+
+void destroyWidget () {
+ parent.destroyItem (this);
+ releaseHandle ();
+}
+
+int findContentPresenter (int element, int contentPresenterType) {
+ int type = OS.Object_GetType (element);
+ boolean found = OS.Object_Equals (contentPresenterType, type);
+ OS.GCHandle_Free (type);
+ if (found) return element;
+ int count = OS.VisualTreeHelper_GetChildrenCount (element);
+ for (int i = 0; i < count; i++) {
+ int child = OS.VisualTreeHelper_GetChild (element, i);
+ int result = findContentPresenter (child, contentPresenterType);
+ if (child != result) OS.GCHandle_Free (child);
+ if (result != 0) return result;
+ }
+ return 0;
+}
+
+int findPart (String part) {
+ int contentPresenterType = OS.ContentPresenter_typeid();
+ int contentPresenter = findContentPresenter(headerHandle, contentPresenterType);
+ int result = 0;
+ if (contentPresenter != 0) {
+ int template = OS.GridViewColumn_HeaderTemplate (handle);
+ int strPtr = createDotNetString (part, false);
+ result = OS.FrameworkTemplate_FindName (template, strPtr, contentPresenter);
+ OS.GCHandle_Free (strPtr);
+ OS.GCHandle_Free (template);
+ OS.GCHandle_Free (contentPresenter);
+ }
+ OS.GCHandle_Free (contentPresenterType);
+ return result;
+}
+
+/**
+ * Returns a value which describes the position of the
+ * text or image in the receiver. The value will be one of
+ * <code>LEFT</code>, <code>RIGHT</code> or <code>CENTER</code>.
+ *
+ * @return the alignment
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getAlignment () {
+ checkWidget ();
+ if ((style & SWT.LEFT) != 0) return SWT.LEFT;
+ if ((style & SWT.CENTER) != 0) return SWT.CENTER;
+ if ((style & SWT.RIGHT) != 0) return SWT.RIGHT;
+ return SWT.LEFT;
+}
+
+/**
+ * Gets the moveable attribute. A column that is
+ * not moveable cannot be reordered by the user
+ * by dragging the header but may be reordered
+ * by the programmer.
+ *
+ * @return the moveable attribute
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Tree#getColumnOrder()
+ * @see Tree#setColumnOrder(int[])
+ * @see TreeColumn#setMoveable(boolean)
+ * @see SWT#Move
+ *
+ * @since 3.2
+ */
+public boolean getMoveable () {
+ checkWidget ();
+ return moveable;
+}
+
+String getNameText () {
+ return getText ();
+}
+
+/**
+ * Returns the receiver's parent, which must be a <code>Tree</code>.
+ *
+ * @return the receiver's parent
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Tree getParent () {
+ checkWidget ();
+ return parent;
+}
+
+/**
+ * Gets the resizable attribute. A column that is
+ * not resizable cannot be dragged by the user but
+ * may be resized by the programmer.
+ *
+ * @return the resizable attribute
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getResizable () {
+ checkWidget ();
+ return resizable;
+}
+
+/**
+ * Returns the receiver's tool tip text, or null if it has
+ * not been set.
+ *
+ * @return the receiver's tool tip text
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public String getToolTipText () {
+ checkWidget();
+ int strPtr = OS.FrameworkElement_ToolTip (headerHandle);
+ String string = createJavaString (strPtr);
+ OS.GCHandle_Free (strPtr);
+ return string;
+}
+
+/**
+ * Gets the width of the receiver.
+ *
+ * @return the width
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getWidth () {
+ checkWidget ();
+ return (int) OS.GridViewColumn_ActualWidth(handle);
+}
+
+int HandleConvert (int value, int targetType, int parameter, int culture) {
+ int imageSourceType = OS.ImageSource_typeid ();
+ int result = 0;
+ if (OS.Object_Equals (imageSourceType, targetType)) {
+ if (image != null) result = image.handle;
+ } else {
+ if (text != null) {
+ result = stringPtr;
+ if (result == 0) {
+ result = stringPtr = createDotNetString (text, false);
+ }
+ }
+ }
+ OS.GCHandle_Free (imageSourceType);
+ return result;
+}
+
+/**
+ * Causes the receiver to be resized to its preferred size.
+ * For a composite, this involves computing the preferred size
+ * from its layout, if there is one.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ */
+public void pack () {
+ checkWidget ();
+ int index = parent.indexOf (this);
+ if (index == -1) return;
+ int widthProperty = OS.GridViewColumn_WidthProperty ();
+ OS.DependencyObject_ClearValue (handle, widthProperty);
+ OS.GCHandle_Free (widthProperty);
+ OS.UIElement_UpdateLayout (headerHandle);
+}
+
+void releaseHandle () {
+ super.releaseHandle ();
+ if (handle != 0) OS.GCHandle_Free (handle);
+ handle = 0;
+ OS.GCHandle_Free (headerHandle);
+ headerHandle = 0;
+ parent = null;
+}
+
+void releaseWidget () {
+ super.releaseWidget ();
+ if (stringPtr != 0) OS.GCHandle_Free (stringPtr);
+ stringPtr = 0;
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the control is moved or resized.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ControlListener
+ * @see #addControlListener
+ */
+public void removeControlListener (ControlListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Move, listener);
+ eventTable.unhook (SWT.Resize, listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the control is selected.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #addSelectionListener
+ */
+public void removeSelectionListener(SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Selection, listener);
+ eventTable.unhook (SWT.DefaultSelection,listener);
+}
+
+/**
+ * Controls how text and images will be displayed in the receiver.
+ * The argument should be one of <code>LEFT</code>, <code>RIGHT</code>
+ * or <code>CENTER</code>.
+ *
+ * @param alignment the new alignment
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setAlignment (int alignment) {
+ checkWidget ();
+ if ((alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER)) == 0) return;
+ int index = parent.indexOf (this);
+ if (index == -1 || index == 0) return;
+ style &= ~(SWT.LEFT | SWT.RIGHT | SWT.CENTER);
+ style |= alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER);
+ //TODO
+}
+
+public void setImage (Image image) {
+ checkWidget();
+ super.setImage (image);
+ int part = findPart (Tree.IMAGE_PART_NAME);
+ if (part != 0) {
+ int property = OS.Image_SourceProperty ();
+ int bindingExpression = OS.FrameworkElement_GetBindingExpression (part, property);
+ OS.BindingExpression_UpdateTarget (bindingExpression);
+ OS.GCHandle_Free (bindingExpression);
+ OS.GCHandle_Free (property);
+ OS.GCHandle_Free (part);
+ }
+}
+
+/**
+ * Sets the moveable attribute. A column that is
+ * moveable can be reordered by the user by dragging
+ * the header. A column that is not moveable cannot be
+ * dragged by the user but may be reordered
+ * by the programmer.
+ *
+ * @param moveable the moveable attribute
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Tree#setColumnOrder(int[])
+ * @see Tree#getColumnOrder()
+ * @see TreeColumn#getMoveable()
+ * @see SWT#Move
+ *
+ * @since 3.2
+ */
+public void setMoveable (boolean moveable) {
+ checkWidget ();
+ this.moveable = moveable;
+}
+
+/**
+ * Sets the resizable attribute. A column that is
+ * not resizable cannot be dragged by the user but
+ * may be resized by the programmer.
+ *
+ * @param resizable the resize attribute
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setResizable (boolean resizable) {
+ checkWidget ();
+ this.resizable = resizable;
+}
+
+void setSortDirection (int direction) {
+ //TODO
+}
+
+public void setText (String string) {
+ checkWidget ();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (string.equals (text)) return;
+ super.setText (string);
+ if (stringPtr != 0) {
+ OS.GCHandle_Free (stringPtr);
+ stringPtr = 0;
+ }
+ int part = findPart (Tree.TEXT_PART_NAME);
+ if (part != 0) {
+ int property = OS.TextBlock_TextProperty ();
+ int bindingExpression = OS.FrameworkElement_GetBindingExpression (part, property);
+ OS.BindingExpression_UpdateTarget (bindingExpression);
+ OS.GCHandle_Free (bindingExpression);
+ OS.GCHandle_Free (property);
+ OS.GCHandle_Free (part);
+ }
+}
+
+/**
+ * Sets the receiver's tool tip text to the argument, which
+ * may be null indicating that no tool tip text should be shown.
+ *
+ * @param string the new tool tip text (or null)
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public void setToolTipText (String string) {
+ checkWidget();
+ int strPtr = createDotNetString (string, false);
+ OS.FrameworkElement_ToolTip (headerHandle, strPtr);
+ OS.GCHandle_Free (strPtr);
+}
+
+/**
+ * Sets the width of the receiver.
+ *
+ * @param width the new width
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setWidth (int width) {
+ checkWidget ();
+ OS.GridViewColumn_Width (handle, width);
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TreeItem.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TreeItem.java
new file mode 100644
index 0000000000..778b330acb
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/TreeItem.java
@@ -0,0 +1,1304 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Instances of this class represent a selectable user interface object
+ * that represents a hierarchy of tree items in a tree widget.
+ *
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>(none)</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * <p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ */
+
+public class TreeItem extends Item {
+ int [] stringHandle;
+ Tree parent;
+ String [] strings;
+ Image [] images;
+ int itemCount;
+ boolean checked, grayed, cached;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * (which must be a <code>Tree</code> or a <code>TreeItem</code>)
+ * and a style value describing its behavior and appearance.
+ * The item is added to the end of the items maintained by its parent.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a tree control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public TreeItem (Tree parent, int style) {
+ this (checkNull (parent), null, style, parent.itemCount, 0);
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * (which must be a <code>Tree</code> or a <code>TreeItem</code>),
+ * a style value describing its behavior and appearance, and the index
+ * at which to place it in the items maintained by its parent.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a tree control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ * @param index the zero-relative index to store the receiver in its parent
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public TreeItem (Tree parent, int style, int index) {
+ this (checkNull (parent), null, style, index, 0);
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * (which must be a <code>Tree</code> or a <code>TreeItem</code>)
+ * and a style value describing its behavior and appearance.
+ * The item is added to the end of the items maintained by its parent.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parentItem a tree control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public TreeItem (TreeItem parentItem, int style) {
+ this (checkNull (parentItem).parent, parentItem, style, parentItem.itemCount, 0);
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * (which must be a <code>Tree</code> or a <code>TreeItem</code>),
+ * a style value describing its behavior and appearance, and the index
+ * at which to place it in the items maintained by its parent.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parentItem a tree control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ * @param index the zero-relative index to store the receiver in its parent
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public TreeItem (TreeItem parentItem, int style, int index) {
+ this (checkNull (parentItem).parent, parentItem, style, index, 0);
+}
+
+TreeItem (Tree parent, TreeItem parentItem, int style, int index, int handle) {
+ super (parent, style);
+ this.parent = parent;
+ this.handle = handle;
+ if (handle == 0) {
+ parent.createItem (this, parentItem, index);
+ } else {
+ createWidget ();
+ }
+}
+
+static Tree checkNull (Tree tree) {
+ if (tree == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+ return tree;
+}
+
+static TreeItem checkNull (TreeItem item) {
+ if (item == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+ return item;
+}
+
+protected void checkSubclass () {
+ if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
+}
+
+void clear () {
+ text = "";
+ image = null;
+ strings = null;
+ images = null;
+// background = foreground = font = -1;
+// cellBackground = cellForeground = cellFont = null;
+// if ((parent.style & SWT.VIRTUAL) != 0) cached = false;
+}
+
+/**
+ * Clears the item at the given zero-relative index in the receiver.
+ * The text, icon and other attributes of the item are set to the default
+ * value. If the tree was created with the <code>SWT.VIRTUAL</code> style,
+ * these attributes are requested again as needed.
+ *
+ * @param index the index of the item to clear
+ * @param all <code>true</code> if all child items of the indexed item should be
+ * cleared recursively, and <code>false</code> otherwise
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SWT#VIRTUAL
+ * @see SWT#SetData
+ *
+ * @since 3.2
+ */
+public void clear (int index, boolean all) {
+ checkWidget ();
+// int hwnd = parent.handle;
+// int hItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, handle);
+// if (hItem == 0) error (SWT.ERROR_INVALID_RANGE);
+// hItem = parent.findItem (hItem, index);
+// if (hItem == 0) error (SWT.ERROR_INVALID_RANGE);
+// TVITEM tvItem = new TVITEM ();
+// tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM;
+// parent.clear (hItem, tvItem);
+// if (all) {
+// hItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, hItem);
+// parent.clearAll (hItem, tvItem, all);
+// }
+}
+
+/**
+ * Clears all the items in the receiver. The text, icon and other
+ * attributes of the items are set to their default values. If the
+ * tree was created with the <code>SWT.VIRTUAL</code> style, these
+ * attributes are requested again as needed.
+ *
+ * @param all <code>true</code> if all child items should be cleared
+ * recursively, and <code>false</code> otherwise
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SWT#VIRTUAL
+ * @see SWT#SetData
+ *
+ * @since 3.2
+ */
+public void clearAll (boolean all) {
+ checkWidget ();
+// int hwnd = parent.handle;
+// int hItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, handle);
+// if (hItem == 0) return;
+// TVITEM tvItem = new TVITEM ();
+// tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM;
+// parent.clearAll (hItem, tvItem, all);
+}
+
+void columnInserted(int index) {
+ int newLength = parent.columnCount + 1;
+ if (strings != null && strings.length == newLength) return;
+ if (strings != null) {
+ String [] temp = new String [newLength];
+ System.arraycopy (strings, 0, temp, 0, index);
+ System.arraycopy (strings, index, temp, index + 1, parent.columnCount - index);
+ strings = temp;
+ }
+ if (stringHandle != null) {
+ int [] temp = new int [newLength];
+ System.arraycopy (stringHandle, 0, temp, 0, index);
+ System.arraycopy (stringHandle, index, temp, index + 1, parent.columnCount - index);
+ stringHandle = temp;
+ }
+ if (images != null) {
+ Image [] temp = new Image [newLength];
+ System.arraycopy (images, 0, temp, 0, index);
+ System.arraycopy (images, index, temp, index + 1, parent.columnCount - index);
+ images = temp;
+ }
+ int items = OS.ItemsControl_Items (handle);
+ for (int i=0; i<itemCount; i++) {
+ TreeItem item = parent.getItem (items, i, false);
+ if (item != null) {
+ item.columnInserted (index);
+ }
+ }
+ OS.GCHandle_Free (items);
+}
+
+public void columnRemoved(int index) {
+ if (strings != null) {
+ String [] temp = new String [parent.columnCount];
+ System.arraycopy (strings, 0, temp, 0, index);
+ System.arraycopy (strings, index + 1, temp, index, parent.columnCount - index);
+ strings = temp;
+ }
+ if (stringHandle != null) {
+ int [] temp = new int [parent.columnCount];
+ System.arraycopy (stringHandle, 0, temp, 0, index);
+ System.arraycopy (stringHandle, index + 1, temp, index, parent.columnCount - index);
+ if (stringHandle [index] != 0) OS.GCHandle_Free (stringHandle [index]);
+ stringHandle = temp;
+ }
+ if (images != null) {
+ Image [] temp = new Image [parent.columnCount];
+ System.arraycopy (images, 0, temp, 0, index);
+ System.arraycopy (images, index + 1, temp, index, parent.columnCount - index);
+ images = temp;
+ }
+ int items = OS.ItemsControl_Items (handle);
+ for (int i=0; i<itemCount; i++) {
+ TreeItem item = parent.getItem (items, i, false);
+ if (item != null) {
+ item.columnRemoved (index);
+ }
+ }
+ OS.GCHandle_Free (items);
+}
+
+void createHandle () {
+ int headerHandle;
+ if (handle == 0) {
+ handle = OS.gcnew_TreeViewItem ();
+ if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+ headerHandle = OS.gcnew_SWTTreeViewRowPresenter (parent.handle);
+ if (headerHandle == 0) error (SWT.ERROR_NO_HANDLES);
+ OS.GridViewRowPresenterBase_Columns (headerHandle, parent.columns);
+ OS.HeaderedItemsControl_Header (handle, headerHandle);
+ } else {
+ headerHandle = OS.HeaderedItemsControl_Header (handle);
+ }
+ int content = OS.gcnew_Point (jniRef, 0);
+ OS.GridViewRowPresenter_Content (headerHandle, content);
+ OS.GCHandle_Free (headerHandle);
+ OS.GCHandle_Free (content);
+}
+
+void deregister () {
+ display.removeWidget (handle);
+}
+
+void destroyWidget () {
+ parent.destroyItem (this);
+ super.destroyWidget ();
+}
+
+int findContentPresenter (int element, int column) {
+ int controlTemplate = OS.Control_Template (handle);
+ int headerName = createDotNetString ("PART_Header", false);
+ int partHeader = OS.FrameworkTemplate_FindName (controlTemplate, headerName, handle);
+ //TODO - test this on classic look
+ int rowPresenter = OS.VisualTreeHelper_GetChild (partHeader, 0);
+ int contentPresenter = OS.VisualTreeHelper_GetChild (rowPresenter, column);
+ OS.GCHandle_Free (partHeader);
+ OS.GCHandle_Free (headerName);
+ OS.GCHandle_Free (controlTemplate);
+ OS.GCHandle_Free(rowPresenter);
+ return contentPresenter;
+}
+
+int findPart (int column, String part) {
+ if (!OS.FrameworkElement_IsLoaded (handle)) return 0;
+ if (OS.UIElement_Visibility (handle) != OS.Visibility_Visible) return 0;
+ int contentPresenter = findContentPresenter (handle, column);
+ int columnHandle = OS.GridViewColumnCollection_default (parent.columns, column);
+ int cellTemplate = OS.GridViewColumn_CellTemplate (columnHandle);
+ int name = createDotNetString (part, false);
+ int result = OS.FrameworkTemplate_FindName (cellTemplate, name, contentPresenter);
+ OS.GCHandle_Free (columnHandle);
+ if (name != 0) OS.GCHandle_Free (name);
+ OS.GCHandle_Free (cellTemplate);
+ OS.GCHandle_Free (contentPresenter);
+ return result;
+}
+
+/**
+ * Returns the receiver's background color.
+ *
+ * @return the background color
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.0
+ *
+ */
+public Color getBackground () {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ return parent.getBackground ();
+}
+
+/**
+ * Returns the background color at the given column index in the receiver.
+ *
+ * @param index the column index
+ * @return the background color
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public Color getBackground (int index) {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ return parent.getBackground ();
+}
+
+/**
+ * Returns a rectangle describing the receiver's size and location
+ * relative to its parent.
+ *
+ * @return the receiver's bounding rectangle
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Rectangle getBounds () {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ //BUG?
+ if (!OS.UIElement_IsVisible(handle)) return new Rectangle (0, 0, 0, 0);
+ int point = OS.gcnew_Point (0, 0);
+ int location = OS.UIElement_TranslatePoint (handle, point, parent.handle);
+ int x = (int) OS.Point_X (location);
+ int y = (int) OS.Point_Y (location);
+ OS.GCHandle_Free (point);
+ OS.GCHandle_Free (location);
+ int width = (int) OS.FrameworkElement_ActualWidth (handle);
+ int height = (int) OS.FrameworkElement_ActualHeight (handle);
+ return new Rectangle (x, y, width, height);
+}
+
+/**
+ * Returns a rectangle describing the receiver's size and location
+ * relative to its parent at a column in the tree.
+ *
+ * @param index the index that specifies the column
+ * @return the receiver's bounding column rectangle
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public Rectangle getBounds (int index) {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ if (!(0 <= index && index < parent.columnCount)) return new Rectangle (0, 0, 0, 0);
+ if (!OS.UIElement_IsVisible (handle)) return new Rectangle (0, 0, 0, 0);
+ int point = OS.gcnew_Point (0, 0);
+ OS.UIElement_UpdateLayout (handle);
+ int contentPresenter = findContentPresenter (handle, index);
+ int location = OS.UIElement_TranslatePoint (contentPresenter, point, parent.handle);
+ int x = (int) OS.Point_X (location);
+ int y = (int) OS.Point_Y (location);
+ OS.GCHandle_Free (point);
+ OS.GCHandle_Free (location);
+ int width = (int) OS.FrameworkElement_ActualWidth (contentPresenter);
+ int height = (int) OS.FrameworkElement_ActualHeight (contentPresenter);
+ return new Rectangle (x, y, width, height);
+}
+
+/**
+ * Returns <code>true</code> if the receiver is checked,
+ * and false otherwise. When the parent does not have
+ * the <code>CHECK style, return false.
+ * <p>
+ *
+ * @return the checked state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getChecked () {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ if ((parent.style & SWT.CHECK) == 0) return false;
+ return checked;
+}
+
+/**
+ * Returns <code>true</code> if the receiver is expanded,
+ * and false otherwise.
+ * <p>
+ *
+ * @return the expanded state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getExpanded () {
+ checkWidget ();
+ return OS.TreeViewItem_IsExpanded (handle);
+}
+
+/**
+ * Returns the font that the receiver will use to paint textual information for this item.
+ *
+ * @return the receiver's font
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public Font getFont () {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ return parent.getFont ();
+}
+
+/**
+ * Returns the font that the receiver will use to paint textual information
+ * for the specified cell in this item.
+ *
+ * @param index the column index
+ * @return the receiver's font
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public Font getFont (int index) {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ return parent.getFont ();
+}
+
+/**
+ * Returns the foreground color that the receiver will use to draw.
+ *
+ * @return the receiver's foreground color
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.0
+ *
+ */
+public Color getForeground () {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ return parent.getForeground ();
+}
+
+/**
+ *
+ * Returns the foreground color at the given column index in the receiver.
+ *
+ * @param index the column index
+ * @return the foreground color
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public Color getForeground (int index) {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ return parent.getForeground ();
+}
+
+/**
+ * Returns <code>true</code> if the receiver is grayed,
+ * and false otherwise. When the parent does not have
+ * the <code>CHECK style, return false.
+ * <p>
+ *
+ * @return the grayed state of the checkbox
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getGrayed () {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ if ((parent.style & SWT.CHECK) == 0) return false;
+ return false;
+}
+
+/**
+ * Returns the item at the given, zero-relative index in the
+ * receiver. Throws an exception if the index is out of range.
+ *
+ * @param index the index of the item to return
+ * @return the item at the given index
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public TreeItem getItem (int index) {
+ checkWidget ();
+ if (index < 0 || index >= itemCount) error (SWT.ERROR_INVALID_RANGE);
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ int items = OS.ItemsControl_Items (handle);
+ TreeItem item = parent.getItem (items, index, true);
+ OS.GCHandle_Free (items);
+ return item;
+}
+
+/**
+ * Returns the number of items contained in the receiver
+ * that are direct item children of the receiver.
+ *
+ * @return the number of items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getItemCount () {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ return itemCount;
+}
+
+/**
+ * Returns a (possibly empty) array of <code>TreeItem</code>s which
+ * are the direct item children of the receiver.
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its list of items, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ *
+ * @return the receiver's items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public TreeItem [] getItems () {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ int items = OS.ItemsControl_Items (handle);
+ TreeItem [] result = new TreeItem [itemCount];
+ for (int i = 0; i < result.length; i++) {
+ result [i] = parent.getItem (items, i, true);
+ }
+ OS.GCHandle_Free (items);
+ return result;
+}
+
+public Image getImage () {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ return super.getImage ();
+}
+
+/**
+ * Returns the image stored at the given column index in the receiver,
+ * or null if the image has not been set or if the column does not exist.
+ *
+ * @param index the column index
+ * @return the image stored at the given column index in the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public Image getImage (int index) {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ if (index == 0) return getImage ();
+ if (images != null) {
+ if (0 <= index && index < images.length) return images [index];
+ }
+ return null;
+}
+
+/**
+ * Returns a rectangle describing the size and location
+ * relative to its parent of an image at a column in the
+ * tree.
+ *
+ * @param index the index that specifies the column
+ * @return the receiver's bounding image rectangle
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public Rectangle getImageBounds (int index) {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ //TODO
+ return new Rectangle (0, 0, 0, 0);
+}
+
+/**
+ * Returns the receiver's parent, which must be a <code>Tree</code>.
+ *
+ * @return the receiver's parent
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Tree getParent () {
+ checkWidget ();
+ return parent;
+}
+
+/**
+ * Returns the receiver's parent item, which must be a
+ * <code>TreeItem</code> or null when the receiver is a
+ * root.
+ *
+ * @return the receiver's parent item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public TreeItem getParentItem () {
+ checkWidget ();
+ int parentItem = OS.FrameworkElement_Parent (handle);
+ TreeItem result = null;
+ if (!OS.Object_Equals (parentItem, parent.handle)) {
+ result = (TreeItem) display.getWidget (parentItem);
+ }
+ OS.GCHandle_Free (parentItem);
+ return result;
+}
+
+public String getText () {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ return getText (0);
+}
+
+/**
+ * Returns the text stored at the given column index in the receiver,
+ * or empty string if the text has not been set.
+ *
+ * @param index the column index
+ * @return the text stored at the given column index in the receiver
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public String getText (int index) {
+ checkWidget ();
+ if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED);
+ if (strings != null) {
+ if (0 <= index && index < strings.length) {
+ String string = strings [index];
+ return string != null ? string : "";
+ }
+ }
+ return "";
+}
+
+Control getWidgetControl () {
+ return parent;
+}
+
+/**
+ * Searches the receiver's list starting at the first item
+ * (index 0) until an item is found that is equal to the
+ * argument, and returns the index of that item. If no item
+ * is found, returns -1.
+ *
+ * @param item the search item
+ * @return the index of the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the tool item is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the tool item has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public int indexOf (TreeItem item) {
+ checkWidget ();
+ if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (item.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+ int items = OS.ItemsControl_Items (handle);
+ int index = OS.ItemCollection_IndexOf(items, item.handle);
+ OS.GCHandle_Free (items);
+ return index;
+}
+
+void register () {
+ display.addWidget (handle, this);
+}
+
+void releaseChildren (boolean destroy) {
+ int items = OS.ItemsControl_Items (handle);
+ for (int i=0; i<itemCount; i++) {
+ TreeItem item = parent.getItem (items, i, false);
+ if (item != null && !item.isDisposed ()) item.release (false);
+ }
+ OS.GCHandle_Free (items);
+ super.releaseChildren (destroy);
+}
+
+void releaseHandle () {
+ super.releaseHandle ();
+ if (handle != 0) OS.GCHandle_Free (handle);
+ handle = 0;
+ parent = null;
+}
+
+void releaseWidget () {
+ super.releaseWidget ();
+ if (stringHandle != null) {
+ for (int i = 0; i < stringHandle.length; i++) {
+ if (stringHandle [i] != 0) OS.GCHandle_Free (stringHandle [i]);
+ }
+ }
+ stringHandle = null;
+ strings = null;
+ images = null;
+}
+
+/**
+ * Removes all of the items from the receiver.
+ * <p>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public void removeAll () {
+ checkWidget ();
+ int items = OS.ItemsControl_Items (handle);
+ for (int i = 0; i < itemCount; i++) {
+ TreeItem item = parent.getItem (items, i, false);
+ if (item != null && !item.isDisposed ()) item.release (false);
+ }
+ OS.ItemCollection_Clear (items);
+ OS.GCHandle_Free (items);
+}
+
+void resetImage (int index) {
+ if (OS.FrameworkElement_IsLoaded (handle)) {
+ int part = findPart (index, Table.IMAGE_PART_NAME);
+ int property = OS.Image_SourceProperty ();
+ int bindingExpression = OS.FrameworkElement_GetBindingExpression (part, property);
+ OS.BindingExpression_UpdateTarget (bindingExpression);
+ OS.GCHandle_Free (part);
+ OS.GCHandle_Free (property);
+ OS.GCHandle_Free (bindingExpression);
+ }
+}
+
+void resetText (int index) {
+ if (OS.FrameworkElement_IsLoaded (handle)) {
+ int part = findPart (index, Table.TEXT_PART_NAME);
+ int property = OS.TextBlock_TextProperty ();
+ int bindingExpression = OS.FrameworkElement_GetBindingExpression (part, property);
+ OS.BindingExpression_UpdateTarget (bindingExpression);
+ OS.GCHandle_Free (part);
+ OS.GCHandle_Free (property);
+ OS.GCHandle_Free (bindingExpression);
+ }
+}
+
+/**
+ * Sets the receiver's background color to the color specified
+ * by the argument, or to the default system color for the item
+ * if the argument is null.
+ *
+ * @param color the new color (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.0
+ *
+ */
+public void setBackground (Color color) {
+ checkWidget ();
+ if (color != null && color.isDisposed ()) {
+ SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+ //TODO
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
+}
+
+/**
+ * Sets the background color at the given column index in the receiver
+ * to the color specified by the argument, or to the default system color for the item
+ * if the argument is null.
+ *
+ * @param index the column index
+ * @param color the new color (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ *
+ */
+public void setBackground (int index, Color color) {
+ checkWidget ();
+ if (color != null && color.isDisposed ()) {
+ SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+ int count = Math.max (1, parent.getColumnCount ());
+ if (0 > index || index > count - 1) return;
+ //TODO
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
+}
+
+/**
+ * Sets the checked state of the receiver.
+ * <p>
+ *
+ * @param checked the new checked state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setChecked (boolean checked) {
+ checkWidget ();
+ if ((parent.style & SWT.CHECK) == 0) return;
+ //TODO
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
+}
+
+/**
+ * Sets the expanded state of the receiver.
+ * <p>
+ *
+ * @param expanded the new expanded state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setExpanded (boolean expanded) {
+ checkWidget ();
+ OS.TreeViewItem_IsExpanded (handle, expanded);
+}
+
+/**
+ * Sets the font that the receiver will use to paint textual information
+ * for this item to the font specified by the argument, or to the default font
+ * for that kind of control if the argument is null.
+ *
+ * @param font the new font (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void setFont (Font font){
+ checkWidget ();
+ if (font != null && font.isDisposed ()) {
+ SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+ //TODO
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
+}
+
+
+/**
+ * Sets the font that the receiver will use to paint textual information
+ * for the specified cell in this item to the font specified by the
+ * argument, or to the default font for that kind of control if the
+ * argument is null.
+ *
+ * @param index the column index
+ * @param font the new font (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public void setFont (int index, Font font) {
+ checkWidget ();
+ if (font != null && font.isDisposed ()) {
+ SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+ int count = Math.max (1, parent.getColumnCount ());
+ if (0 > index || index > count - 1) return;
+ //TODO
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
+}
+
+/**
+ * Sets the receiver's foreground color to the color specified
+ * by the argument, or to the default system color for the item
+ * if the argument is null.
+ *
+ * @param color the new color (or null)
+ *
+ * @since 2.0
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 2.0
+ *
+ */
+public void setForeground (Color color) {
+ checkWidget ();
+ if (color != null && color.isDisposed ()) {
+ SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+ //TODO
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
+}
+
+/**
+ * Sets the foreground color at the given column index in the receiver
+ * to the color specified by the argument, or to the default system color for the item
+ * if the argument is null.
+ *
+ * @param index the column index
+ * @param color the new color (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ *
+ */
+public void setForeground (int index, Color color){
+ checkWidget ();
+ if (color != null && color.isDisposed ()) {
+ SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+ int count = Math.max (1, parent.getColumnCount ());
+ if (0 > index || index > count - 1) return;
+ //TODO
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
+}
+
+/**
+ * Sets the grayed state of the checkbox for this item. This state change
+ * only applies if the Tree was created with the SWT.CHECK style.
+ *
+ * @param grayed the new grayed state of the checkbox
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setGrayed (boolean grayed) {
+ checkWidget ();
+ if ((parent.style & SWT.CHECK) == 0) return;
+ this.grayed = grayed;
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
+}
+
+/**
+ * Sets the image for multiple columns in the tree.
+ *
+ * @param images the array of new images
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the array of images is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if one of the images has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public void setImage (Image [] images) {
+ checkWidget ();
+ if (images == null) error (SWT.ERROR_NULL_ARGUMENT);
+ for (int i=0; i<images.length; i++) {
+ setImage (i, images [i]);
+ }
+}
+
+/**
+ * Sets the receiver's image at a column.
+ *
+ * @param index the column index
+ * @param image the new image
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public void setImage (int index, Image image) {
+ checkWidget();
+ if (image != null && image.isDisposed ()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ int count = Math.max (1, parent.getColumnCount ());
+ if (0 > index || index > count - 1) return;
+ if (images == null) {
+ images = new Image [count];
+ }
+ images [index] = image;
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
+ resetImage (index);
+}
+
+public void setImage (Image image) {
+ checkWidget ();
+ setImage (0, image);
+}
+
+/**
+ * Sets the number of child items contained in the receiver.
+ *
+ * @param count the number of items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public void setItemCount (int count) {
+ checkWidget ();
+ parent.setItemCount (this, count);
+}
+
+/**
+ * Sets the text for multiple columns in the tree.
+ *
+ * @param strings the array of new strings
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public void setText (String [] strings) {
+ checkWidget ();
+ if (strings == null) error (SWT.ERROR_NULL_ARGUMENT);
+ for (int i=0; i<strings.length; i++) {
+ String string = strings [i];
+ if (string != null) setText (i, string);
+ }
+}
+
+/**
+ * Sets the receiver's text at a column
+ *
+ * @param index the column index
+ * @param string the new text
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public void setText (int index, String string) {
+ checkWidget();
+ if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int count = Math.max(1, parent.getColumnCount ());
+ if (0 > index || index > count - 1) return;
+
+ if (strings == null) {
+ strings = new String [count];
+ }
+ if (string.equals (strings [index])) return;
+ strings [index] = string;
+ if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
+ if (stringHandle != null && stringHandle [index] != 0) {
+ OS.GCHandle_Free (stringHandle [index]);
+ stringHandle [index] = 0;
+ }
+ resetText (index);
+}
+
+public void setText (String string) {
+ checkWidget ();
+ setText (0, string);
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Widget.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Widget.java
new file mode 100644
index 0000000000..a519875153
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/Widget.java
@@ -0,0 +1,1364 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.*;
+import org.eclipse.swt.internal.wpf.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.events.*;
+
+/**
+ * This class is the abstract superclass of all user interface objects.
+ * Widgets are created, disposed and issue notification to listeners
+ * when events occur which affect them.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>(none)</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Dispose</dd>
+ * </dl>
+ * <p>
+ * IMPORTANT: This class is intended to be subclassed <em>only</em>
+ * within the SWT implementation. However, it has not been marked
+ * final to allow those outside of the SWT development team to implement
+ * patched versions of the class in order to get around specific
+ * limitations in advance of when those limitations can be addressed
+ * by the team. Any class built using subclassing to access the internals
+ * of this class will likely fail to compile or run between releases and
+ * may be strongly platform specific. Subclassing should not be attempted
+ * without an intimate and detailed understanding of the workings of the
+ * hierarchy. No support is provided for user-written classes which are
+ * implemented as subclasses of this class.
+ * </p>
+ *
+ * @see #checkSubclass
+ */
+
+public abstract class Widget {
+ /**
+ * the handle to the OS resource
+ * (Warning: This field is platform dependent)
+ * <p>
+ * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
+ * public API. It is marked public only so that it can be shared
+ * within the packages provided by SWT. It is not available on all
+ * platforms and should never be accessed from application code.
+ * </p>
+ */
+ public int handle;
+ int jniRef;
+ int style, state;
+ Display display;
+ EventTable eventTable;
+ Object data;
+
+ /* Global state flags */
+ static final int DISPOSED = 1<<0;
+ static final int CANVAS = 1<<1;
+ static final int KEYED_DATA = 1<<2;
+ static final int DISABLED = 1<<3;
+ static final int HIDDEN = 1<<4;
+
+ /* A layout was requested on this widget */
+ static final int LAYOUT_NEEDED = 1<<5;
+
+ /* The preferred size of a child has changed */
+ static final int LAYOUT_CHANGED = 1<<6;
+
+ /* A layout was requested in this widget hierachy */
+ static final int LAYOUT_CHILD = 1<<7;
+
+ /* Background flags */
+ static final int THEME_BACKGROUND = 1<<8;
+ static final int DRAW_BACKGROUND = 1<<9;
+ static final int PARENT_BACKGROUND = 1<<10;
+
+ /* Dispose and release flags */
+ static final int RELEASED = 1<<11;
+ static final int DISPOSE_SENT = 1<<12;
+
+
+ static final int MOVED = 1<<13;
+ static final int RESIZED = 1<<14;
+
+ /* Mouse track flag */
+ static final int TRACK_MOUSE = 1<<13;
+
+ /* Default size for widgets */
+ static final int DEFAULT_WIDTH = 64;
+ static final int DEFAULT_HEIGHT = 64;
+
+
+ static final int CLICK = 1;
+
+/**
+ * Prevents uninitialized instances from being created outside the package.
+ */
+Widget () {
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a widget which will be the parent of the new instance (cannot be null)
+ * @param style the style of widget to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the parent is disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT
+ * @see #checkSubclass
+ * @see #getStyle
+ */
+public Widget (Widget parent, int style) {
+ checkSubclass ();
+ checkParent (parent);
+ this.style = style;
+ display = parent.display;
+}
+
+void _addListener (int eventType, Listener listener) {
+ if (eventTable == null) eventTable = new EventTable ();
+ eventTable.hook (eventType, listener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when an event of the given type occurs. When the
+ * event does occur in the widget, the listener is notified by
+ * sending it the <code>handleEvent()</code> message. The event
+ * type is one of the event constants defined in class <code>SWT</code>.
+ *
+ * @param eventType the type of event to listen for
+ * @param listener the listener which should be notified when the event occurs
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Listener
+ * @see SWT
+ * @see #removeListener
+ * @see #notifyListeners
+ */
+public void addListener (int eventType, Listener listener) {
+ checkWidget();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ _addListener (eventType, listener);
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the widget is disposed. When the widget is
+ * disposed, the listener is notified by sending it the
+ * <code>widgetDisposed()</code> message.
+ *
+ * @param listener the listener which should be notified when the receiver is disposed
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see DisposeListener
+ * @see #removeDisposeListener
+ */
+public void addDisposeListener (DisposeListener listener) {
+ checkWidget();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Dispose, typedListener);
+}
+
+void addWidget () {
+}
+
+/**
+ * Returns a style with exactly one style bit set out of
+ * the specified set of exclusive style bits. All other
+ * possible bits are cleared when the first matching bit
+ * is found. Bits that are not part of the possible set
+ * are untouched.
+ *
+ * @param style the original style bits
+ * @param int0 the 0th possible style bit
+ * @param int1 the 1st possible style bit
+ * @param int2 the 2nd possible style bit
+ * @param int3 the 3rd possible style bit
+ * @param int4 the 4th possible style bit
+ * @param int5 the 5th possible style bit
+ *
+ * @return the new style bits
+ */
+static int checkBits (int style, int int0, int int1, int int2, int int3, int int4, int int5) {
+ int mask = int0 | int1 | int2 | int3 | int4 | int5;
+ if ((style & mask) == 0) style |= int0;
+ if ((style & int0) != 0) style = (style & ~mask) | int0;
+ if ((style & int1) != 0) style = (style & ~mask) | int1;
+ if ((style & int2) != 0) style = (style & ~mask) | int2;
+ if ((style & int3) != 0) style = (style & ~mask) | int3;
+ if ((style & int4) != 0) style = (style & ~mask) | int4;
+ if ((style & int5) != 0) style = (style & ~mask) | int5;
+ return style;
+}
+
+boolean checkEvent (int e) {
+ if (isDisposed ()) return false;
+ int routedEventType = OS.RoutedEventArgs_typeid ();
+ int source = 0;
+ if (OS.Type_IsInstanceOfType (routedEventType, e)) {
+ source = OS.RoutedEventArgs_Source (e);
+ }
+ OS.GCHandle_Free (routedEventType);
+ if (source == 0) return true;
+ if (OS.Object_Equals (source, handle)) {
+ OS.GCHandle_Free (source);
+ return true;
+ }
+ Widget widget = display.getWidget (source);
+ OS.GCHandle_Free (source);
+ if (widget == this) return true;
+ if (hasItems ()) {
+ if (this == widget.getWidgetControl ()) return true;
+ }
+ return false;
+}
+
+void checkOrientation (Widget parent) {
+ style &= ~SWT.MIRRORED;
+ if ((style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT)) == 0) {
+ if (parent != null) {
+ if ((parent.style & SWT.LEFT_TO_RIGHT) != 0) style |= SWT.LEFT_TO_RIGHT;
+ if ((parent.style & SWT.RIGHT_TO_LEFT) != 0) style |= SWT.RIGHT_TO_LEFT;
+ }
+ }
+ style = checkBits (style, SWT.LEFT_TO_RIGHT, SWT.RIGHT_TO_LEFT, 0, 0, 0, 0);
+}
+
+void checkOpened () {
+ /* Do nothing */
+}
+
+/**
+ * Throws an exception if the specified widget can not be
+ * used as a parent for the receiver.
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the parent is disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * </ul>
+ */
+void checkParent (Widget parent) {
+ if (parent == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (parent.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+ parent.checkWidget ();
+ parent.checkOpened ();
+}
+
+/**
+ * Checks that this class can be subclassed.
+ * <p>
+ * The SWT class library is intended to be subclassed
+ * only at specific, controlled points (most notably,
+ * <code>Composite</code> and <code>Canvas</code> when
+ * implementing new widgets). This method enforces this
+ * rule unless it is overridden.
+ * </p><p>
+ * <em>IMPORTANT:</em> By providing an implementation of this
+ * method that allows a subclass of a class which does not
+ * normally allow subclassing to be created, the implementer
+ * agrees to be fully responsible for the fact that any such
+ * subclass will likely fail between SWT releases and will be
+ * strongly platform specific. No support is provided for
+ * user-written classes which are implemented in this fashion.
+ * </p><p>
+ * The ability to subclass outside of the allowed SWT classes
+ * is intended purely to enable those not on the SWT development
+ * team to implement patches in order to get around specific
+ * limitations in advance of when those limitations can be
+ * addressed by the team. Subclassing should not be attempted
+ * without an intimate and detailed understanding of the hierarchy.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ */
+protected void checkSubclass () {
+ if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
+}
+
+/**
+ * Throws an <code>SWTException</code> if the receiver can not
+ * be accessed by the caller. This may include both checks on
+ * the state of the receiver and more generally on the entire
+ * execution context. This method <em>should</em> be called by
+ * widget implementors to enforce the standard SWT invariants.
+ * <p>
+ * Currently, it is an error to invoke any method (other than
+ * <code>isDisposed()</code>) on a widget that has had its
+ * <code>dispose()</code> method called. It is also an error
+ * to call widget methods from any thread that is different
+ * from the thread that created the widget.
+ * </p><p>
+ * In future releases of SWT, there may be more or fewer error
+ * checks and exceptions may be thrown for different reasons.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+protected void checkWidget () {
+ Display display = this.display;
+ if (display == null) error (SWT.ERROR_WIDGET_DISPOSED);
+ if (display.thread != Thread.currentThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
+ if ((state & DISPOSED) != 0) error (SWT.ERROR_WIDGET_DISPOSED);
+}
+
+void createHandle () {
+}
+
+int createDotNetString (String string, boolean fixMnemonic) {
+ if (string == null) return 0;
+ char [] buffer;
+ if (fixMnemonic) {
+ buffer = fixMnemonic (string);
+ } else {
+ int length = string.length ();
+ buffer = new char [length + 1];
+ string.getChars (0, length, buffer, 0);
+ }
+ int ptr = OS.gcnew_String (buffer);
+ if (ptr == 0) error (SWT.ERROR_NO_HANDLES);
+ return ptr;
+}
+
+String createJavaString (int ptr) {
+ int charArray = OS.String_ToCharArray (ptr);
+ char[] chars = new char[OS.String_Length (ptr)];
+ OS.memmove (chars, charArray, chars.length * 2);
+ OS.GCHandle_Free (charArray);
+ return new String (chars);
+}
+
+void createWidget () {
+ jniRef = OS.NewGlobalRef (this);
+ if (jniRef == 0) error (SWT.ERROR_NO_HANDLES);
+ createHandle ();
+ addWidget ();
+ register ();
+ hookEvents ();
+}
+
+/**
+ * Destroys the widget in the operating system and releases
+ * the widget's handle. If the widget does not have a handle,
+ * this method may hide the widget, mark the widget as destroyed
+ * or do nothing, depending on the widget.
+ * <p>
+ * When a widget is destroyed in the operating system, its
+ * descendents are also destroyed by the operating system.
+ * This means that it is only necessary to call <code>destroyWidget</code>
+ * on the root of the widget tree.
+ * </p><p>
+ * This method is called after <code>releaseWidget()</code>.
+ * </p><p>
+ * See also <code>releaseChild()</code>, <code>releaseWidget()</code>
+ * and <code>releaseHandle()</code>.
+ * </p>
+ *
+ * @see #dispose
+ */
+void destroyWidget () {
+ releaseHandle ();
+}
+
+/**
+ * Disposes of the operating system resources associated with
+ * the receiver and all its descendents. After this method has
+ * been invoked, the receiver and all descendents will answer
+ * <code>true</code> when sent the message <code>isDisposed()</code>.
+ * Any internal connections between the widgets in the tree will
+ * have been removed to facilitate garbage collection.
+ * <p>
+ * NOTE: This method is not called recursively on the descendents
+ * of the receiver. This means that, widget implementers can not
+ * detect when a widget is being disposed of by re-implementing
+ * this method, but should instead listen for the <code>Dispose</code>
+ * event.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #addDisposeListener
+ * @see #removeDisposeListener
+ * @see #checkWidget
+ */
+public void dispose () {
+ /*
+ * Note: It is valid to attempt to dispose a widget
+ * more than once. If this happens, fail silently.
+ */
+ if (isDisposed ()) return;
+ if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
+ release (true);
+}
+
+boolean dragDetect (int x, int y) {
+ return hooks (SWT.DragDetect);
+}
+
+boolean dragOverride () {
+ return false;
+}
+
+void dumpObjectType (int object) {
+ int type = OS.Type_FullName(OS.Object_GetType(object));
+ String typeName = createJavaString(type);
+ OS.GCHandle_Free(type);
+ System.out.println(typeName);
+}
+
+void dumpVisualTree (int visual, int depth) {
+ for (int i = 0; i < depth; i++) System.out.print ("\t");
+ int type = OS.Type_FullName(OS.Object_GetType(visual));
+ String typeName = createJavaString (type);
+ int name = OS.FrameworkElement_Name (visual);
+ String widgetName = createJavaString (name);
+ OS.GCHandle_Free(type);
+ OS.GCHandle_Free (name);
+ System.out.println(typeName + " ["+widgetName+"]");
+ int count = OS.VisualTreeHelper_GetChildrenCount(visual);
+ for (int i = 0; i < count; i++) {
+ int child = OS.VisualTreeHelper_GetChild (visual, i);
+ dumpVisualTree(child, depth+1);
+ OS.GCHandle_Free(child);
+ }
+}
+/**
+ * Does whatever widget specific cleanup is required, and then
+ * uses the code in <code>SWTError.error</code> to handle the error.
+ *
+ * @param code the descriptive error code
+ *
+ * @see SWT#error(int)
+ */
+void error (int code) {
+ SWT.error(code);
+}
+
+boolean filters (int eventType) {
+ return display.filters (eventType);
+}
+
+char [] fixMnemonic (String string) {
+ int length = string.length ();
+ char [] text = new char [length];
+ string.getChars (0, length, text, 0);
+ int i = 0, j = 0;
+ char [] result = new char [length * 2 + 1];
+ while (i < length) {
+ switch (text [i]) {
+ case '&':
+ if (i + 1 < length && text [i + 1] == '&') {
+ i++;
+ } else {
+ text [i] = '_';
+ }
+ break;
+ case '_':
+ result [j++] = '_';
+ break;
+ }
+ result [j++] = text [i++];
+ }
+ return result;
+}
+
+/**
+ * Returns the application defined widget data associated
+ * with the receiver, or null if it has not been set. The
+ * <em>widget data</em> is a single, unnamed field that is
+ * stored with every widget.
+ * <p>
+ * Applications may put arbitrary objects in this field. If
+ * the object stored in the widget data needs to be notified
+ * when the widget is disposed of, it is the application's
+ * responsibility to hook the Dispose event on the widget and
+ * do so.
+ * </p>
+ *
+ * @return the widget data
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - when the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - when called from the wrong thread</li>
+ * </ul>
+ *
+ * @see #setData(Object)
+ */
+public Object getData () {
+ checkWidget();
+ return (state & KEYED_DATA) != 0 ? ((Object []) data) [0] : data;
+}
+
+/**
+ * Returns the application defined property of the receiver
+ * with the specified name, or null if it has not been set.
+ * <p>
+ * Applications may have associated arbitrary objects with the
+ * receiver in this fashion. If the objects stored in the
+ * properties need to be notified when the widget is disposed
+ * of, it is the application's responsibility to hook the
+ * Dispose event on the widget and do so.
+ * </p>
+ *
+ * @param key the name of the property
+ * @return the value of the property or null if it has not been set
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the key is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #setData(String, Object)
+ */
+public Object getData (String key) {
+ checkWidget();
+ if (key == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if ((state & KEYED_DATA) != 0) {
+ Object [] table = (Object []) data;
+ for (int i=1; i<table.length; i+=2) {
+ if (key.equals (table [i])) return table [i+1];
+ }
+ }
+ return null;
+}
+
+/**
+ * Returns the <code>Display</code> that is associated with
+ * the receiver.
+ * <p>
+ * A widget's display is either provided when it is created
+ * (for example, top level <code>Shell</code>s) or is the
+ * same as its parent's display.
+ * </p>
+ *
+ * @return the receiver's display
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public Display getDisplay () {
+ Display display = this.display;
+ if (display == null) error (SWT.ERROR_WIDGET_DISPOSED);
+ return display;
+}
+
+Menu getMenu () {
+ return null;
+}
+
+/**
+ * Returns the name of the widget. This is the name of
+ * the class without the package name.
+ *
+ * @return the name of the widget
+ */
+String getName () {
+ String string = getClass ().getName ();
+ int index = string.lastIndexOf ('.');
+ if (index == -1) return string;
+ return string.substring (index + 1, string.length ());
+}
+
+/*
+ * Returns a short printable representation for the contents
+ * of a widget. For example, a button may answer the label
+ * text. This is used by <code>toString</code> to provide a
+ * more meaningful description of the widget.
+ *
+ * @return the contents string for the widget
+ *
+ * @see #toString
+ */
+String getNameText () {
+ return ""; //$NON-NLS-1$
+}
+
+/**
+ * Returns the receiver's style information.
+ * <p>
+ * Note that the value which is returned by this method <em>may
+ * not match</em> the value which was provided to the constructor
+ * when the receiver was created. This can occur when the underlying
+ * operating system does not support a particular combination of
+ * requested styles. For example, if the platform widget used to
+ * implement a particular SWT widget always has scroll bars, the
+ * result of calling this method would always have the
+ * <code>SWT.H_SCROLL</code> and <code>SWT.V_SCROLL</code> bits set.
+ * </p>
+ *
+ * @return the style bits
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getStyle () {
+ checkWidget();
+ return style;
+}
+
+Control getWidgetControl () {
+ return null;
+}
+
+boolean hasItems () {
+ return false;
+}
+
+void hookEvents () {
+}
+
+/*
+ * Returns <code>true</code> if the specified eventType is
+ * hooked, and <code>false</code> otherwise. Implementations
+ * of SWT can avoid creating objects and sending events
+ * when an event happens in the operating system but
+ * there are no listeners hooked for the event.
+ *
+ * @param eventType the event to be checked
+ *
+ * @return <code>true</code> when the eventType is hooked and <code>false</code> otherwise
+ *
+ * @see #isListening
+ */
+boolean hooks (int eventType) {
+ if (eventTable == null) return false;
+ return eventTable.hooks (eventType);
+}
+
+/**
+ * Returns <code>true</code> if the widget has been disposed,
+ * and <code>false</code> otherwise.
+ * <p>
+ * This method gets the dispose state for the widget.
+ * When a widget has been disposed, it is an error to
+ * invoke any other method using the widget.
+ * </p>
+ *
+ * @return <code>true</code> when the widget is disposed and <code>false</code> otherwise
+ */
+public boolean isDisposed () {
+ return (state & DISPOSED) != 0;
+}
+
+/**
+ * Returns <code>true</code> if there are any listeners
+ * for the specified event type associated with the receiver,
+ * and <code>false</code> otherwise. The event type is one of
+ * the event constants defined in class <code>SWT</code>.
+ *
+ * @param eventType the type of event
+ * @return true if the event is hooked
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SWT
+ */
+public boolean isListening (int eventType) {
+ checkWidget();
+ return hooks (eventType);
+}
+
+/*
+ * Returns <code>true</code> when subclassing is
+ * allowed and <code>false</code> otherwise
+ *
+ * @return <code>true</code> when subclassing is allowed and <code>false</code> otherwise
+ */
+boolean isValidSubclass () {
+ return Display.isValidClass (getClass ());
+}
+
+/*
+ * Returns <code>true</code> when the current thread is
+ * the thread that created the widget and <code>false</code>
+ * otherwise.
+ *
+ * @return <code>true</code> when the current thread is the thread that created the widget and <code>false</code> otherwise
+ */
+boolean isValidThread () {
+ return getDisplay ().isValidThread ();
+}
+
+void mapEvent (int hwnd, Event event) {
+}
+
+boolean mnemonicMatch (int accessText, char key) {
+ if (accessText == 0) return false;
+ char mnemonic = OS.AccessText_AccessKey (accessText);
+ return Character.toLowerCase (key) == Character.toLowerCase (mnemonic);
+}
+
+/**
+ * Notifies all of the receiver's listeners for events
+ * of the given type that one such event has occurred by
+ * invoking their <code>handleEvent()</code> method. The
+ * event type is one of the event constants defined in class
+ * <code>SWT</code>.
+ *
+ * @param eventType the type of event which has occurred
+ * @param event the event data
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SWT
+ * @see #addListener
+ * @see #removeListener
+ */
+public void notifyListeners (int eventType, Event event) {
+ checkWidget();
+ if (event == null) event = new Event ();
+ sendEvent (eventType, event);
+}
+
+void postEvent (int eventType) {
+ sendEvent (eventType, null, false);
+}
+
+void postEvent (int eventType, Event event) {
+ sendEvent (eventType, event, false);
+}
+
+void register () {
+}
+
+/*
+ * Releases the widget hiearchy and optionally destroys
+ * the receiver.
+ * <p>
+ * Typically, a widget with children will broadcast this
+ * message to all children so that they too can release their
+ * resources. The <code>releaseHandle</code> method is used
+ * as part of this broadcast to zero the handle fields of the
+ * children without calling <code>destroyWidget</code>. In
+ * this scenario, the children are actually destroyed later,
+ * when the operating system destroys the widget tree.
+ * </p>
+ *
+ * @param destroy indicates that the receiver should be destroyed
+ *
+ * @see #dispose
+ * @see #releaseHandle
+ * @see #releaseParent
+ * @see #releaseWidget
+*/
+void release (boolean destroy) {
+ if ((state & DISPOSE_SENT) == 0) {
+ state |= DISPOSE_SENT;
+ sendEvent (SWT.Dispose);
+ }
+ if ((state & DISPOSED) == 0) {
+ releaseChildren (destroy);
+ }
+ if ((state & RELEASED) == 0) {
+ state |= RELEASED;
+ if (destroy) {
+ releaseParent ();
+ releaseWidget ();
+ destroyWidget ();
+ } else {
+ releaseWidget ();
+ releaseHandle ();
+ }
+ }
+}
+
+void releaseChildren (boolean destroy) {
+}
+
+/*
+ * Releases the widget's handle by zero'ing it out.
+ * Does not destroy or release any operating system
+ * resources.
+ * <p>
+ * This method is called after <code>releaseWidget</code>
+ * or from <code>destroyWidget</code> when a widget is being
+ * destroyed to ensure that the widget is marked as destroyed
+ * in case the act of destroying the widget in the operating
+ * system causes application code to run in callback that
+ * could access the widget.
+ * </p>
+ *
+ * @see #dispose
+ * @see #releaseChildren
+ * @see #releaseParent
+ * @see #releaseWidget
+ */
+void releaseHandle () {
+ state |= DISPOSED;
+ display = null;
+ if (jniRef != 0) OS.DeleteGlobalRef (jniRef);
+ jniRef = 0;
+}
+
+/*
+ * Releases the receiver, a child in a widget hierarchy,
+ * from its parent.
+ * <p>
+ * When a widget is destroyed, it may be necessary to remove
+ * it from an internal data structure of the parent. When
+ * a widget has no handle, it may also be necessary for the
+ * parent to hide the widget or otherwise indicate that the
+ * widget has been disposed. For example, disposing a menu
+ * bar requires that the menu bar first be released from the
+ * shell when the menu bar is active.
+ * </p>
+ *
+ * @see #dispose
+ * @see #releaseChildren
+ * @see #releaseWidget
+ * @see #releaseHandle
+ */
+void releaseParent () {
+}
+
+/*
+ * Releases any internal resources back to the operating
+ * system and clears all fields except the widget handle.
+ * <p>
+ * When a widget is destroyed, resources that were acquired
+ * on behalf of the programmer need to be returned to the
+ * operating system. For example, if the widget made a
+ * copy of an icon, supplied by the programmer, this copy
+ * would be freed in <code>releaseWidget</code>. Also,
+ * to assist the garbage collector and minimize the amount
+ * of memory that is not reclaimed when the programmer keeps
+ * a reference to a disposed widget, all fields except the
+ * handle are zero'd. The handle is needed by <code>destroyWidget</code>.
+ * </p>
+ *
+ * @see #dispose
+ * @see #releaseChildren
+ * @see #releaseHandle
+ * @see #releaseParent
+ */
+void releaseWidget () {
+ eventTable = null;
+ data = null;
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when an event of the given type occurs. The event
+ * type is one of the event constants defined in class <code>SWT</code>.
+ *
+ * @param eventType the type of event to listen for
+ * @param listener the listener which should no longer be notified when the event occurs
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Listener
+ * @see SWT
+ * @see #addListener
+ * @see #notifyListeners
+ */
+public void removeListener (int eventType, Listener listener) {
+ checkWidget();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (eventType, listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when an event of the given type occurs.
+ * <p>
+ * <b>IMPORTANT:</b> This method is <em>not</em> part of the SWT
+ * public API. It is marked public only so that it can be shared
+ * within the packages provided by SWT. It should never be
+ * referenced from application code.
+ * </p>
+ *
+ * @param eventType the type of event to listen for
+ * @param listener the listener which should no longer be notified when the event occurs
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Listener
+ * @see #addListener
+ */
+protected void removeListener (int eventType, SWTEventListener listener) {
+ checkWidget();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (eventType, listener);
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the widget is disposed.
+ *
+ * @param listener the listener which should no longer be notified when the receiver is disposed
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see DisposeListener
+ * @see #addDisposeListener
+ */
+public void removeDisposeListener (DisposeListener listener) {
+ checkWidget();
+ if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (eventTable == null) return;
+ eventTable.unhook (SWT.Dispose, listener);
+}
+
+boolean sendDragEvent (int x, int y) {
+ Event event = new Event ();
+ event.x = x;
+ event.y = y;
+ postEvent (SWT.DragDetect, event);
+ if (isDisposed ()) return false;
+ return event.doit;
+}
+
+void sendEvent (Event event) {
+ Display display = event.display;
+ if (!display.filterEvent (event)) {
+ if (eventTable != null) eventTable.sendEvent (event);
+ }
+}
+
+void sendEvent (int eventType) {
+ sendEvent (eventType, null, true);
+}
+
+void sendEvent (int eventType, Event event) {
+ sendEvent (eventType, event, true);
+}
+
+void sendEvent (int eventType, Event event, boolean send) {
+ if (eventTable == null && !display.filters (eventType)) {
+ return;
+ }
+ if (event == null) event = new Event ();
+ event.type = eventType;
+ event.display = display;
+ event.widget = this;
+ if (event.time == 0) {
+ event.time = display.getLastEventTime ();
+ }
+ if (send) {
+ sendEvent (event);
+ } else {
+ display.postEvent (event);
+ }
+}
+
+boolean sendKeyEvent (int type, int e, boolean textInput) {
+ if (textInput) {
+ int text = OS.TextCompositionEventArgs_Text(e);
+ if (OS.String_Length(text) == 0) {
+ OS.GCHandle_Free(text);
+ text = OS.TextCompositionEventArgs_SystemText(e);
+ if (OS.String_Length(text) == 0) {
+ OS.GCHandle_Free(text);
+ text = OS.TextCompositionEventArgs_ControlText(e);
+ if (OS.String_Length(text) == 0) {
+ return false;
+ }
+ }
+ }
+ int chars = OS.String_ToCharArray(text);
+ char[] buffer = new char[OS.String_Length(text)];
+ OS.memmove(buffer, chars, buffer.length * 2);
+ OS.GCHandle_Free(chars);
+ OS.GCHandle_Free(text);
+ for (int i = 0; i < buffer.length; i++) {
+ Event event = new Event ();
+ if (buffer.length == 1) {
+ event.keyCode = Display.translateKey(display.lastKey);
+ }
+ event.character = buffer[i];
+ //hack for dead key
+ if (display.deadChar) {
+ event.character = display.lastChar;
+ display.deadChar = false;
+ }
+ setInputState(event, type, 0, 0);
+ sendEvent (type, event);
+ if (isDisposed ()) return false;
+ }
+ return true;
+ } else {
+ Event event = new Event ();
+ if (!setKeyState (event, type, e)) return true;
+ sendEvent (type, event);
+ if (isDisposed ()) return false;
+ return event.doit;
+ }
+}
+
+boolean sendMouseEvent (int type, int e, boolean send) {
+ if (!hooks (type) && !filters (type)) return true;
+ Event event = new Event ();
+ if (type == SWT.MouseDown || type == SWT.MouseUp) {
+ event.button = OS.MouseButtonEventArgs_ChangedButton (e) + 1;
+ event.count = OS.MouseButtonEventArgs_ClickCount (e);
+ }
+ if (type == SWT.MouseWheel) {
+ int lines = OS.SystemParameters_WheelScrollLines ();
+ int delta = OS.MouseWheelEventArgs_Delta (e);
+ if (lines == -1) {
+ event.detail = SWT.SCROLL_PAGE;
+ event.count = delta / 120;
+ } else {
+ event.detail = SWT.SCROLL_LINE;
+ event.count = delta * lines / 120;
+ }
+ }
+ int topHandle = topHandle ();
+ int point = OS.MouseEventArgs_GetPosition (e, topHandle);
+ event.x = (int) OS.Point_X (point);
+ event.y = (int) OS.Point_Y (point);
+ OS.GCHandle_Free (point);
+ setInputState (event, type, e, 0);
+ Event doubleClick = null;
+ if (type == SWT.MouseDown && (event.count & 1) == 0) {
+ doubleClick = new Event();
+ doubleClick.button = event.button;
+ doubleClick.x = event.x;
+ doubleClick.y = event.y;
+ doubleClick.count = event.count;
+ doubleClick.stateMask = event.stateMask;
+ }
+ if (send) {
+ sendEvent (type, event);
+ if (isDisposed ()) return false;
+ } else {
+ postEvent (type, event);
+ }
+ if (doubleClick != null) {
+ if (send) {
+ sendEvent (SWT.MouseDoubleClick, doubleClick);
+ if (isDisposed ()) return false;
+ } else {
+ postEvent (SWT.MouseDoubleClick, doubleClick);
+ }
+ }
+ return event.doit;
+}
+
+/**
+ * Sets the application defined widget data associated
+ * with the receiver to be the argument. The <em>widget
+ * data</em> is a single, unnamed field that is stored
+ * with every widget.
+ * <p>
+ * Applications may put arbitrary objects in this field. If
+ * the object stored in the widget data needs to be notified
+ * when the widget is disposed of, it is the application's
+ * responsibility to hook the Dispose event on the widget and
+ * do so.
+ * </p>
+ *
+ * @param data the widget data
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - when the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - when called from the wrong thread</li>
+ * </ul>
+ *
+ * @see #getData()
+ */
+public void setData (Object data) {
+ checkWidget();
+ if ((state & KEYED_DATA) != 0) {
+ ((Object []) this.data) [0] = data;
+ } else {
+ this.data = data;
+ }
+}
+
+/**
+ * Sets the application defined property of the receiver
+ * with the specified name to the given value.
+ * <p>
+ * Applications may associate arbitrary objects with the
+ * receiver in this fashion. If the objects stored in the
+ * properties need to be notified when the widget is disposed
+ * of, it is the application's responsibility to hook the
+ * Dispose event on the widget and do so.
+ * </p>
+ *
+ * @param key the name of the property
+ * @param value the new value for the property
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the key is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #getData(String)
+ */
+public void setData (String key, Object value) {
+ checkWidget();
+ if (key == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int index = 1;
+ Object [] table = null;
+ if ((state & KEYED_DATA) != 0) {
+ table = (Object []) data;
+ while (index < table.length) {
+ if (key.equals (table [index])) break;
+ index += 2;
+ }
+ }
+ if (value != null) {
+ if ((state & KEYED_DATA) != 0) {
+ if (index == table.length) {
+ Object [] newTable = new Object [table.length + 2];
+ System.arraycopy (table, 0, newTable, 0, table.length);
+ data = table = newTable;
+ }
+ } else {
+ table = new Object [3];
+ table [0] = data;
+ data = table;
+ state |= KEYED_DATA;
+ }
+ table [index] = key;
+ table [index + 1] = value;
+ } else {
+ if ((state & KEYED_DATA) != 0) {
+ if (index != table.length) {
+ int length = table.length - 2;
+ if (length == 1) {
+ data = table [0];
+ state &= ~KEYED_DATA;
+ } else {
+ Object [] newTable = new Object [length];
+ System.arraycopy (table, 0, newTable, 0, index);
+ System.arraycopy (table, index + 2, newTable, index, length - index);
+ data = newTable;
+ }
+ }
+ }
+ }
+}
+
+boolean sendFocusEvent (int type) {
+ sendEvent (type);
+ // widget could be disposed at this point
+ return true;
+}
+
+boolean setInputState (Event event, int type, int mouseEvent, int keyEvent) {
+ int modifiers;
+ if (keyEvent != 0) {
+ int keyboardDevice = OS.KeyboardEventArgs_KeyboardDevice(keyEvent);
+ modifiers = OS.KeyboardDevice_Modifiers(keyboardDevice);
+ OS.GCHandle_Free(keyboardDevice);
+ } else {
+ modifiers = OS.Keyboard_Modifiers();
+ }
+ if ((modifiers & OS.ModifierKeys_Alt) != 0) event.stateMask |= SWT.ALT;
+ if ((modifiers & OS.ModifierKeys_Shift) != 0) event.stateMask |= SWT.SHIFT;
+ if ((modifiers & OS.ModifierKeys_Control) != 0) event.stateMask |= SWT.CONTROL;
+ if (mouseEvent != 0) {
+ if (OS.MouseEventArgs_LeftButton(mouseEvent) == OS.MouseButtonState_Pressed) event.stateMask |= SWT.BUTTON1;
+ if (OS.MouseEventArgs_MiddleButton(mouseEvent) == OS.MouseButtonState_Pressed) event.stateMask |= SWT.BUTTON2;
+ if (OS.MouseEventArgs_RightButton(mouseEvent) == OS.MouseButtonState_Pressed) event.stateMask |= SWT.BUTTON3;
+ if (OS.MouseEventArgs_XButton1(mouseEvent) == OS.MouseButtonState_Pressed) event.stateMask |= SWT.BUTTON4;
+ if (OS.MouseEventArgs_XButton2(mouseEvent) == OS.MouseButtonState_Pressed) event.stateMask |= SWT.BUTTON5;
+ } else {
+ if (OS.Mouse_LeftButton() == OS.MouseButtonState_Pressed) event.stateMask |= SWT.BUTTON1;
+ if (OS.Mouse_MiddleButton() == OS.MouseButtonState_Pressed) event.stateMask |= SWT.BUTTON2;
+ if (OS.Mouse_RightButton() == OS.MouseButtonState_Pressed) event.stateMask |= SWT.BUTTON3;
+ if (OS.Mouse_XButton1() == OS.MouseButtonState_Pressed) event.stateMask |= SWT.BUTTON4;
+ if (OS.Mouse_XButton2() == OS.MouseButtonState_Pressed) event.stateMask |= SWT.BUTTON5;
+ }
+ switch (type) {
+ case SWT.MouseDown:
+ case SWT.MouseDoubleClick:
+ if (event.button == 1) event.stateMask &= ~SWT.BUTTON1;
+ if (event.button == 2) event.stateMask &= ~SWT.BUTTON2;
+ if (event.button == 3) event.stateMask &= ~SWT.BUTTON3;
+ if (event.button == 4) event.stateMask &= ~SWT.BUTTON4;
+ if (event.button == 5) event.stateMask &= ~SWT.BUTTON5;
+ break;
+ case SWT.MouseUp:
+ if (event.button == 1) event.stateMask |= SWT.BUTTON1;
+ if (event.button == 2) event.stateMask |= SWT.BUTTON2;
+ if (event.button == 3) event.stateMask |= SWT.BUTTON3;
+ if (event.button == 4) event.stateMask |= SWT.BUTTON4;
+ if (event.button == 5) event.stateMask |= SWT.BUTTON5;
+ break;
+ case SWT.KeyDown:
+ case SWT.Traverse:
+ if (event.keyCode == SWT.ALT) event.stateMask &= ~SWT.ALT;
+ if (event.keyCode == SWT.SHIFT) event.stateMask &= ~SWT.SHIFT;
+ if (event.keyCode == SWT.CONTROL) event.stateMask &= ~SWT.CONTROL;
+ break;
+ case SWT.KeyUp:
+ if (event.keyCode == SWT.ALT) event.stateMask |= SWT.ALT;
+ if (event.keyCode == SWT.SHIFT) event.stateMask |= SWT.SHIFT;
+ if (event.keyCode == SWT.CONTROL) event.stateMask |= SWT.CONTROL;
+ break;
+ }
+ return true;
+}
+
+boolean setKeyState (Event event, int type, int e) {
+ int key = display.lastKey = OS.KeyEventArgs_Key(e);
+ boolean repeat = OS.KeyEventArgs_IsRepeat(e);
+ switch (key) {
+ case OS.Key_ImeProcessed:
+ return false;
+ case OS.Key_LeftAlt:
+ case OS.Key_RightAlt:
+ case OS.Key_LeftCtrl:
+ case OS.Key_LeftShift:
+ case OS.Key_RightCtrl:
+ case OS.Key_RightShift:
+ if (repeat) return false;
+ break;
+ case OS.Key_System:
+ key = OS.KeyEventArgs_SystemKey(e);
+ switch (key) {
+ case OS.Key_LeftAlt:
+ case OS.Key_RightAlt:
+ if (repeat) return false;
+ }
+ }
+ boolean textual = false;
+ int vKey = OS.KeyInterop_VirtualKeyFromKey (key);
+ int mapKey = OS.MapVirtualKeyW (vKey, 2);
+ if ((mapKey & 0x80000000) != 0) {
+ display.deadChar = true;
+ return false;
+ }
+ char [] result = new char [1];
+ byte [] keyboard = new byte [256];
+ OS.GetKeyboardState (keyboard);
+ textual = OS.ToUnicode (vKey, 0, keyboard, result, 1, 0) == 1;
+ if (textual && type == SWT.KeyDown) {
+ if (display.deadChar) display.lastChar = result [0];
+ //TODO problem: in german, dead key + non-combing key
+ // example: '^' + 'p' fails.
+ return false;
+ }
+ event.keyCode = Display.translateKey (key);
+ if (type == SWT.KeyUp) event.character = result [0];
+ return setInputState (event, type, 0, e);
+}
+
+boolean showMenu (int x, int y) {
+ Event event = new Event ();
+ event.x = x;
+ event.y = y;
+ sendEvent (SWT.MenuDetect, event);
+ if (!event.doit) return true;
+ Menu menu = getMenu ();
+ if (menu != null && !menu.isDisposed ()) {
+ if (x != event.x || y != event.y) {
+ menu.setLocation (event.x, event.y);
+ }
+ menu.setVisible (true);
+ return true;
+ }
+ return false;
+}
+
+int topHandle () {
+ return handle;
+}
+
+/**
+ * Returns a string containing a concise, human-readable
+ * description of the receiver.
+ *
+ * @return a string representation of the receiver
+ */
+public String toString () {
+ String string = "*Disposed*"; //$NON-NLS-1$
+ if (!isDisposed ()) {
+ string = "*Wrong Thread*"; //$NON-NLS-1$
+ if (isValidThread ()) string = getNameText ();
+ }
+ return getName () + " {" + string + "}"; //$NON-NLS-1$ //$NON-NLS-2$
+}
+
+}