summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Campo <ccampo>2010-08-09 07:57:10 +0000
committerChristian Campo <ccampo>2010-08-09 07:57:10 +0000
commitc64b166eb91342ebed0e339dc0c596666896fdd4 (patch)
tree7632b0fe94ed73a77a3459d37992919a42b2a8a7
parent2f47908a071ffd38fcd4f9b9f8edf751975f35df (diff)
downloadeclipse.platform.swt-c64b166eb91342ebed0e339dc0c596666896fdd4.tar.gz
eclipse.platform.swt-c64b166eb91342ebed0e339dc0c596666896fdd4.tar.xz
eclipse.platform.swt-c64b166eb91342ebed0e339dc0c596666896fdd4.zip
initial checkin of Qt Source code as approved in https://dev.eclipse.org/ipzilla/show_bug.cgi?id=4301
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Browser/qt/org/eclipse/swt/browser/QtWebkit.java201
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/ByteArrayTransfer.java201
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/Clipboard.java410
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/DragSource.java593
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/DropTarget.java638
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/FileTransfer.java145
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/HTMLTransfer.java76
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/ImageTransfer.java76
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/RTFTransfer.java79
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TableDragSourceEffect.java43
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TableDropTargetEffect.java55
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TextTransfer.java106
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/Transfer.java163
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TransferData.java87
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TreeDragSourceEffect.java42
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TreeDropTargetEffect.java129
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/URLTransfer.java75
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Color.java364
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Cursor.java445
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Device.java920
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/DeviceData.java23
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Font.java379
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/FontData.java722
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/FontMetrics.java165
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/GC.java3555
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/GCData.java53
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Image.java978
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Region.java776
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/DragNDropListener.java28
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/FontConverter.java107
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/KeyUtil.java120
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/QtSWTConverter.java110
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/QtSupplementaryFontData.java28
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/SWQT.java51
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/SignalConnector.java74
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/StylableScrollArea.java60
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/ToString.java99
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Button.java801
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Canvas.java355
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Caret.java590
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ColorDialog.java164
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Combo.java1398
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Composite.java1301
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Control.java4225
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/DateTime.java806
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Decorations.java1218
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/DirectoryDialog.java202
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Display.java3200
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/FileDialog.java443
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/FontDialog.java246
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Group.java293
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Label.java456
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Link.java552
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/List.java1380
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Menu.java1423
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/MenuItem.java1011
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/MessageBox.java312
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ProgressBar.java318
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Sash.java387
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Scale.java494
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ScrollBar.java876
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Scrollable.java430
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Shell.java1490
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Slider.java632
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Spinner.java948
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TabFolder.java755
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TabItem.java389
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Table.java2561
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TableColumn.java664
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TableItem.java1441
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Text.java1875
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ToolBar.java530
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ToolItem.java981
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ToolTip.java512
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Tracker.java859
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TrayItem.java536
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Tree.java1913
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TreeColumn.java714
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TreeItem.java1573
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Widget.java1358
80 files changed, 54788 insertions, 0 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Browser/qt/org/eclipse/swt/browser/QtWebkit.java b/bundles/org.eclipse.swt/Eclipse SWT Browser/qt/org/eclipse/swt/browser/QtWebkit.java
new file mode 100644
index 0000000000..b0b4cc759d
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Browser/qt/org/eclipse/swt/browser/QtWebkit.java
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 compeople AG 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:
+ * compeople AG - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.browser;
+
+import com.trolltech.qt.core.QUrl;
+import com.trolltech.qt.webkit.QWebView;
+
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *
+ */
+public class QtWebkit extends WebBrowser {
+
+ private QWebView webView = null;
+ private int style;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.swt.browser.WebBrowser#create(org.eclipse.swt.widgets.Composite
+ * , int)
+ */
+ @Override
+ public void create(Composite parent, int style) {
+ this.style = style;
+ webView = new QWebView(parent.getQWidget());
+ webView.loadProgress.connect(this, "loadProgress(int)"); //$NON-NLS-1$
+ webView.loadFinished.connect(this, "loadFinished(boolean)"); //$NON-NLS-1$
+ webView.titleChanged.connect(this, "titleChanged(java.lang.String)"); //$NON-NLS-1$
+
+ }
+
+ public void loadProgress(int progress) {
+ ProgressEvent progressEvent = new ProgressEvent(browser);
+ progressEvent.display = browser.getDisplay();
+ progressEvent.widget = browser;
+ progressEvent.current = progress;
+ for (int i = 0; i < progressListeners.length; i++) {
+ progressListeners[i].changed(progressEvent);
+ }
+ }
+
+ public void loadFinished(boolean OK) {
+ ProgressEvent progressEvent = new ProgressEvent(browser);
+ progressEvent.display = browser.getDisplay();
+ progressEvent.widget = browser;
+ for (int i = 0; i < progressListeners.length; i++) {
+ progressListeners[i].completed(progressEvent);
+ }
+ }
+
+ public void titleChanged(String title) {
+ TitleEvent newEvent = new TitleEvent(browser);
+ newEvent.display = browser.getDisplay();
+ newEvent.widget = browser;
+ newEvent.title = title;
+ for (int i = 0; i < titleListeners.length; i++) {
+ titleListeners[i].changed(newEvent);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.browser.WebBrowser#execute(java.lang.String)
+ */
+ @Override
+ public boolean execute(String script) {
+ webView.page().mainFrame().evaluateJavaScript(script);
+ webView.repaint(); // TODO seems to help for SWT Snippet161 but is a repaint really necessary ?
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.browser.WebBrowser#back()
+ */
+ @Override
+ public boolean back() {
+ webView.back();
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.browser.WebBrowser#forward()
+ */
+ @Override
+ public boolean forward() {
+ webView.forward();
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.browser.WebBrowser#getBrowserType()
+ */
+ @Override
+ public String getBrowserType() {
+ // TODO Auto-generated method stub
+ return "qtWebkit";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.browser.WebBrowser#getText()
+ */
+ @Override
+ public String getText() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.browser.WebBrowser#getUrl()
+ */
+ @Override
+ public String getUrl() {
+ return webView.url().toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.browser.WebBrowser#isBackEnabled()
+ */
+ @Override
+ public boolean isBackEnabled() {
+ return webView.history().canGoBack();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.browser.WebBrowser#isForwardEnabled()
+ */
+ @Override
+ public boolean isForwardEnabled() {
+ return webView.history().canGoForward();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.browser.WebBrowser#refresh()
+ */
+ @Override
+ public void refresh() {
+ webView.reload();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.browser.WebBrowser#setText(java.lang.String)
+ */
+ @Override
+ public boolean setText(String html) {
+ webView.setHtml(html);
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.browser.WebBrowser#setUrl(java.lang.String)
+ */
+ @Override
+ public boolean setUrl(String url) {
+ webView.load(new QUrl(url));
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.browser.WebBrowser#stop()
+ */
+ @Override
+ public void stop() {
+ webView.stop();
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/ByteArrayTransfer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/ByteArrayTransfer.java
new file mode 100644
index 0000000000..e46c883f8b
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/ByteArrayTransfer.java
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.dnd;
+
+/**
+ * The class <code>ByteArrayTransfer</code> provides a platform specific
+ * mechanism for converting a java <code>byte[]</code> to a platform specific
+ * representation of the byte array and vice versa.
+ *
+ * <p>
+ * <code>ByteArrayTransfer</code> is never used directly but is sub-classed by
+ * transfer agents that convert between data in a java format such as a
+ * <code>String</code> and a platform specific byte array.
+ *
+ * <p>
+ * If the data you are converting <b>does not</b> map to a <code>byte[]</code>,
+ * you should sub-class <code>Transfer</code> directly and do your own mapping
+ * to a platform data type.
+ * </p>
+ *
+ * <p>
+ * The following snippet shows a subclass of ByteArrayTransfer that transfers
+ * data defined by the class <code>MyType</code>.
+ * </p>
+ *
+ * <pre>
+ * <code>
+ * public class MyType {
+ * public String fileName;
+ * public long fileLength;
+ * public long lastModified;
+ * }
+ * </code>
+ * </pre>
+ *
+ * <pre>
+ * <code>
+ * public class MyTypeTransfer extends ByteArrayTransfer {
+ *
+ * private static final String MYTYPENAME = "my_type_name";
+ * private static final int MYTYPEID = registerType(MYTYPENAME);
+ * private static MyTypeTransfer _instance = new MyTypeTransfer();
+ *
+ * private MyTypeTransfer() {}
+ *
+ * public static MyTypeTransfer getInstance () {
+ * return _instance;
+ * }
+ * public void javaToNative (Object object, TransferData transferData) {
+ * if (object == null || !(object instanceof MyType[])) return;
+ *
+ * if (isSupportedType(transferData)) {
+ * MyType[] myTypes = (MyType[]) object;
+ * try {
+ * // write data to a byte array and then ask super to convert to pMedium
+ * ByteArrayOutputStream out = new ByteArrayOutputStream();
+ * DataOutputStream writeOut = new DataOutputStream(out);
+ * for (int i = 0, length = myTypes.length; i &lt; length; i++){
+ * byte[] buffer = myTypes[i].fileName.getBytes();
+ * writeOut.writeInt(buffer.length);
+ * writeOut.write(buffer);
+ * writeOut.writeLong(myTypes[i].fileLength);
+ * writeOut.writeLong(myTypes[i].lastModified);
+ * }
+ * byte[] buffer = out.toByteArray();
+ * writeOut.close();
+ *
+ * super.javaToNative(buffer, transferData);
+ *
+ * } catch (IOException e) {
+ * }
+ * }
+ * }
+ * public Object nativeToJava(TransferData transferData){
+ *
+ * if (isSupportedType(transferData)) {
+ *
+ * byte[] buffer = (byte[])super.nativeToJava(transferData);
+ * if (buffer == null) return null;
+ *
+ * MyType[] myData = new MyType[0];
+ * try {
+ * ByteArrayInputStream in = new ByteArrayInputStream(buffer);
+ * DataInputStream readIn = new DataInputStream(in);
+ * while(readIn.available() > 20) {
+ * MyType datum = new MyType();
+ * int size = readIn.readInt();
+ * byte[] name = new byte[size];
+ * readIn.read(name);
+ * datum.fileName = new String(name);
+ * datum.fileLength = readIn.readLong();
+ * datum.lastModified = readIn.readLong();
+ * MyType[] newMyData = new MyType[myData.length + 1];
+ * System.arraycopy(myData, 0, newMyData, 0, myData.length);
+ * newMyData[myData.length] = datum;
+ * myData = newMyData;
+ * }
+ * readIn.close();
+ * } catch (IOException ex) {
+ * return null;
+ * }
+ * return myData;
+ * }
+ *
+ * return null;
+ * }
+ * protected String[] getTypeNames(){
+ * return new String[]{MYTYPENAME};
+ * }
+ * protected int[] getTypeIds(){
+ * return new int[] {MYTYPEID};
+ * }
+ * }
+ * </code>
+ * </pre>
+ *
+ * @see Transfer
+ */
+public abstract class ByteArrayTransfer extends Transfer {
+
+ @Override
+ public TransferData[] getSupportedTypes() {
+ int[] types = getTypeIds();
+ String[] names = getTypeNames();
+ TransferData[] data = new TransferData[types.length];
+ for (int i = 0; i < types.length; i++) {
+ data[i] = new TransferData();
+ data[i].type = types[i];
+ data[i].format = names[i];
+ }
+ return data;
+ }
+
+ @Override
+ public boolean isSupportedType(TransferData transferData) {
+ if (transferData == null) {
+ return false;
+ }
+ int[] types = getTypeIds();
+ for (int i = 0; i < types.length; i++) {
+ if (transferData.type == types[i]) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * This implementation of <code>javaToNative</code> converts a java
+ * <code>byte[]</code> to a platform specific representation.
+ *
+ * @param object
+ * a java <code>byte[]</code> containing the data to be converted
+ * @param transferData
+ * an empty <code>TransferData</code> object that will be filled
+ * in on return with the platform specific format of the data
+ *
+ * @see Transfer#nativeToJava
+ */
+ @Override
+ protected void javaToNative(Object object, TransferData transferData) {
+ if (!checkByteArray(object) || !isSupportedType(transferData)) {
+ DND.error(DND.ERROR_INVALID_DATA);
+ }
+ transferData.data = object;
+ }
+
+ /**
+ * This implementation of <code>nativeToJava</code> converts a platform
+ * specific representation of a byte array to a java <code>byte[]</code>.
+ *
+ * @param transferData
+ * the platform specific representation of the data to be
+ * converted
+ * @return a java <code>byte[]</code> containing the converted data if the
+ * conversion was successful; otherwise null
+ *
+ * @see Transfer#javaToNative
+ */
+ @Override
+ protected Object nativeToJava(TransferData transferData) {
+ if (!checkByteArray(transferData.data) || !isSupportedType(transferData)) {
+ return null;
+ }
+ return transferData.data;
+ }
+
+ protected boolean checkByteArray(Object object) {
+ return object != null && object instanceof byte[] && ((byte[]) object).length > 0;
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/Clipboard.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/Clipboard.java
new file mode 100644
index 0000000000..981acde037
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/Clipboard.java
@@ -0,0 +1,410 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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.dnd;
+
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * The <code>Clipboard</code> provides a mechanism for transferring data from one
+ * application to another or within an application.
+ *
+ * <p>IMPORTANT: This class is <em>not</em> intended to be subclassed.</p>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#clipboard">Clipboard snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ClipboardExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class Clipboard {
+
+ private Display display;
+
+/**
+ * Constructs a new instance of this class. Creating an instance of a Clipboard
+ * may cause system resources to be allocated depending on the platform. It is therefore
+ * mandatory that the Clipboard instance be disposed when no longer required.
+ *
+ * @param display the display on which to allocate the clipboard
+ *
+ * @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 Clipboard#dispose
+ * @see Clipboard#checkSubclass
+ */
+public Clipboard(Display display) {
+ checkSubclass ();
+ if (display == null) {
+ display = Display.getCurrent();
+ if (display == null) {
+ display = Display.getDefault();
+ }
+ }
+ if (display.getThread() != Thread.currentThread()) {
+ DND.error(SWT.ERROR_THREAD_INVALID_ACCESS);
+ }
+ this.display = display;
+}
+
+/**
+ * Checks that this class can be subclassed.
+ * <p>
+ * The SWT class library is intended to be subclassed
+ * only at specific, controlled points. 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 () {
+ String name = getClass().getName ();
+ String validName = Clipboard.class.getName();
+ if (!validName.equals(name)) {
+ DND.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) DND.error (SWT.ERROR_WIDGET_DISPOSED);
+ if (display.getThread() != Thread.currentThread ()) DND.error (SWT.ERROR_THREAD_INVALID_ACCESS);
+ if (display.isDisposed()) DND.error(SWT.ERROR_WIDGET_DISPOSED);
+}
+
+/**
+ * Disposes of the operating system resources associated with the clipboard.
+ * The data will still be available on the system clipboard after the dispose
+ * method is called.
+ *
+ * <p>NOTE: On some platforms the data will not be available once the application
+ * has exited or the display has been disposed.</p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * </ul>
+ */
+public void dispose () {
+ if (isDisposed()) return;
+ if (display.getThread() != Thread.currentThread()) DND.error(SWT.ERROR_THREAD_INVALID_ACCESS);
+ display = null;
+}
+
+/**
+ * Retrieve the data of the specified type currently available on the system
+ * clipboard. Refer to the specific subclass of <code>Transfer</code> to
+ * determine the type of object returned.
+ *
+ * <p>The following snippet shows text and RTF text being retrieved from the
+ * clipboard:</p>
+ *
+ * <code><pre>
+ * Clipboard clipboard = new Clipboard(display);
+ * TextTransfer textTransfer = TextTransfer.getInstance();
+ * String textData = (String)clipboard.getContents(textTransfer);
+ * if (textData != null) System.out.println("Text is "+textData);
+ * RTFTransfer rtfTransfer = RTFTransfer.getInstance();
+ * String rtfData = (String)clipboard.getContents(rtfTransfer);
+ * if (rtfData != null) System.out.println("RTF Text is "+rtfData);
+ * clipboard.dispose();
+ * </code></pre>
+ *
+ * @param transfer the transfer agent for the type of data being requested
+ * @return the data obtained from the clipboard or null if no data of this type is available
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - 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 transfer is null</li>
+ * </ul>
+ *
+ * @see Transfer
+ */
+public Object getContents(Transfer transfer) {
+ return getContents(transfer, DND.CLIPBOARD);
+}
+
+/**
+ * Retrieve the data of the specified type currently available on the specified
+ * clipboard. Refer to the specific subclass of <code>Transfer</code> to
+ * determine the type of object returned.
+ *
+ * <p>The following snippet shows text and RTF text being retrieved from the
+ * clipboard:</p>
+ *
+ * <code><pre>
+ * Clipboard clipboard = new Clipboard(display);
+ * TextTransfer textTransfer = TextTransfer.getInstance();
+ * String textData = (String)clipboard.getContents(textTransfer);
+ * if (textData != null) System.out.println("Text is "+textData);
+ * RTFTransfer rtfTransfer = RTFTransfer.getInstance();
+ * String rtfData = (String)clipboard.getContents(rtfTransfer, DND.CLIPBOARD);
+ * if (rtfData != null) System.out.println("RTF Text is "+rtfData);
+ * clipboard.dispose();
+ * </code></pre>
+ *
+ * <p>The clipboards value is either one of the clipboard constants defined in
+ * class <code>DND</code>, 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>DND</code> clipboard constants.</p>
+ *
+ * @param transfer the transfer agent for the type of data being requested
+ * @param clipboards on which to look for data
+ *
+ * @return the data obtained from the clipboard or null if no data of this type is available
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - 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 transfer is null</li>
+ * </ul>
+ *
+ * @see Transfer
+ * @see DND#CLIPBOARD
+ * @see DND#SELECTION_CLIPBOARD
+ *
+ * @since 3.1
+ */
+public Object getContents(Transfer transfer, int clipboards) {
+ checkWidget();
+ if (transfer == null) DND.error(SWT.ERROR_NULL_ARGUMENT);
+ if (!(transfer instanceof TextTransfer)) return null;
+ return display.getData("TextTransfer"); //$NON-NLS-1$
+}
+
+/**
+ * Returns <code>true</code> if the clipboard has been disposed,
+ * and <code>false</code> otherwise.
+ * <p>
+ * This method gets the dispose state for the clipboard.
+ * When a clipboard has been disposed, it is an error to
+ * invoke any other method using the clipboard.
+ * </p>
+ *
+ * @return <code>true</code> when the widget is disposed and <code>false</code> otherwise
+ *
+ * @since 3.0
+ */
+public boolean isDisposed () {
+ return (display == null);
+}
+
+/**
+ * Place data of the specified type on the system clipboard. More than one type
+ * of data can be placed on the system clipboard at the same time. Setting the
+ * data clears any previous data from the system clipboard, regardless of type.
+ *
+ * <p>NOTE: On some platforms, the data is immediately copied to the system
+ * clipboard but on other platforms it is provided upon request. As a result,
+ * if the application modifies the data object it has set on the clipboard, that
+ * modification may or may not be available when the data is subsequently
+ * requested.</p>
+ *
+ * <p>The following snippet shows text and RTF text being set on the copy/paste
+ * clipboard:
+ * </p>
+ *
+ * <code><pre>
+ * Clipboard clipboard = new Clipboard(display);
+ * String textData = "Hello World";
+ * String rtfData = "{\\rtf1\\b\\i Hello World}";
+ * TextTransfer textTransfer = TextTransfer.getInstance();
+ * RTFTransfer rtfTransfer = RTFTransfer.getInstance();
+ * Transfer[] transfers = new Transfer[]{textTransfer, rtfTransfer};
+ * Object[] data = new Object[]{textData, rtfData};
+ * clipboard.setContents(data, transfers);
+ * clipboard.dispose();
+ * </code></pre>
+ *
+ * @param data the data to be set in the clipboard
+ * @param dataTypes the transfer agents that will convert the data to its
+ * platform specific format; each entry in the data array must have a
+ * corresponding dataType
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if data is null or datatypes is null
+ * or the length of data is not the same as the length of dataTypes</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>
+ * @exception SWTError <ul>
+ * <li>ERROR_CANNOT_SET_CLIPBOARD - if the clipboard is locked or otherwise unavailable</li>
+ * </ul>
+ *
+ * <p>NOTE: ERROR_CANNOT_SET_CLIPBOARD should be an SWTException, since it is a
+ * recoverable error, but can not be changed due to backward compatibility.</p>
+ */
+public void setContents(Object[] data, Transfer[] dataTypes) {
+ setContents(data, dataTypes, DND.CLIPBOARD);
+}
+
+/**
+ * Place data of the specified type on the specified clipboard. More than one
+ * type of data can be placed on the specified clipboard at the same time.
+ * Setting the data clears any previous data from the specified
+ * clipboard, regardless of type.
+ *
+ * <p>NOTE: On some platforms, the data is immediately copied to the specified
+ * clipboard but on other platforms it is provided upon request. As a result,
+ * if the application modifies the data object it has set on the clipboard, that
+ * modification may or may not be available when the data is subsequently
+ * requested.</p>
+ *
+ * <p>The clipboards value is either one of the clipboard constants defined in
+ * class <code>DND</code>, 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>DND</code> clipboard constants.</p>
+ *
+ * <p>The following snippet shows text and RTF text being set on the copy/paste
+ * clipboard:
+ * </p>
+ *
+ * <code><pre>
+ * Clipboard clipboard = new Clipboard(display);
+ * String textData = "Hello World";
+ * String rtfData = "{\\rtf1\\b\\i Hello World}";
+ * TextTransfer textTransfer = TextTransfer.getInstance();
+ * RTFTransfer rtfTransfer = RTFTransfer.getInstance();
+ * Transfer[] transfers = new Transfer[]{textTransfer, rtfTransfer};
+ * Object[] data = new Object[]{textData, rtfData};
+ * clipboard.setContents(data, transfers, DND.CLIPBOARD);
+ * clipboard.dispose();
+ * </code></pre>
+ *
+ * @param data the data to be set in the clipboard
+ * @param dataTypes the transfer agents that will convert the data to its
+ * platform specific format; each entry in the data array must have a
+ * corresponding dataType
+ * @param clipboards on which to set the data
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if data is null or datatypes is null
+ * or the length of data is not the same as the length of dataTypes</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>
+ * @exception SWTError <ul>
+ * <li>ERROR_CANNOT_SET_CLIPBOARD - if the clipboard is locked or otherwise unavailable</li>
+ * </ul>
+ *
+ * <p>NOTE: ERROR_CANNOT_SET_CLIPBOARD should be an SWTException, since it is a
+ * recoverable error, but can not be changed due to backward compatibility.</p>
+ *
+ * @see DND#CLIPBOARD
+ * @see DND#SELECTION_CLIPBOARD
+ *
+ * @since 3.1
+ */
+public void setContents(Object[] data, Transfer[] dataTypes, int clipboards) {
+ checkWidget();
+ if (data == null || dataTypes == null || data.length != dataTypes.length) {
+ DND.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+
+ for (int i = 0; i < dataTypes.length; i++) {
+ if (dataTypes[i] instanceof TextTransfer && data[i] instanceof String){
+ display.setData("TextTransfer", data[i]); //$NON-NLS-1$
+ return;
+ }
+ }
+}
+
+/**
+ * Returns an array of the data types currently available on the system
+ * clipboard. Use with Transfer.isSupportedType.
+ *
+ * @return array of data types currently available on the system clipboard
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - 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 Transfer#isSupportedType
+ *
+ * @since 3.0
+ */
+public TransferData[] getAvailableTypes() {
+ checkWidget();
+ return new TransferData[0];
+}
+
+/**
+ * Returns a platform specific list of the data types currently available on the
+ * system clipboard.
+ *
+ * <p>Note: <code>getAvailableTypeNames</code> is a utility for writing a Transfer
+ * sub-class. It should NOT be used within an application because it provides
+ * platform specific information.</p>
+ *
+ * @return a platform specific list of the data types currently available on the
+ * system clipboard
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if 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[] getAvailableTypeNames() {
+ checkWidget();
+ return new String[0];
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/DragSource.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/DragSource.java
new file mode 100644
index 0000000000..fffc83ce22
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/DragSource.java
@@ -0,0 +1,593 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.dnd;
+
+import com.trolltech.qt.core.QByteArray;
+import com.trolltech.qt.core.QMimeData;
+import com.trolltech.qt.core.Qt.DropAction;
+import com.trolltech.qt.core.Qt.DropActions;
+import com.trolltech.qt.gui.QDrag;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTError;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ *
+ * <code>DragSource</code> defines the source object for a drag and drop
+ * transfer.
+ *
+ * <p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ *
+ * <p>
+ * A drag source is the object which originates a drag and drop operation. For
+ * the specified widget, it defines the type of data that is available for
+ * dragging and the set of operations that can be performed on that data. The
+ * operations can be any bit-wise combination of DND.MOVE, DND.COPY or DND.LINK.
+ * The type of data that can be transferred is specified by subclasses of
+ * Transfer such as TextTransfer or FileTransfer. The type of data transferred
+ * can be a predefined system type or it can be a type defined by the
+ * application. For instructions on how to define your own transfer type, refer
+ * to <code>ByteArrayTransfer</code>.
+ * </p>
+ *
+ * <p>
+ * You may have several DragSources in an application but you can only have one
+ * DragSource per Control. Data dragged from this DragSource can be dropped on a
+ * site within this application or it can be dropped on another application such
+ * as an external Text editor.
+ * </p>
+ *
+ * <p>
+ * The application supplies the content of the data being transferred by
+ * implementing the <code>DragSourceListener</code> and associating it with the
+ * DragSource via DragSource#addDragListener.
+ * </p>
+ *
+ * <p>
+ * When a successful move operation occurs, the application is required to take
+ * the appropriate action to remove the data from its display and remove any
+ * associated operating system resources or internal references. Typically in a
+ * move operation, the drop target makes a copy of the data and the drag source
+ * deletes the original. However, sometimes copying the data can take a long
+ * time (such as copying a large file). Therefore, on some platforms, the drop
+ * target may actually move the data in the operating system rather than make a
+ * copy. This is usually only done in file transfers. In this case, the drag
+ * source is informed in the DragEnd event that a DROP_TARGET_MOVE was
+ * performed. It is the responsibility of the drag source at this point to clean
+ * up its displayed information. No action needs to be taken on the operating
+ * system resources.
+ * </p>
+ *
+ * <p>
+ * The following example shows a Label widget that allows text to be dragged
+ * from it.
+ * </p>
+ *
+ * <code><pre>
+ * // Enable a label as a Drag Source
+ * Label label = new Label(shell, SWT.NONE);
+ * // This example will allow text to be dragged
+ * Transfer[] types = new Transfer[] {TextTransfer.getInstance()};
+ * // This example will allow the text to be copied or moved to the drop target
+ * int operations = DND.DROP_MOVE | DND.DROP_COPY;
+ *
+ * DragSource source = new DragSource(label, operations);
+ * source.setTransfer(types);
+ * source.addDragListener(new DragSourceListener() {
+ * public void dragStart(DragSourceEvent e) {
+ * // Only start the drag if there is actually text in the
+ * // label - this text will be what is dropped on the target.
+ * if (label.getText().length() == 0) {
+ * event.doit = false;
+ * }
+ * };
+ * public void dragSetData(DragSourceEvent event) {
+ * // A drop has been performed, so provide the data of the
+ * // requested type.
+ * // (Checking the type of the requested data is only
+ * // necessary if the drag source supports more than
+ * // one data type but is shown here as an example).
+ * if (TextTransfer.getInstance().isSupportedType(event.dataType)){
+ * event.data = label.getText();
+ * }
+ * }
+ * public void dragFinished(DragSourceEvent event) {
+ * // A Move operation has been performed so remove the data
+ * // from the source
+ * if (event.detail == DND.DROP_MOVE)
+ * label.setText("");
+ * }
+ * });
+ * </pre></code>
+ *
+ *
+ * <dl>
+ * <dt><b>Styles</b></dt>
+ * <dd>DND.DROP_NONE, DND.DROP_COPY, DND.DROP_MOVE, DND.DROP_LINK</dd>
+ * <dt><b>Events</b></dt>
+ * <dd>DND.DragStart, DND.DragSetData, DND.DragEnd</dd>
+ * </dl>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#dnd">Drag and Drop
+ * snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * DNDExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class DragSource extends Widget {
+
+ // info for registering as a drag source
+ private Control control;
+ private Listener controlListener;
+ private Transfer[] transferAgents = new Transfer[0];
+ private DragSourceEffect dragEffect;
+ private QDrag drag;
+
+ private static final String DEFAULT_DRAG_SOURCE_EFFECT = "DEFAULT_DRAG_SOURCE_EFFECT"; //$NON-NLS-1$
+
+ /**
+ * Creates a new <code>DragSource</code> to handle dragging from the
+ * specified <code>Control</code>. Creating an instance of a DragSource may
+ * cause system resources to be allocated depending on the platform. It is
+ * therefore mandatory that the DragSource instance be disposed when no
+ * longer required.
+ *
+ * @param control
+ * the <code>Control</code> that the user clicks on to initiate
+ * the drag
+ * @param style
+ * the bitwise OR'ing of allowed operations; this may be a
+ * combination of any of DND.DROP_NONE, DND.DROP_COPY,
+ * DND.DROP_MOVE, DND.DROP_LINK
+ *
+ * @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>
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_CANNOT_INIT_DRAG - unable to initiate drag
+ * source; this will occur if more than one drag source is
+ * created for a control or if the operating system will not
+ * allow the creation of the drag source</li>
+ * </ul>
+ *
+ * <p>
+ * NOTE: ERROR_CANNOT_INIT_DRAG should be an SWTException,
+ * since it is a recoverable error, but can not be changed
+ * due to backward compatibility.
+ * </p>
+ *
+ * @see Widget#dispose
+ * @see DragSource#checkSubclass
+ * @see DND#DROP_NONE
+ * @see DND#DROP_COPY
+ * @see DND#DROP_MOVE
+ * @see DND#DROP_LINK
+ */
+ public DragSource(Control control, int style) {
+ super(control, checkStyle(style));
+ this.control = control;
+ if (control.getData(DND.DRAG_SOURCE_KEY) != null) {
+ DND.error(DND.ERROR_CANNOT_INIT_DRAG);
+ }
+ control.setDragEnabled(true);
+ control.setData(DND.DRAG_SOURCE_KEY, this);
+
+ controlListener = new Listener() {
+ public void handleEvent(Event event) {
+ if (event.type == SWT.DragDetect) {
+ if (!DragSource.this.isDisposed()) {
+ DragSource.this.drag(event);
+ return;
+ }
+ }
+ if (event.type == SWT.Dispose) {
+ if (!DragSource.this.isDisposed()) {
+ DragSource.this.dispose();
+ }
+ }
+ }
+ };
+ control.addListener(SWT.Dispose, controlListener);
+ control.addListener(SWT.DragDetect, controlListener);
+
+ this.addListener(SWT.Dispose, new Listener() {
+ public void handleEvent(Event e) {
+ onDispose();
+ }
+ });
+
+ Object effect = control.getData(DEFAULT_DRAG_SOURCE_EFFECT);
+ if (effect instanceof DragSourceEffect) {
+ dragEffect = (DragSourceEffect) effect;
+ } else if (control instanceof Tree) {
+ dragEffect = new TreeDragSourceEffect((Tree) control);
+ } else if (control instanceof Table) {
+ dragEffect = new TableDragSourceEffect((Table) control);
+ }
+ }
+
+ private void drag(Event dragEvent) {
+ if (transferAgents == null || transferAgents.length == 0) {
+ return;
+ }
+ System.out.println("dragging ongoing");
+
+ try {
+ if (drag == null) {
+ DNDEvent event = new DNDEvent();
+ event.widget = this;
+ event.x = dragEvent.x;
+ event.y = dragEvent.y;
+ event.time = dragEvent.time;
+ event.doit = true;
+ notifyListeners(DND.DragStart, event);
+
+ if (!event.doit) {
+ System.out.println("stop after DragStart event");
+ return;
+ }
+
+ QMimeData mimeData = createMimeData();
+ if (mimeData == null) {
+ System.out.println("stop after DragSetData event");
+ return;
+ }
+
+ System.out.println("send mime: " + mimeData);
+
+ drag = new QDrag(control.getQWidget());
+
+ drag.setMimeData(mimeData);
+
+ DropActions actions = convertOps2Actions(getStyle());
+ DropAction dropAction = drag.exec(actions, defaultAction(actions));
+
+ int operation = convertAction(dropAction);
+ DNDEvent endEvent = new DNDEvent();
+ endEvent.widget = this;
+ endEvent.doit = operation != 0;
+ endEvent.detail = operation;
+ notifyListeners(DND.DragEnd, endEvent);
+
+ control.dragEnd();
+ System.out.println(dropAction);
+ }
+ } finally {
+ drag = null;
+ }
+ }
+
+ /**
+ * @param actions
+ * @return
+ */
+ private DropAction defaultAction(DropActions actions) {
+ if (actions.isSet(DropAction.CopyAction)) {
+ return DropAction.CopyAction;
+ } else if (actions.isSet(DropAction.MoveAction)) {
+ return DropAction.MoveAction;
+ } else if (actions.isSet(DropAction.LinkAction)) {
+ return DropAction.LinkAction;
+ } else if (actions.isSet(DropAction.TargetMoveAction)) {
+ return DropAction.TargetMoveAction;
+ }
+ return DropAction.IgnoreAction;
+ }
+
+ /**
+ * @param dragEvent
+ * @return
+ */
+ private QMimeData createMimeData() {
+ QMimeData mimeData = null;
+ for (Transfer transfer : transferAgents) {
+ if (transfer == null) {
+ continue;
+ }
+ for (TransferData transferData : transfer.getSupportedTypes()) {
+ DNDEvent setDataEvent = new DNDEvent();
+ setDataEvent.widget = this;
+ setDataEvent.dataType = transferData;
+ notifyListeners(DND.DragSetData, setDataEvent);
+ if (setDataEvent.doit && setDataEvent.data != null) {
+ transfer.javaToNative(setDataEvent.data, transferData);
+ if (mimeData == null) {
+ mimeData = new QMimeData();
+ }
+ mimeData.setData(transferData.format, new QByteArray((byte[]) transferData.data));
+ }
+ }
+ }
+ return mimeData;
+ }
+
+ static int convertAction(DropAction dropAction) {
+ if (dropAction == DropAction.CopyAction) {
+ return DND.DROP_COPY;
+ }
+ if (dropAction == DropAction.MoveAction) {
+ return DND.DROP_MOVE;
+ }
+ if (dropAction == DropAction.LinkAction) {
+ return DND.DROP_LINK;
+ }
+ if (dropAction == DropAction.TargetMoveAction) {
+ return DND.DROP_TARGET_MOVE;
+ }
+ return DND.DROP_NONE;
+ }
+
+ static int convertActions(DropActions dropActions) {
+ int actions = DND.DROP_NONE;
+ if (dropActions.isSet(DropAction.CopyAction)) {
+ actions |= DND.DROP_COPY;
+ }
+ if (dropActions.isSet(DropAction.MoveAction)) {
+ actions |= DND.DROP_MOVE;
+ }
+ if (dropActions.isSet(DropAction.LinkAction)) {
+ actions |= DND.DROP_LINK;
+ }
+ if (dropActions.isSet(DropAction.TargetMoveAction)) {
+ actions |= DND.DROP_TARGET_MOVE;
+ }
+ return actions;
+ }
+
+ static DropActions convertOps2Actions(int operations) {
+ int actions = 0;
+ if ((operations & DND.DROP_COPY) != 0) {
+ actions |= DropAction.CopyAction.value();
+ }
+ if ((operations & DND.DROP_MOVE) != 0) {
+ actions |= DropAction.MoveAction.value();
+ }
+ if ((operations & DND.DROP_LINK) != 0) {
+ actions |= DropAction.LinkAction.value();
+ }
+ if ((operations & DND.DROP_TARGET_MOVE) != 0) {
+ actions |= DropAction.TargetMoveAction.value();
+ }
+ return new DropActions(actions);
+ }
+
+ /**
+ * Adds the listener to the collection of listeners who will be notified
+ * when a drag and drop operation is in progress, by sending it one of the
+ * messages defined in the <code>DragSourceListener</code> interface.
+ *
+ * <p>
+ * <ul>
+ * <li><code>dragStart</code> is called when the user has begun the actions
+ * required to drag the widget. This event gives the application the chance
+ * to decide if a drag should be started.
+ * <li><code>dragSetData</code> is called when the data is required from the
+ * drag source.
+ * <li><code>dragFinished</code> is called when the drop has successfully
+ * completed (mouse up over a valid target) or has been terminated (such as
+ * hitting the ESC key). Perform cleanup such as removing data from the
+ * source side on a successful move operation.
+ * </ul>
+ * </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 DragSourceListener
+ * @see #getDragListeners
+ * @see #removeDragListener
+ * @see DragSourceEvent
+ */
+ public void addDragListener(DragSourceListener listener) {
+ if (listener == null) {
+ DND.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ DNDListener typedListener = new DNDListener(listener);
+ typedListener.dndWidget = this;
+ addListener(DND.DragStart, typedListener);
+ addListener(DND.DragSetData, typedListener);
+ addListener(DND.DragEnd, typedListener);
+ }
+
+ static int checkStyle(int style) {
+ if (style == SWT.NONE) {
+ return DND.DROP_MOVE;
+ }
+ return style;
+ }
+
+ @Override
+ protected void checkSubclass() {
+ String name = getClass().getName();
+ String validName = DragSource.class.getName();
+ if (!validName.equals(name)) {
+ DND.error(SWT.ERROR_INVALID_SUBCLASS);
+ }
+ }
+
+ /**
+ * Returns the Control which is registered for this DragSource. This is the
+ * control that the user clicks in to initiate dragging.
+ *
+ * @return the Control which is registered for this DragSource
+ */
+ public Control getControl() {
+ return control;
+ }
+
+ /**
+ * Returns an array of listeners who will be notified when a drag and drop
+ * operation is in progress, by sending it one of the messages defined in
+ * the <code>DragSourceListener</code> interface.
+ *
+ * @return the listeners who will be notified when a drag and drop operation
+ * is in progress
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - 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 DragSourceListener
+ * @see #addDragListener
+ * @see #removeDragListener
+ * @see DragSourceEvent
+ *
+ * @since 3.4
+ */
+ public DragSourceListener[] getDragListeners() {
+ Listener[] listeners = getListeners(DND.DragStart);
+ int length = listeners.length;
+ DragSourceListener[] dragListeners = new DragSourceListener[length];
+ int count = 0;
+ for (int i = 0; i < length; i++) {
+ Listener listener = listeners[i];
+ if (listener instanceof DNDListener) {
+ dragListeners[count] = (DragSourceListener) ((DNDListener) listener).getEventListener();
+ count++;
+ }
+ }
+ if (count == length) {
+ return dragListeners;
+ }
+ DragSourceListener[] result = new DragSourceListener[count];
+ System.arraycopy(dragListeners, 0, result, 0, count);
+ return result;
+ }
+
+ /**
+ * Returns the drag effect that is registered for this DragSource. This drag
+ * effect will be used during a drag and drop operation.
+ *
+ * @return the drag effect that is registered for this DragSource
+ *
+ * @since 3.3
+ */
+ public DragSourceEffect getDragSourceEffect() {
+ return dragEffect;
+ }
+
+ /**
+ * Returns the list of data types that can be transferred by this
+ * DragSource.
+ *
+ * @return the list of data types that can be transferred by this DragSource
+ */
+ public Transfer[] getTransfer() {
+ return transferAgents;
+ }
+
+ private void onDispose() {
+ if (control == null) {
+ return;
+ }
+ if (controlListener != null) {
+ control.removeListener(SWT.Dispose, controlListener);
+ control.removeListener(SWT.DragDetect, controlListener);
+ }
+ controlListener = null;
+ control.setData(DND.DRAG_SOURCE_KEY, null);
+ control = null;
+ transferAgents = null;
+ }
+
+ /**
+ * Removes the listener from the collection of listeners who will be
+ * notified when a drag and drop operation is in progress.
+ *
+ * @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 DragSourceListener
+ * @see #addDragListener
+ * @see #getDragListeners
+ */
+ public void removeDragListener(DragSourceListener listener) {
+ if (listener == null) {
+ DND.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ removeListener(DND.DragStart, listener);
+ removeListener(DND.DragSetData, listener);
+ removeListener(DND.DragEnd, listener);
+ }
+
+ /**
+ * Specifies the drag effect for this DragSource. This drag effect will be
+ * used during a drag and drop operation.
+ *
+ * @param effect
+ * the drag effect that is registered for this DragSource
+ *
+ * @since 3.3
+ */
+ public void setDragSourceEffect(DragSourceEffect effect) {
+ dragEffect = effect;
+ }
+
+ /**
+ * Specifies the list of data types that can be transferred by this
+ * DragSource. The application must be able to provide data to match each of
+ * these types when a successful drop has occurred.
+ *
+ * @param transferAgents
+ * a list of Transfer objects which define the types of data that
+ * can be dragged from this source
+ */
+ public void setTransfer(Transfer[] transferAgents) {
+ this.transferAgents = transferAgents;
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/DropTarget.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/DropTarget.java
new file mode 100644
index 0000000000..4bf4db6afd
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/DropTarget.java
@@ -0,0 +1,638 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.dnd;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.trolltech.qt.core.QByteArray;
+import com.trolltech.qt.core.QMimeData;
+import com.trolltech.qt.core.QPoint;
+import com.trolltech.qt.core.Qt.DropAction;
+import com.trolltech.qt.core.Qt.DropActions;
+import com.trolltech.qt.gui.QDragEnterEvent;
+import com.trolltech.qt.gui.QDragLeaveEvent;
+import com.trolltech.qt.gui.QDragMoveEvent;
+import com.trolltech.qt.gui.QDropEvent;
+import com.trolltech.qt.gui.QWidget;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTError;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.internal.qt.DragNDropListener;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ *
+ * Class <code>DropTarget</code> defines the target object for a drag and drop
+ * transfer.
+ *
+ * <p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ *
+ * <p>
+ * This class identifies the <code>Control</code> over which the user must
+ * position the cursor in order to drop the data being transferred. It also
+ * specifies what data types can be dropped on this control and what operations
+ * can be performed. You may have several DropTragets in an application but
+ * there can only be a one to one mapping between a <code>Control</code> and a
+ * <code>DropTarget</code>. The DropTarget can receive data from within the same
+ * application or from other applications (such as text dragged from a text
+ * editor like Word).
+ * </p>
+ *
+ * <code><pre>
+ * int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK;
+ * Transfer[] types = new Transfer[] {TextTransfer.getInstance()};
+ * DropTarget target = new DropTarget(label, operations);
+ * target.setTransfer(types);
+ * </code></pre>
+ *
+ * <p>
+ * The application is notified of data being dragged over this control and of
+ * when a drop occurs by implementing the interface
+ * <code>DropTargetListener</code> which uses the class
+ * <code>DropTargetEvent</code>. The application can modify the type of drag
+ * being performed on this Control at any stage of the drag by modifying the
+ * <code>event.detail</code> field or the <code>event.currentDataType</code>
+ * field. When the data is dropped, it is the responsibility of the application
+ * to copy this data for its own purposes.
+ *
+ * <code><pre>
+ * target.addDropListener (new DropTargetListener() {
+ * public void dragEnter(DropTargetEvent event) {};
+ * public void dragOver(DropTargetEvent event) {};
+ * public void dragLeave(DropTargetEvent event) {};
+ * public void dragOperationChanged(DropTargetEvent event) {};
+ * public void dropAccept(DropTargetEvent event) {}
+ * public void drop(DropTargetEvent event) {
+ * // A drop has occurred, copy over the data
+ * if (event.data == null) { // no data to copy, indicate failure in event.detail
+ * event.detail = DND.DROP_NONE;
+ * return;
+ * }
+ * label.setText ((String) event.data); // data copied to label text
+ * }
+ * });
+ * </pre></code>
+ *
+ * <dl>
+ * <dt><b>Styles</b></dt>
+ * <dd>DND.DROP_NONE, DND.DROP_COPY, DND.DROP_MOVE, DND.DROP_LINK</dd>
+ * <dt><b>Events</b></dt>
+ * <dd>DND.DragEnter, DND.DragLeave, DND.DragOver, DND.DragOperationChanged,
+ * DND.DropAccept, DND.Drop</dd>
+ * </dl>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#dnd">Drag and Drop
+ * snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * DNDExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class DropTarget extends Widget {
+
+ // info for registering as a droptarget
+ Control control;
+ Listener controlListener;
+ Transfer[] transferAgents = new Transfer[0];
+ DropTargetEffect dropEffect;
+ private DragNDropListener dndListener;
+
+ static final String DEFAULT_DROP_TARGET_EFFECT = "DEFAULT_DROP_TARGET_EFFECT"; //$NON-NLS-1$
+
+ /**
+ * Creates a new <code>DropTarget</code> to allow data to be dropped on the
+ * specified <code>Control</code>. Creating an instance of a DropTarget may
+ * cause system resources to be allocated depending on the platform. It is
+ * therefore mandatory that the DropTarget instance be disposed when no
+ * longer required.
+ *
+ * @param control
+ * the <code>Control</code> over which the user positions the
+ * cursor to drop the data
+ * @param style
+ * the bitwise OR'ing of allowed operations; this may be a
+ * combination of any of DND.DROP_NONE, DND.DROP_COPY,
+ * DND.DROP_MOVE, DND.DROP_LINK
+ *
+ * @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>
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_CANNOT_INIT_DROP - unable to initiate drop
+ * target; this will occur if more than one drop target is
+ * created for a control or if the operating system will not
+ * allow the creation of the drop target</li>
+ * </ul>
+ *
+ * <p>
+ * NOTE: ERROR_CANNOT_INIT_DROP should be an SWTException,
+ * since it is a recoverable error, but can not be changed
+ * due to backward compatibility.
+ * </p>
+ *
+ * @see Widget#dispose
+ * @see DropTarget#checkSubclass
+ * @see DND#DROP_NONE
+ * @see DND#DROP_COPY
+ * @see DND#DROP_MOVE
+ * @see DND#DROP_LINK
+ */
+ public DropTarget(Control control, int style) {
+ super(control, checkStyle(style));
+ this.control = control;
+ if (control.getData(DND.DROP_TARGET_KEY) != null) {
+ DND.error(DND.ERROR_CANNOT_INIT_DROP);
+ }
+ control.setData(DND.DROP_TARGET_KEY, this);
+ control.setAcceptDrops(true);
+
+ controlListener = new Listener() {
+ public void handleEvent(Event event) {
+ if (!DropTarget.this.isDisposed()) {
+ DropTarget.this.dispose();
+ }
+ }
+ };
+ control.addListener(SWT.Dispose, controlListener);
+
+ this.addListener(SWT.Dispose, new Listener() {
+ public void handleEvent(Event event) {
+ onDispose();
+ }
+ });
+
+ this.dndListener = new QDNDListener();
+ control.setDragNDropListener(dndListener);
+
+ Object effect = control.getData(DEFAULT_DROP_TARGET_EFFECT);
+ if (effect instanceof DropTargetEffect) {
+ dropEffect = (DropTargetEffect) effect;
+ } else if (control instanceof Table) {
+ dropEffect = new TableDropTargetEffect((Table) control);
+ } else if (control instanceof Tree) {
+ dropEffect = new TreeDropTargetEffect((Tree) control);
+ }
+ }
+
+ /**
+ * Adds the listener to the collection of listeners who will be notified
+ * when a drag and drop operation is in progress, by sending it one of the
+ * messages defined in the <code>DropTargetListener</code> interface.
+ *
+ * <p>
+ * <ul>
+ * <li><code>dragEnter</code> is called when the cursor has entered the drop
+ * target boundaries
+ * <li><code>dragLeave</code> is called when the cursor has left the drop
+ * target boundaries and just before the drop occurs or is cancelled.
+ * <li><code>dragOperationChanged</code> is called when the operation being
+ * performed has changed (usually due to the user changing the selected
+ * modifier key(s) while dragging)
+ * <li><code>dragOver</code> is called when the cursor is moving over the
+ * drop target
+ * <li><code>dropAccept</code> is called just before the drop is performed.
+ * The drop target is given the chance to change the nature of the drop or
+ * veto the drop by setting the <code>event.detail</code> field
+ * <li><code>drop</code> is called when the data is being dropped
+ * </ul>
+ * </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 DropTargetListener
+ * @see #getDropListeners
+ * @see #removeDropListener
+ * @see DropTargetEvent
+ */
+ public void addDropListener(DropTargetListener listener) {
+ if (listener == null) {
+ DND.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ DNDListener typedListener = new DNDListener(listener);
+ typedListener.dndWidget = this;
+ addListener(DND.DragEnter, typedListener);
+ addListener(DND.DragLeave, typedListener);
+ addListener(DND.DragOver, typedListener);
+ addListener(DND.DragOperationChanged, typedListener);
+ addListener(DND.Drop, typedListener);
+ addListener(DND.DropAccept, typedListener);
+ }
+
+ static int checkStyle(int style) {
+ if (style == SWT.NONE) {
+ return DND.DROP_MOVE;
+ }
+ return style;
+ }
+
+ @Override
+ protected void checkSubclass() {
+ String name = getClass().getName();
+ String validName = DropTarget.class.getName();
+ if (!validName.equals(name)) {
+ DND.error(SWT.ERROR_INVALID_SUBCLASS);
+ }
+ }
+
+ /**
+ * Returns the Control which is registered for this DropTarget. This is the
+ * control over which the user positions the cursor to drop the data.
+ *
+ * @return the Control which is registered for this DropTarget
+ */
+ public Control getControl() {
+ return control;
+ }
+
+ /**
+ * Returns an array of listeners who will be notified when a drag and drop
+ * operation is in progress, by sending it one of the messages defined in
+ * the <code>DropTargetListener</code> interface.
+ *
+ * @return the listeners who will be notified when a drag and drop operation
+ * is in progress
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - 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 DropTargetListener
+ * @see #addDropListener
+ * @see #removeDropListener
+ * @see DropTargetEvent
+ *
+ * @since 3.4
+ */
+ public DropTargetListener[] getDropListeners() {
+ Listener[] listeners = getListeners(DND.DragEnter);
+ int length = listeners.length;
+ DropTargetListener[] dropListeners = new DropTargetListener[length];
+ int count = 0;
+ for (int i = 0; i < length; i++) {
+ Listener listener = listeners[i];
+ if (listener instanceof DropTargetListener) {
+ dropListeners[count] = (DropTargetListener) ((DNDListener) listener).getEventListener();
+ count++;
+ }
+ }
+ if (count == length) {
+ return dropListeners;
+ }
+ DropTargetListener[] result = new DropTargetListener[count];
+ System.arraycopy(dropListeners, 0, result, 0, count);
+ return result;
+ }
+
+ /**
+ * Returns the drop effect for this DropTarget. This drop effect will be
+ * used during a drag and drop to display the drag under effect on the
+ * target widget.
+ *
+ * @return the drop effect that is registered for this DropTarget
+ *
+ * @since 3.3
+ */
+ public DropTargetEffect getDropTargetEffect() {
+ return dropEffect;
+ }
+
+ /**
+ * Specifies the drop effect for this DropTarget. This drop effect will be
+ * used during a drag and drop to display the drag under effect on the
+ * target widget.
+ *
+ * @param effect
+ * the drop effect that is registered for this DropTarget
+ *
+ * @since 3.3
+ */
+ public void setDropTargetEffect(DropTargetEffect effect) {
+ dropEffect = effect;
+ }
+
+ /**
+ * Returns a list of the data types that can be transferred to this
+ * DropTarget.
+ *
+ * @return a list of the data types that can be transferred to this
+ * DropTarget
+ */
+ public Transfer[] getTransfer() {
+ return transferAgents;
+ }
+
+ void onDispose() {
+ if (control == null) {
+ return;
+ }
+ if (controlListener != null) {
+ control.removeListener(SWT.Dispose, controlListener);
+ }
+ controlListener = null;
+ control.unsetDragNDropListener(dndListener);
+ dndListener = null;
+ control.setData(DND.DROP_TARGET_KEY, null);
+ control.setAcceptDrops(false);
+ transferAgents = null;
+ control = null;
+ }
+
+ /**
+ * Removes the listener from the collection of listeners who will be
+ * notified when a drag and drop operation is in progress.
+ *
+ * @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 DropTargetListener
+ * @see #addDropListener
+ * @see #getDropListeners
+ */
+ public void removeDropListener(DropTargetListener listener) {
+ if (listener == null) {
+ DND.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ removeListener(DND.DragEnter, listener);
+ removeListener(DND.DragLeave, listener);
+ removeListener(DND.DragOver, listener);
+ removeListener(DND.DragOperationChanged, listener);
+ removeListener(DND.Drop, listener);
+ removeListener(DND.DropAccept, listener);
+ }
+
+ /**
+ * Specifies the data types that can be transferred to this DropTarget. If
+ * data is being dragged that does not match one of these types, the drop
+ * target will be notified of the drag and drop operation but the
+ * currentDataType will be null and the operation will be DND.NONE.
+ *
+ * @param transferAgents
+ * a list of Transfer objects which define the types of data that
+ * can be dropped on this target
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if transferAgents is null</li>
+ * </ul>
+ */
+ public void setTransfer(Transfer[] transferAgents) {
+ if (transferAgents == null) {
+ DND.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ this.transferAgents = transferAgents;
+ }
+
+ private final class QDNDListener implements DragNDropListener {
+ TransferData selectedDataType;
+ int selectedOperation = -1;
+
+ public void dragEnter(QDragEnterEvent qEvent) {
+ System.out.println("DNDListener.dragEnter");
+
+ DNDEvent event = new DNDEvent();
+ if (!initDNDEvent(event, qEvent.source(), qEvent.mimeData(), qEvent.pos(), qEvent.proposedAction(), qEvent
+ .possibleActions())) {
+ return;
+ }
+
+ int operation = event.detail;
+ int allowedOperations = event.operations;
+ System.out.println("proposed op: " + operation + " from: " + event.operations);
+ selectedDataType = null;
+ selectedOperation = DND.DROP_NONE;
+ notifyListeners(DND.DragEnter, event);
+
+ if (!handleEventResponse(qEvent, event, operation, allowedOperations)) {
+ qEvent.acceptProposedAction();
+ }
+ }
+
+ public void dragMove(QDragMoveEvent qEvent) {
+ System.out.println("DNDListener.dragMove");
+
+ DNDEvent event = new DNDEvent();
+ if (!initDNDEvent(event, qEvent.source(), qEvent.mimeData(), qEvent.pos(), qEvent.proposedAction(), qEvent
+ .possibleActions())) {
+ return;
+ }
+ int operation = event.detail;
+ int allowedOperations = event.operations;
+
+ System.out.println("proposed op: " + operation + " from: " + event.operations);
+
+ selectedDataType = null;
+ if (selectedOperation != operation) {
+ System.out.println("op changed");
+ notifyListeners(DND.DragOperationChanged, event);
+ } else {
+ notifyListeners(DND.DragOver, event);
+ }
+ handleEventResponse(qEvent, event, operation, allowedOperations);
+ }
+
+ public void drop(QDropEvent event) {
+ System.out.println("DNDListener.drop. selected type: " + selectedDataType + " op: " + selectedOperation);
+
+ DNDEvent swtEvent = new DNDEvent();
+ if (!initDNDEvent(swtEvent, event.source(), event.mimeData(), event.pos(), event.proposedAction(), event
+ .possibleActions())) {
+ return;
+ }
+
+ swtEvent.dataType = selectedDataType;
+ swtEvent.detail = selectedOperation;
+
+ Transfer transfer = getTransfer(selectedDataType.format);
+ QByteArray ba = event.mimeData().data(selectedDataType.format);
+ if (ba == null || transfer == null) {
+ System.out.println("no data or transfer for format: " + selectedDataType.format);
+ return;
+ }
+ selectedDataType.data = ba.toByteArray();
+ swtEvent.data = transfer.nativeToJava(selectedDataType);
+
+ notifyListeners(DND.Drop, swtEvent);
+ handleEventResponse(event, swtEvent, selectedOperation, selectedOperation);
+ }
+
+ public void dragLeave(QDragLeaveEvent event) {
+ System.out.println("DNDListener.dragLeave");
+ DNDEvent swtEvent = new DNDEvent();
+
+ swtEvent.widget = DropTarget.this;
+ swtEvent.detail = DND.DROP_NONE;
+ notifyListeners(DND.DragLeave, swtEvent);
+ selectedDataType = null;
+ selectedOperation = -1;
+ }
+
+ private boolean initDNDEvent(DNDEvent event, QWidget source, QMimeData mimeData, QPoint globalPos,
+ DropAction proposedAction, DropActions possibleActions) {
+
+ event.operations = DragSource.convertActions(possibleActions) & getStyle();
+ if (event.operations == DND.DROP_NONE) {
+ return false;
+ }
+
+ TransferData[] dataTypes = getDataTypes(mimeData);
+ if (dataTypes.length == 0) {
+ System.out.println("no supported mime types found");
+ return false;
+ }
+
+ QPoint pos = source.mapToGlobal(globalPos);
+ event.widget = DropTarget.this;
+ event.x = pos.x();
+ event.y = pos.y();
+ event.time = DropTarget.this.control.getDisplay().getLastEventTime();
+ event.dataType = dataTypes[0];
+ event.dataTypes = dataTypes;
+ event.detail = DragSource.convertAction(proposedAction);
+ event.feedback = DND.FEEDBACK_SELECT;
+ event.doit = true;
+ if (dropEffect != null) {
+ event.item = dropEffect.getItem(event.x, event.y);
+ }
+
+ return true;
+ }
+
+ private boolean handleEventResponse(QDropEvent qEvent, DNDEvent event, int operation, int allowedOperations) {
+ selectedDataType = event.dataType;
+ System.out.println("selected type: " + selectedDataType);
+ System.out.println("op from event : " + event.detail);
+ if (event.detail == DND.DROP_DEFAULT) {
+ event.detail = (allowedOperations & DND.DROP_MOVE) != 0 ? DND.DROP_MOVE : DND.DROP_NONE;
+ }
+
+ if (selectedDataType != null && (allowedOperations & event.detail) != 0) {
+ selectedOperation = event.detail;
+ }
+ System.out.println("selected op : " + selectedOperation);
+
+ if (selectedOperation == operation) {
+ qEvent.acceptProposedAction();
+ } else {
+ if (selectedOperation != DND.DROP_NONE) {
+ DropAction action = convertOperation(selectedOperation);
+ System.out.println("changed op: " + action);
+ qEvent.setDropAction(action);
+ qEvent.accept();
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private Transfer getTransfer(String format) {
+ for (Transfer transfer : transferAgents) {
+ if (transfer == null) {
+ continue;
+ }
+ for (String typeName : transfer.getTypeNames()) {
+ if (format.equals(typeName)) {
+ return transfer;
+ }
+ }
+ }
+ return null;
+ }
+
+ private TransferData[] getDataTypes(QMimeData mimeData) {
+ System.out.println("got mimeData " + mimeData.formats());
+
+ List<TransferData> dataTypes = new ArrayList<TransferData>();
+ for (Transfer transfer : transferAgents) {
+ if (transfer == null) {
+ continue;
+ }
+ String[] typeNames = transfer.getTypeNames();
+ int[] typeIds = transfer.getTypeIds();
+ for (int i = 0; i < typeNames.length; i++) {
+ String typeName = typeNames[i];
+ if (mimeData.hasFormat(typeName)) {
+ TransferData data = new TransferData();
+ data.type = typeIds[i];
+ data.format = typeName;
+ dataTypes.add(data);
+ }
+ }
+ }
+ //System.out.println("mime -> transfer types: " + dataTypes);
+ return dataTypes.toArray(new TransferData[dataTypes.size()]);
+ }
+
+ private DropAction convertOperation(int operation) {
+ if (operation == DND.DROP_COPY) {
+ return DropAction.CopyAction;
+ }
+ if (operation == DND.DROP_MOVE) {
+ return DropAction.MoveAction;
+ }
+ if (operation == DND.DROP_LINK) {
+ return DropAction.LinkAction;
+ }
+ if (operation == DND.DROP_TARGET_MOVE) {
+ return DropAction.TargetMoveAction;
+ }
+ return DropAction.IgnoreAction;
+ }
+
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/FileTransfer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/FileTransfer.java
new file mode 100644
index 0000000000..21e615d272
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/FileTransfer.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.dnd;
+
+/**
+ * The class <code>FileTransfer</code> provides a platform specific mechanism
+ * for converting a list of files represented as a java <code>String[]</code> to
+ * a platform specific representation of the data and vice versa. Each
+ * <code>String</code> in the array contains the absolute path for a single file
+ * or directory.
+ *
+ * <p>
+ * An example of a java <code>String[]</code> containing a list of files is
+ * shown below:
+ * </p>
+ *
+ * <code><pre>
+ * File file1 = new File("C:\temp\file1");
+ * File file2 = new File("C:\temp\file2");
+ * String[] fileData = new String[2];
+ * fileData[0] = file1.getAbsolutePath();
+ * fileData[1] = file2.getAbsolutePath();
+ * </code></pre>
+ *
+ * @see Transfer
+ */
+public class FileTransfer extends ByteArrayTransfer {
+ /**
+ *
+ */
+ private static final String SEPARATOR = "\n";
+ private static final String URI_LIST = "text/uri-list"; //$NON-NLS-1$
+ private static final int URI_LIST_ID = registerType(URI_LIST);
+
+ private FileTransfer() {
+ }
+
+ private static FileTransfer _instance = new FileTransfer();
+
+ /**
+ * Returns the singleton instance of the FileTransfer class.
+ *
+ * @return the singleton instance of the FileTransfer class
+ */
+ public static FileTransfer getInstance() {
+ return _instance;
+ }
+
+ /**
+ * This implementation of <code>javaToNative</code> converts a list of file
+ * names represented by a java <code>String[]</code> to a platform specific
+ * representation. Each <code>String</code> in the array contains the
+ * absolute path for a single file or directory.
+ *
+ * @param object
+ * a java <code>String[]</code> containing the file names to be
+ * converted
+ * @param transferData
+ * an empty <code>TransferData</code> object that will be filled
+ * in on return with the platform specific format of the data
+ *
+ * @see Transfer#nativeToJava
+ */
+ @Override
+ public void javaToNative(Object object, TransferData transferData) {
+ if (!checkStringArray(object) || !isSupportedType(transferData)) {
+ DND.error(DND.ERROR_INVALID_DATA);
+ }
+ boolean first = true;
+ StringBuilder sb = new StringBuilder();
+ String[] files = (String[]) object;
+ for (String file : files) {
+ if (file == null || file.length() == 0) {
+ continue;
+ }
+ System.out.println("dnd file: " + file);
+ if (first) {
+ first = false;
+ } else {
+ sb.append(SEPARATOR);
+ }
+ sb.append("file://");
+ sb.append(file);
+ }
+ transferData.data = sb.toString().getBytes();
+ transferData.format = URI_LIST;
+ }
+
+ /**
+ * This implementation of <code>nativeToJava</code> converts a platform
+ * specific representation of a list of file names to a java
+ * <code>String[]</code>. Each String in the array contains the absolute
+ * path for a single file or directory.
+ *
+ * @param transferData
+ * the platform specific representation of the data to be
+ * converted
+ * @return a java <code>String[]</code> containing a list of file names if
+ * the conversion was successful; otherwise null
+ *
+ * @see Transfer#javaToNative
+ */
+ @Override
+ public Object nativeToJava(TransferData transferData) {
+ byte[] data = (byte[]) super.nativeToJava(transferData);
+ if (data == null) {
+ return null;
+ }
+ String[] files = new String(data).split(SEPARATOR);
+ return files;
+ }
+
+ @Override
+ protected int[] getTypeIds() {
+ return new int[] { URI_LIST_ID };
+ }
+
+ @Override
+ protected String[] getTypeNames() {
+ return new String[] { URI_LIST };
+ }
+
+ boolean checkStringArray(Object object) {
+ if (object == null || !(object instanceof String[]) || ((String[]) object).length == 0) {
+ return false;
+ }
+ String[] strings = (String[]) object;
+ for (int i = 0; i < strings.length; i++) {
+ if (strings[i] == null || strings[i].length() == 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/HTMLTransfer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/HTMLTransfer.java
new file mode 100644
index 0000000000..afdec0185a
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/HTMLTransfer.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.dnd;
+
+/**
+ * The class <code>HTMLTransfer</code> provides a platform specific mechanism
+ * for converting text in HTML format represented as a java <code>String</code>
+ * to a platform specific representation of the data and vice versa.
+ *
+ * <p>An example of a java <code>String</code> containing HTML text is shown
+ * below:</p>
+ *
+ * <code><pre>
+ * String htmlData = "<p>This is a paragraph of text.</p>";
+ * </code></pre>
+ *
+ * @see Transfer
+ */
+public class HTMLTransfer extends ByteArrayTransfer {
+
+ private static HTMLTransfer _instance = new HTMLTransfer();
+ private static final String TYPENAME1 = "text/html\0";
+ private static final int TYPEID1 = registerType(TYPENAME1);
+ private static final String TYPENAME2 = "TEXT/HTML\0";
+ private static final int TYPEID2 = registerType(TYPENAME2);
+
+private HTMLTransfer() {
+}
+/**
+ * Returns the singleton instance of the HTMLTransfer class.
+ *
+ * @return the singleton instance of the HTMLTransfer class
+ */
+public static HTMLTransfer getInstance () {
+ return _instance;
+}
+/**
+ * This implementation of <code>javaToNative</code> converts HTML-formatted text
+ * represented by a java <code>String</code> to a platform specific representation.
+ *
+ * @param object a java <code>String</code> containing HTML text
+ * @param transferData an empty <code>TransferData</code> object that will
+ * be filled in on return with the platform specific format of the data
+ *
+ * @see Transfer#nativeToJava
+ */
+public void javaToNative (Object object, TransferData transferData){
+}
+/**
+ * This implementation of <code>nativeToJava</code> converts a platform specific
+ * representation of HTML text to a java <code>String</code>.
+ *
+ * @param transferData the platform specific representation of the data to be converted
+ * @return a java <code>String</code> containing HTML text if the conversion was successful;
+ * otherwise null
+ *
+ * @see Transfer#javaToNative
+ */
+public Object nativeToJava(TransferData transferData){
+ return null;
+}
+protected String[] getTypeNames(){
+ return new String[]{TYPENAME1, TYPENAME2};
+}
+protected int[] getTypeIds(){
+ return new int[]{TYPEID1, TYPEID2};
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/ImageTransfer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/ImageTransfer.java
new file mode 100644
index 0000000000..8e5c3a4d28
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/ImageTransfer.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 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.dnd;
+
+/**
+ * The class <code>ImageTransfer</code> provides a platform specific mechanism
+ * for converting an Image represented as a java <code>ImageData</code> to a
+ * platform specific representation of the data and vice versa.
+ *
+ * <p>An example of a java <code>ImageData</code> is shown below:</p>
+ *
+ * <code><pre>
+ * Image image = new Image(display, "C:\temp\img1.gif");
+ * ImageData imgData = image.getImageData();
+ * </code></pre>
+ *
+ * @see Transfer
+ *
+ * @since 3.4
+ */
+public class ImageTransfer extends ByteArrayTransfer {
+
+private ImageTransfer() {}
+
+/**
+ * Returns the singleton instance of the ImageTransfer class.
+ *
+ * @return the singleton instance of the ImageTransfer class
+ */
+public static ImageTransfer getInstance () {
+ return null;
+}
+
+/**
+ * This implementation of <code>javaToNative</code> converts an ImageData object represented
+ * by java <code>ImageData</code> to a platform specific representation.
+ *
+ * @param object a java <code>ImageData</code> containing the ImageData to be converted
+ * @param transferData an empty <code>TransferData</code> object that will
+ * be filled in on return with the platform specific format of the data
+ *
+ * @see Transfer#nativeToJava
+ */
+public void javaToNative(Object object, TransferData transferData) {
+}
+
+/**
+ * This implementation of <code>nativeToJava</code> converts a platform specific
+ * representation of an image to java <code>ImageData</code>.
+ *
+ * @param transferData the platform specific representation of the data to be converted
+ * @return a java <code>ImageData</code> of the image if the conversion was successful;
+ * otherwise null
+ *
+ * @see Transfer#javaToNative
+ */
+public Object nativeToJava(TransferData transferData) {
+ return null;
+}
+
+protected int[] getTypeIds(){
+ return null;
+}
+
+protected String[] getTypeNames(){
+ return null;
+}
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/RTFTransfer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/RTFTransfer.java
new file mode 100644
index 0000000000..11085904b3
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/RTFTransfer.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.dnd;
+
+
+/**
+ * The class <code>RTFTransfer</code> provides a platform specific mechanism
+ * for converting text in RTF format represented as a java <code>String</code>
+ * to a platform specific representation of the data and vice versa.
+ *
+ * <p>An example of a java <code>String</code> containing RTF text is shown
+ * below:</p>
+ *
+ * <code><pre>
+ * String rtfData = "{\\rtf1{\\colortbl;\\red255\\green0\\blue0;}\\uc1\\b\\i Hello World}";
+ * </code></pre>
+ *
+ * @see Transfer
+ */
+public class RTFTransfer extends ByteArrayTransfer {
+
+ private static RTFTransfer _instance = new RTFTransfer();
+ private static final String TYPENAME1 = "text/rtf\0";
+ private static final int TYPEID1 = registerType(TYPENAME1);
+ private static final String TYPENAME2 = "TEXT/RTF\0";
+ private static final int TYPEID2 = registerType(TYPENAME2);
+ private static final String TYPENAME3 = "application/rtf\0";
+ private static final int TYPEID3 = registerType(TYPENAME3);
+
+private RTFTransfer() {
+}
+/**
+ * Returns the singleton instance of the RTFTransfer class.
+ *
+ * @return the singleton instance of the RTFTransfer class
+ */
+public static RTFTransfer getInstance () {
+ return _instance;
+}
+/**
+ * This implementation of <code>javaToNative</code> converts RTF-formatted text
+ * represented by a java <code>String</code> to a platform specific representation.
+ *
+ * @param object a java <code>String</code> containing RTF text
+ * @param transferData an empty <code>TransferData</code> object that will
+ * be filled in on return with the platform specific format of the data
+ *
+ * @see Transfer#nativeToJava
+ */
+public void javaToNative (Object object, TransferData transferData){
+}
+/**
+ * This implementation of <code>nativeToJava</code> converts a platform specific
+ * representation of RTF text to a java <code>String</code>.
+ *
+ * @param transferData the platform specific representation of the data to be converted
+ * @return a java <code>String</code> containing RTF text if the conversion was successful;
+ * otherwise null
+ *
+ * @see Transfer#javaToNative
+ */
+public Object nativeToJava(TransferData transferData){
+ return null;
+}
+protected String[] getTypeNames(){
+ return new String[]{TYPENAME1, TYPENAME2, TYPENAME3};
+}
+protected int[] getTypeIds(){
+ return new int[]{TYPEID1, TYPEID2, TYPEID3};
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TableDragSourceEffect.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TableDragSourceEffect.java
new file mode 100644
index 0000000000..b7dbda53be
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TableDragSourceEffect.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 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.dnd;
+
+import org.eclipse.swt.widgets.*;
+
+/**
+ * This class provides default implementations to display a source image
+ * when a drag is initiated from a <code>Table</code>.
+ *
+ * <p>Classes that wish to provide their own source image for a <code>Table</code> can
+ * extend the <code>TableDragSourceEffect</code> class, override the
+ * <code>TableDragSourceEffect.dragStart</code> method and set the field
+ * <code>DragSourceEvent.image</code> with their own image.</p>
+ *
+ * Subclasses that override any methods of this class must call the corresponding
+ * <code>super</code> method to get the default drag source effect implementation.
+ *
+ * @see DragSourceEffect
+ * @see DragSourceEvent
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
+ *
+ * @since 3.3
+ */
+public class TableDragSourceEffect extends DragSourceEffect {
+ /**
+ * Creates a new <code>TableDragSourceEffect</code> to handle drag effect
+ * from the specified <code>Table</code>.
+ *
+ * @param table the <code>Table</code> that the user clicks on to initiate the drag
+ */
+ public TableDragSourceEffect(Table table) {
+ super(table);
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TableDropTargetEffect.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TableDropTargetEffect.java
new file mode 100644
index 0000000000..8818ec6a4b
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TableDropTargetEffect.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.dnd;
+
+import org.eclipse.swt.widgets.*;
+
+/**
+ * This class provides a default drag under effect (eg. select, insert and scroll)
+ * when a drag occurs over a <code>Table</code>.
+ *
+ * <p>Classes that wish to provide their own drag under effect for a <code>Table</code>
+ * can extend the <code>TableDropTargetEffect</code> and override any applicable methods
+ * in <code>TableDropTargetEffect</code> to display their own drag under effect.</p>
+ *
+ * Subclasses that override any methods of this class must call the corresponding
+ * <code>super</code> method to get the default drag under effect implementation.
+ *
+ * <p>The feedback value is either one of the FEEDBACK constants defined in
+ * class <code>DND</code> which is applicable to instances of this class,
+ * or it must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>DND</code> effect constants.
+ * </p>
+ * <p>
+ * <dl>
+ * <dt><b>Feedback:</b></dt>
+ * <dd>FEEDBACK_SELECT, FEEDBACK_SCROLL</dd>
+ * </dl>
+ * </p>
+ *
+ * @see DropTargetAdapter
+ * @see DropTargetEvent
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
+ *
+ * @since 3.3
+ */
+public class TableDropTargetEffect extends DropTargetEffect {
+ /**
+ * Creates a new <code>TableDropTargetEffect</code> to handle the drag under effect on the specified
+ * <code>Table</code>.
+ *
+ * @param table the <code>Table</code> over which the user positions the cursor to drop the data
+ */
+ public TableDropTargetEffect(Table table) {
+ super(table);
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TextTransfer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TextTransfer.java
new file mode 100644
index 0000000000..0b83a9633b
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TextTransfer.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.dnd;
+
+/**
+ * The class <code>TextTransfer</code> provides a platform specific mechanism
+ * for converting plain text represented as a java <code>String</code> to a
+ * platform specific representation of the data and vice versa.
+ *
+ * <p>
+ * An example of a java <code>String</code> containing plain text is shown
+ * below:
+ * </p>
+ *
+ * <code><pre>
+ * String textData = "Hello World";
+ * </code></pre>
+ *
+ * @see Transfer
+ */
+public class TextTransfer extends ByteArrayTransfer {
+ private static final String TYPENAME = "text/plain"; //$NON-NLS-1$
+ private static final int TYPEID = registerType(TYPENAME);
+ private static TextTransfer _instance = new TextTransfer();
+
+ private TextTransfer() {
+ }
+
+ /**
+ * Returns the singleton instance of the TextTransfer class.
+ *
+ * @return the singleton instance of the TextTransfer class
+ */
+ public static TextTransfer getInstance() {
+ return _instance;
+ }
+
+ /**
+ * This implementation of <code>javaToNative</code> converts plain text
+ * represented by a java <code>String</code> to a platform specific
+ * representation.
+ *
+ * @param object
+ * a java <code>String</code> containing text
+ * @param transferData
+ * an empty <code>TransferData</code> object that will be filled
+ * in on return with the platform specific format of the data
+ *
+ * @see Transfer#nativeToJava
+ */
+ @Override
+ public void javaToNative(Object object, TransferData transferData) {
+ if (!checkText(object) || !isSupportedType(transferData)) {
+ DND.error(DND.ERROR_INVALID_DATA);
+ return;
+ }
+ transferData.data = ((String) object).getBytes();
+ transferData.format = TYPENAME;
+ transferData.type = TYPEID;
+ }
+
+ private boolean checkText(Object object) {
+ return object != null && object instanceof String && ((String) object).length() > 0;
+ }
+
+ /**
+ * This implementation of <code>nativeToJava</code> converts a platform
+ * specific representation of plain text to a java <code>String</code>.
+ *
+ * @param transferData
+ * the platform specific representation of the data to be
+ * converted
+ * @return a java <code>String</code> containing text if the conversion was
+ * successful; otherwise null
+ *
+ * @see Transfer#javaToNative
+ */
+ @Override
+ public Object nativeToJava(TransferData transferData) {
+ byte[] data = (byte[]) super.nativeToJava(transferData);
+ if (data == null) {
+ return null;
+ }
+ return new String(data);
+ }
+
+ @Override
+ protected String[] getTypeNames() {
+ return new String[] { TYPENAME };
+ }
+
+ @Override
+ protected int[] getTypeIds() {
+ return new int[] { TYPEID };
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/Transfer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/Transfer.java
new file mode 100644
index 0000000000..4ed963d9f0
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/Transfer.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.dnd;
+
+/**
+ * <code>Transfer</code> provides a mechanism for converting between a java
+ * representation of data and a platform specific representation of data and
+ * vice versa. It is used in data transfer operations such as drag and drop and
+ * clipboard copy/paste.
+ *
+ * <p>
+ * You should only need to become familiar with this class if you are
+ * implementing a Transfer subclass and you are unable to subclass the
+ * ByteArrayTransfer class.
+ * </p>
+ *
+ * @see ByteArrayTransfer
+ * @see <a href="http://www.eclipse.org/swt/snippets/#dnd">Drag and Drop
+ * snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * DNDExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ */
+public abstract class Transfer {
+
+ /**
+ * Returns a list of the platform specific data types that can be converted
+ * using this transfer agent.
+ *
+ * <p>
+ * Only the data type fields of the <code>TransferData</code> objects are
+ * filled in.
+ * </p>
+ *
+ * @return a list of the data types that can be converted using this
+ * transfer agent
+ */
+ abstract public TransferData[] getSupportedTypes();
+
+ /**
+ * Returns true if the <code>TransferData</code> data type can be converted
+ * using this transfer agent, or false otherwise (including if transferData
+ * is <code>null</code>).
+ *
+ * @param transferData
+ * a platform specific description of a data type; only the data
+ * type fields of the <code>TransferData</code> object need to be
+ * filled in
+ *
+ * @return true if the transferData data type can be converted using this
+ * transfer agent
+ */
+ abstract public boolean isSupportedType(TransferData transferData);
+
+ /**
+ * Returns the platform specific names of the data types that can be
+ * converted using this transfer agent.
+ *
+ * @return the platform specific names of the data types that can be
+ * converted using this transfer agent.
+ */
+ abstract protected String[] getTypeNames();
+
+ /**
+ * Returns the platform specific ids of the data types that can be converted
+ * using this transfer agent.
+ *
+ * @return the platform specific ids of the data types that can be converted
+ * using this transfer agent
+ */
+ abstract protected int[] getTypeIds();
+
+ /**
+ * Converts a java representation of data to a platform specific
+ * representation of the data.
+ *
+ * <p>
+ * On a successful conversion, the transferData.result field will be set as
+ * follows:
+ * <ul>
+ * <li>Windows: COM.S_OK
+ * <li>Motif: 1
+ * <li>GTK: 1
+ * <li>Photon: 1
+ * </ul>
+ * </p>
+ *
+ * <p>
+ * If this transfer agent is unable to perform the conversion, the
+ * transferData.result field will be set to a failure value as follows:
+ * <ul>
+ * <li>Windows: COM.DV_E_TYMED or COM.E_FAIL
+ * <li>Motif: 0
+ * <li>GTK: 0
+ * <li>Photon: 0
+ * </ul>
+ * </p>
+ *
+ * @param object
+ * a java representation of the data to be converted; the type of
+ * Object that is passed in is dependent on the
+ * <code>Transfer</code> subclass.
+ *
+ * @param transferData
+ * an empty TransferData object; this object will be filled in on
+ * return with the platform specific representation of the data
+ *
+ * @exception org.eclipse.swt.SWTException
+ * <ul>
+ * <li>ERROR_INVALID_DATA - if object does not contain data
+ * in a valid format or is <code>null</code></li>
+ * </ul>
+ */
+ abstract protected void javaToNative(Object object, TransferData transferData);
+
+ /**
+ * Converts a platform specific representation of data to a java
+ * representation.
+ *
+ * @param transferData
+ * the platform specific representation of the data to be
+ * converted
+ *
+ * @return a java representation of the converted data if the conversion was
+ * successful; otherwise null. If transferData is <code>null</code>
+ * then <code>null</code> is returned. The type of Object that is
+ * returned is dependent on the <code>Transfer</code> subclass.
+ */
+ abstract protected Object nativeToJava(TransferData transferData);
+
+ /**
+ * Registers a name for a data type and returns the associated unique
+ * identifier.
+ *
+ * <p>
+ * You may register the same type more than once, the same unique identifier
+ * will be returned if the type has been previously registered.
+ * </p>
+ *
+ * <p>
+ * Note: On windows, do <b>not</b> call this method with pre-defined
+ * Clipboard Format types such as CF_TEXT or CF_BITMAP because the
+ * pre-defined identifier will not be returned
+ * </p>
+ *
+ * @param formatName
+ * the name of a data type
+ *
+ * @return the unique identifier associated with this data type
+ */
+ public static int registerType(String formatName) {
+ return formatName.hashCode();
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TransferData.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TransferData.java
new file mode 100644
index 0000000000..cd59afd06a
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TransferData.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.dnd;
+
+/**
+ * The <code>TransferData</code> class is a platform specific data structure for
+ * describing the type and the contents of data being converted by a transfer
+ * agent.
+ *
+ * <p>
+ * As an application writer, you do not need to know the specifics of
+ * TransferData. TransferData instances are passed to a subclass of Transfer and
+ * the Transfer object manages the platform specific issues. You can ask a
+ * Transfer subclass if it can handle this data by calling
+ * Transfer.isSupportedType(transferData).
+ * </p>
+ *
+ * <p>
+ * You should only need to become familiar with the fields in this class if you
+ * are implementing a Transfer subclass and you are unable to subclass the
+ * ByteArrayTransfer class.
+ * </p>
+ *
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ */
+public class TransferData {
+ /**
+ * The type is a unique identifier of a system format or user defined
+ * format. (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 type;
+
+ // attributes specific to set/get
+ Object data;
+ String format;
+
+ /**
+ * The result field contains the result of converting a java data type into
+ * a platform specific value. (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>
+ * <p>
+ * The value of result is 1 if the conversion was successful. The value of
+ * result is 0 if the conversion failed.
+ * </p>
+ */
+ // int result;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("TransferData {type: ");//$NON-NLS-1$
+ sb.append(type);
+ sb.append(", format: ");//$NON-NLS-1$
+ sb.append(format);
+ sb.append(", data: ");//$NON-NLS-1$
+ sb.append(data);
+ sb.append("}"); //$NON-NLS-1$
+ return sb.toString();
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TreeDragSourceEffect.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TreeDragSourceEffect.java
new file mode 100644
index 0000000000..7a66bebb22
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TreeDragSourceEffect.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 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.dnd;
+
+import org.eclipse.swt.widgets.*;
+
+/**
+ * This class provides default implementations to display a source image
+ * when a drag is initiated from a <code>Tree</code>.
+ *
+ * <p>Classes that wish to provide their own source image for a <code>Tree</code> can
+ * extend <code>TreeDragSourceEffect</code> class and override the <code>TreeDragSourceEffect.dragStart</code>
+ * method and set the field <code>DragSourceEvent.image</code> with their own image.</p>
+ *
+ * Subclasses that override any methods of this class must call the corresponding
+ * <code>super</code> method to get the default drag under effect implementation.
+ *
+ * @see DragSourceEffect
+ * @see DragSourceEvent
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
+ *
+ * @since 3.3
+ */
+public class TreeDragSourceEffect extends DragSourceEffect {
+ /**
+ * Creates a new <code>TreeDragSourceEffect</code> to handle drag effect
+ * from the specified <code>Tree</code>.
+ *
+ * @param tree the <code>Tree</code> that the user clicks on to initiate the drag
+ */
+ public TreeDragSourceEffect(Tree tree) {
+ super(tree);
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TreeDropTargetEffect.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TreeDropTargetEffect.java
new file mode 100644
index 0000000000..d5eaaeb31a
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/TreeDropTargetEffect.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.dnd;
+
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * This class provides a default drag under effect (eg. select, insert, scroll
+ * and expand) when a drag occurs over a <code>Tree</code>.
+ *
+ * <p>
+ * Classes that wish to provide their own drag under effect for a
+ * <code>Tree</code> can extend the <code>TreeDropTargetEffect</code> class and
+ * override any applicable methods in <code>TreeDropTargetEffect</code> to
+ * display their own drag under effect.
+ * </p>
+ *
+ * Subclasses that override any methods of this class must call the
+ * corresponding <code>super</code> method to get the default drag under effect
+ * implementation.
+ *
+ * <p>
+ * The feedback value is either one of the FEEDBACK constants defined in class
+ * <code>DND</code> which is applicable to instances of this class, or it must
+ * be built by <em>bitwise OR</em>'ing together (that is, using the
+ * <code>int</code> "|" operator) two or more of those <code>DND</code> effect
+ * constants.
+ * </p>
+ * <p>
+ * <dl>
+ * <dt><b>Feedback:</b></dt>
+ * <dd>FEEDBACK_SELECT, FEEDBACK_INSERT_BEFORE, FEEDBACK_INSERT_AFTER,
+ * FEEDBACK_EXPAND, FEEDBACK_SCROLL</dd>
+ * </dl>
+ * </p>
+ * <p>
+ * Note: Only one of the styles FEEDBACK_SELECT, FEEDBACK_INSERT_BEFORE or
+ * FEEDBACK_INSERT_AFTER may be specified.
+ * </p>
+ *
+ * @see DropTargetAdapter
+ * @see DropTargetEvent
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ *
+ * @since 3.3
+ */
+public class TreeDropTargetEffect extends DropTargetEffect {
+ /**
+ * Creates a new <code>TreeDropTargetEffect</code> to handle the drag under
+ * effect on the specified <code>Tree</code>.
+ *
+ * @param tree
+ * the <code>Tree</code> over which the user positions the cursor
+ * to drop the data
+ */
+ public TreeDropTargetEffect(Tree tree) {
+ super(tree);
+ }
+
+ @Override
+ public void dragEnter(DropTargetEvent event) {
+ System.out.println("TreeDropTargetEffect.dragEnter: " + event);
+ super.dragEnter(event);
+ }
+
+ @Override
+ public void dragLeave(DropTargetEvent event) {
+ System.out.println("TreeDropTargetEffect.dragLeave: " + event);
+ super.dragLeave(event);
+ }
+
+ @Override
+ public void dragOver(DropTargetEvent event) {
+ System.out.println("TreeDropTargetEffect.dragOver: " + event);
+ Tree tree = (Tree) control;
+ //int effect = checkEffect(event.feedback);
+
+ TreeItem item = tree.getItem(tree.toControl(new Point(event.x, event.y)));
+
+ tree.highlightItem(item);
+ }
+
+ @Override
+ public void drop(DropTargetEvent event) {
+ System.out.println("TreeDropTargetEffect.drop: " + event);
+ super.drop(event);
+ }
+
+ @Override
+ public void dropAccept(DropTargetEvent event) {
+ System.out.println("TreeDropTargetEffect.dropAccept: " + event);
+ super.dropAccept(event);
+ }
+
+ @Override
+ public Widget getItem(int x, int y) {
+ //System.out.println("TreeDropTargetEffect.getItem: " + x + " " + y);
+ Tree tree = (Tree) control;
+ TreeItem item = tree.getItem(tree.toControl(new Point(x, y)));
+ //System.out.println("item: " + item);
+ return item;
+ }
+
+ private int checkEffect(int effect) {
+ // Some effects are mutually exclusive. Make sure that only one of the mutually exclusive effects has been specified.
+ if ((effect & DND.FEEDBACK_SELECT) != 0) {
+ effect = effect & ~DND.FEEDBACK_INSERT_AFTER & ~DND.FEEDBACK_INSERT_BEFORE;
+ }
+ if ((effect & DND.FEEDBACK_INSERT_BEFORE) != 0) {
+ effect = effect & ~DND.FEEDBACK_INSERT_AFTER;
+ }
+ return effect;
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/URLTransfer.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/URLTransfer.java
new file mode 100644
index 0000000000..589d3ec7c1
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/qt/org/eclipse/swt/dnd/URLTransfer.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 20007 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.dnd;
+
+/**
+ * The class <code>URLTransfer</code> provides a platform specific mechanism
+ * for converting text in URL format represented as a java <code>String</code>
+ * to a platform specific representation of the data and vice versa. The string
+ * must contain a fully specified url.
+ *
+ * <p>An example of a java <code>String</code> containing a URL is shown below:</p>
+ *
+ * <code><pre>
+ * String url = "http://www.eclipse.org";
+ * </code></pre>
+ *
+ * @see Transfer
+ * @since 3.4
+ */
+public class URLTransfer extends ByteArrayTransfer {
+
+private URLTransfer() {}
+
+/**
+ * Returns the singleton instance of the URLTransfer class.
+ *
+ * @return the singleton instance of the URLTransfer class
+ */
+public static URLTransfer getInstance () {
+ return null;
+}
+
+/**
+ * This implementation of <code>javaToNative</code> converts a URL
+ * represented by a java <code>String</code> to a platform specific representation.
+ *
+ * @param object a java <code>String</code> containing a URL
+ * @param transferData an empty <code>TransferData</code> object that will
+ * be filled in on return with the platform specific format of the data
+ *
+ * @see Transfer#nativeToJava
+ */
+public void javaToNative (Object object, TransferData transferData){
+}
+
+/**
+ * This implementation of <code>nativeToJava</code> converts a platform
+ * specific representation of a URL to a java <code>String</code>.
+ *
+ * @param transferData the platform specific representation of the data to be converted
+ * @return a java <code>String</code> containing a URL if the conversion was successful;
+ * otherwise null
+ *
+ * @see Transfer#javaToNative
+ */
+public Object nativeToJava(TransferData transferData){
+ return null;
+}
+
+protected int[] getTypeIds(){
+ return null;
+}
+
+protected String[] getTypeNames(){
+ return null;
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Color.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Color.java
new file mode 100644
index 0000000000..9d39595e17
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Color.java
@@ -0,0 +1,364 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Portion Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Nokia Corporation - Qt implementation
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.graphics;
+
+import com.trolltech.qt.gui.QColor;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+
+/**
+ * Instances of this class manage the operating system resources that implement
+ * SWT's RGB color model. To create a color you can either specify the
+ * individual color components as integers in the range 0 to 255 or provide an
+ * instance of an <code>RGB</code>.
+ * <p>
+ * Application code must explicitly invoke the <code>Color.dispose()</code>
+ * method to release the operating system resources managed by each instance
+ * when those instances are no longer required.
+ * </p>
+ *
+ * @see RGB
+ * @see Device#getSystemColor
+ */
+public final class Color extends Resource {
+
+ /**
+ * the handle to the OS color 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>
+ */
+ private QColor color;
+
+ /**
+ * Prevents uninitialized instances from being created outside the package.
+ */
+ Color() {
+ }
+
+ /**
+ * Constructs a new instance of this class given a device and the desired
+ * red, green and blue values expressed as ints in the range 0 to 255 (where
+ * 0 is black and 255 is full brightness). On limited color devices, the
+ * color instance created by this call may not have the same RGB values as
+ * the ones specified by the arguments. The RGB values on the returned
+ * instance will be the color values of the operating system color.
+ * <p>
+ * You must dispose the color when it is no longer required.
+ * </p>
+ *
+ * @param device
+ * the device on which to allocate the color
+ * @param red
+ * the amount of red in the color
+ * @param green
+ * the amount of green in the color
+ * @param blue
+ * the amount of blue in the color
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if device is null and there is
+ * no current device</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the red, green or blue
+ * argument is not between 0 and 255</li>
+ * </ul>
+ *
+ * @see #dispose
+ */
+ public Color(Device device, int red, int green, int blue) {
+ init(device, red, green, blue);
+ }
+
+ /**
+ * Constructs a new instance of this class given a device and an
+ * <code>RGB</code> describing the desired red, green and blue values. On
+ * limited color devices, the color instance created by this call may not
+ * have the same RGB values as the ones specified by the argument. The RGB
+ * values on the returned instance will be the color values of the operating
+ * system color.
+ * <p>
+ * You must dispose the color when it is no longer required.
+ * </p>
+ *
+ * @param device
+ * the device on which to allocate the color
+ * @param rgb
+ * the RGB values of the desired color
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if device is null and there is
+ * no current device</li>
+ * <li>ERROR_NULL_ARGUMENT - if the rgb argument is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the red, green or blue
+ * components of the argument are not between 0 and 255</li>
+ * </ul>
+ *
+ * @see #dispose
+ */
+ public Color(Device device, RGB rgb) {
+ if (rgb == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ init(device, rgb.red, rgb.green, rgb.blue);
+ }
+
+ /**
+ * Disposes of the operating system resources associated with this resource.
+ * Applications must dispose of all resources which they allocate.
+ */
+ @Override
+ public void dispose() {
+ if (device == null) {
+ return;
+ }
+ if (device.isDisposed()) {
+ return;
+ }
+ if (device.tracking) {
+ device.dispose_Object(this);
+ }
+ device = null;
+ color = null;
+ }
+
+ /**
+ * Compares the argument to the receiver, and returns true if they represent
+ * the <em>same</em> object using a class specific comparison.
+ *
+ * @param object
+ * the object to compare with this object
+ * @return <code>true</code> if the object is the same as this object and
+ * <code>false</code> otherwise
+ *
+ * @see #hashCode
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (!(object instanceof Color)) {
+ return false;
+ }
+ Color color = (Color) object;
+ if (isDisposed() || color.isDisposed()) {
+ return false;
+ }
+ return this.color.equals(color.color);
+ }
+
+ /**
+ * Returns the amount of blue in the color, from 0 to 255.
+ *
+ * @return the blue component of the color
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public int getBlue() {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return color.blue();
+ }
+
+ /**
+ * Returns the amount of green in the color, from 0 to 255.
+ *
+ * @return the green component of the color
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public int getGreen() {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return color.green();
+ }
+
+ /**
+ * Returns the amount of red in the color, from 0 to 255.
+ *
+ * @return the red component of the color
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public int getRed() {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return color.red();
+ }
+
+ /**
+ * Returns an <code>RGB</code> representing the receiver.
+ *
+ * @return the RGB for the color
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public RGB getRGB() {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return new RGB(color.red(), color.green(), color.blue());
+ }
+
+ /**
+ * Returns an integer hash code for the receiver. Any two objects that
+ * return <code>true</code> when passed to <code>equals</code> must return
+ * the same value for this method.
+ *
+ * @return the receiver's hash
+ *
+ * @see #equals
+ */
+ @Override
+ public int hashCode() {
+ if (isDisposed()) {
+ return 0;
+ }
+ return color.hashCode();
+ }
+
+ /**
+ * Invokes platform specific functionality to allocate a new color.
+ * <p>
+ * <b>IMPORTANT:</b> This method is <em>not</em> part of the public API for
+ * <code>Color</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 red
+ * the red component
+ * @param green
+ * the green component
+ * @param blue
+ * the blue component
+ *
+ * @private
+ */
+
+ void init(Device device, int red, int green, int blue) {
+
+ if (device == null) {
+ device = Device.getDevice();
+ }
+ if (device == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ this.device = device;
+
+ if (red > 255 || red < 0 || green > 255 || green < 0 || blue > 255 || blue < 0) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ // Keep this after dealing with all exceptions!
+ if (device.tracking) {
+ device.new_Object(this);
+ }
+ color = new QColor(red, green, blue);
+ }
+
+ public QColor getColor() {
+ if (color == null) {
+ color = new QColor(getRed(), getGreen(), getBlue());
+ }
+ return color;
+ }
+
+ /**
+ * Returns <code>true</code> if the color has been disposed, and
+ * <code>false</code> otherwise.
+ * <p>
+ * This method gets the dispose state for the color. When a color has been
+ * disposed, it is an error to invoke any other method using the color.
+ *
+ * @return <code>true</code> when the color is disposed and
+ * <code>false</code> otherwise
+ */
+ @Override
+ public boolean isDisposed() {
+ return color == null;
+ }
+
+ /**
+ * Returns a string containing a concise, human-readable description of the
+ * receiver.
+ *
+ * @return a string representation of the receiver
+ */
+ @Override
+ public String toString() {
+ if (isDisposed()) {
+ return "Color {*DISPOSED*}"; //$NON-NLS-1$
+ }
+ return "Color {" + getRed() + ", " + getGreen() + ", " + getBlue() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ }
+
+ /**
+ * Invokes platform specific functionality to allocate a new color.
+ * <p>
+ * <b>IMPORTANT:</b> This method is <em>not</em> part of the public API for
+ * <code>Color</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 device
+ * the device on which to allocate the color
+ * @param handle
+ * the handle for the color
+ * @return a new color object containing the specified device and handle
+ */
+ public static Color qt_new(Device device, int rgb) {
+ Color color = new Color();
+ color.device = device;
+ color.color = new QColor(rgb);
+ return color;
+ }
+
+ public static Color qt_new(Device device, QColor qColor) {
+ Color color = new Color(device, qColor.red(), qColor.green(), qColor.blue());
+ color.color = qColor;
+ return color;
+ }
+
+ public int getPixel() {
+ return getColor().value();
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Cursor.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Cursor.java
new file mode 100644
index 0000000000..6803a4d1a8
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Cursor.java
@@ -0,0 +1,445 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.graphics;
+
+import com.trolltech.qt.core.Qt.CursorShape;
+import com.trolltech.qt.gui.QCursor;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTError;
+
+/**
+ * Instances of this class manage operating system resources that specify the
+ * appearance of the on-screen pointer. To create a cursor you specify the
+ * device and either a simple cursor style describing one of the standard
+ * operating system provided cursors or the image and mask data for the desired
+ * appearance.
+ * <p>
+ * Application code must explicitly invoke the <code>Cursor.dispose()</code>
+ * method to release the operating system resources managed by each instance
+ * when those instances are no longer required.
+ * </p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>
+ * CURSOR_ARROW, CURSOR_WAIT, CURSOR_CROSS, CURSOR_APPSTARTING, CURSOR_HELP,
+ * CURSOR_SIZEALL, CURSOR_SIZENESW, CURSOR_SIZENS, CURSOR_SIZENWSE,
+ * CURSOR_SIZEWE, CURSOR_SIZEN, CURSOR_SIZES, CURSOR_SIZEE, CURSOR_SIZEW,
+ * CURSOR_SIZENE, CURSOR_SIZESE, CURSOR_SIZESW, CURSOR_SIZENW, CURSOR_UPARROW,
+ * CURSOR_IBEAM, CURSOR_NO, CURSOR_HAND</dd>
+ * </dl>
+ * <p>
+ * Note: Only one of the above styles may be specified.
+ * </p>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#cursor">Cursor
+ * snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ */
+
+public final class Cursor extends Resource {
+
+ /**
+ * the handle to the OS cursor 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 QCursor cursor;
+
+ boolean isIcon;
+
+ /**
+ * Prevents uninitialized instances from being created outside the package.
+ */
+ Cursor(Device device) {
+ super(device);
+ }
+
+ /**
+ * Constructs a new cursor given a device and a style constant describing
+ * the desired cursor appearance.
+ * <p>
+ * You must dispose the cursor when it is no longer required.
+ * </p>
+ *
+ * @param device
+ * the device on which to allocate the cursor
+ * @param style
+ * the style of cursor to allocate
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if device is null and there is
+ * no current device</li>
+ * <li>ERROR_INVALID_ARGUMENT - when an unknown style is
+ * specified</li>
+ * </ul>
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_NO_HANDLES - if a handle could not be obtained
+ * for cursor creation</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
+ */
+ public Cursor(Device device, int style) {
+ super(device);
+ CursorShape cursorShape = null;
+ switch (style) {
+ case SWT.CURSOR_HAND:
+ cursorShape = CursorShape.PointingHandCursor;
+ break;
+ case SWT.CURSOR_ARROW:
+ cursorShape = CursorShape.ArrowCursor;
+ break;
+ case SWT.CURSOR_WAIT:
+ cursorShape = CursorShape.WaitCursor;
+ break;
+ case SWT.CURSOR_CROSS:
+ cursorShape = CursorShape.CrossCursor;
+ break;
+ case SWT.CURSOR_APPSTARTING:
+ cursorShape = CursorShape.BusyCursor;
+ break;
+ case SWT.CURSOR_HELP:
+ cursorShape = CursorShape.WhatsThisCursor;
+ break;
+ case SWT.CURSOR_SIZEALL:
+ cursorShape = CursorShape.SizeAllCursor;
+ break;
+ case SWT.CURSOR_SIZENESW:
+ cursorShape = CursorShape.SizeBDiagCursor;
+ break;
+ case SWT.CURSOR_SIZENS:
+ cursorShape = CursorShape.SizeVerCursor;
+ break;
+ case SWT.CURSOR_SIZENWSE:
+ cursorShape = CursorShape.SizeFDiagCursor;
+ break;
+ case SWT.CURSOR_SIZEWE:
+ cursorShape = CursorShape.SizeHorCursor;
+ break;
+ case SWT.CURSOR_SIZEN:
+ cursorShape = CursorShape.SizeVerCursor;
+ break;
+ case SWT.CURSOR_SIZES:
+ cursorShape = CursorShape.SizeVerCursor;
+ break;
+ case SWT.CURSOR_SIZEE:
+ cursorShape = CursorShape.SizeHorCursor;
+ break;
+ case SWT.CURSOR_SIZEW:
+ cursorShape = CursorShape.SizeHorCursor;
+ break;
+ case SWT.CURSOR_SIZENE:
+ cursorShape = CursorShape.SizeBDiagCursor;
+ break;
+ case SWT.CURSOR_SIZESE:
+ cursorShape = CursorShape.SizeBDiagCursor;
+ break;
+ case SWT.CURSOR_SIZESW:
+ cursorShape = CursorShape.SizeFDiagCursor;
+ break;
+ case SWT.CURSOR_SIZENW:
+ cursorShape = CursorShape.SizeFDiagCursor;
+ break;
+ case SWT.CURSOR_UPARROW:
+ cursorShape = CursorShape.UpArrowCursor;
+ break;
+ case SWT.CURSOR_IBEAM:
+ cursorShape = CursorShape.IBeamCursor;
+ break;
+ case SWT.CURSOR_NO:
+ cursorShape = CursorShape.ForbiddenCursor;
+
+ break;
+ default:
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ cursor = new QCursor(cursorShape);
+ init();
+ }
+
+ /**
+ * Constructs a new cursor given a device, image and mask data describing
+ * the desired cursor appearance, and the x and y coordinates of the
+ * <em>hotspot</em> (that is, the point within the area covered by the
+ * cursor which is considered to be where the on-screen pointer is
+ * "pointing").
+ * <p>
+ * The mask data is allowed to be null, but in this case the source must be
+ * an ImageData representing an icon that specifies both color data and mask
+ * data.
+ * <p>
+ * You must dispose the cursor when it is no longer required.
+ * </p>
+ *
+ * @param device
+ * the device on which to allocate the cursor
+ * @param source
+ * the color data for the cursor
+ * @param mask
+ * the mask data for the cursor (or null)
+ * @param hotspotX
+ * the x coordinate of the cursor's hotspot
+ * @param hotspotY
+ * the y coordinate of the cursor's hotspot
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if device is null and there is
+ * no current device</li>
+ * <li>ERROR_NULL_ARGUMENT - if the source is null</li>
+ * <li>ERROR_NULL_ARGUMENT - if the mask is null and the
+ * source does not have a mask</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the source and the mask
+ * are not the same size, or if the hotspot is outside the
+ * bounds of the image</li>
+ * </ul>
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_NO_HANDLES - if a handle could not be obtained
+ * for cursor creation</li>
+ * </ul>
+ */
+ public Cursor(Device device, ImageData source, ImageData mask, int hotspotX, int hotspotY) {
+ this(device, SWT.CURSOR_ARROW);
+ //TODO
+ // super(device);
+ // if (source == null) {
+ // SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ // }
+ // if (mask == null) {
+ // if (source.getTransparencyType() != SWT.TRANSPARENCY_MASK) {
+ // SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ // }
+ // mask = source.getTransparencyMask();
+ // }
+ // /* Check the bounds. Mask must be the same size as source */
+ // if (mask.width != source.width || mask.height != source.height) {
+ // SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ // }
+ // /* Check the hotspots */
+ // if (hotspotX >= source.width || hotspotX < 0 || hotspotY >= source.height || hotspotY < 0) {
+ // SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ // }
+ // /* Convert depth to 1 */
+ // mask = ImageData.convertMask(mask);
+ // source = ImageData.convertMask(source);
+ //
+ // /* Make sure source and mask scanline pad is 2 */
+ // byte[] sourceData = ImageData.convertPad(source.data, source.width, source.height, source.depth,
+ // source.scanlinePad, 2);
+ // byte[] maskData = ImageData.convertPad(mask.data, mask.width, mask.height, mask.depth, mask.scanlinePad, 2);
+
+ /* Create the cursor */
+ // TODO
+ // cursor = new QCursor(mask.)
+ // int /* long */hInst = OS.GetModuleHandle(null);
+ // if (OS.IsWinCE) {
+ // SWT.error(SWT.ERROR_NOT_IMPLEMENTED);
+ // }
+ // handle = OS.CreateCursor(hInst, hotspotX, hotspotY, source.width, source.height, sourceData, maskData);
+ // if (handle == 0) {
+ // SWT.error(SWT.ERROR_NO_HANDLES);
+ // }
+ //init();
+ }
+
+ /**
+ * Constructs a new cursor given a device, image data describing the desired
+ * cursor appearance, and the x and y coordinates of the <em>hotspot</em>
+ * (that is, the point within the area covered by the cursor which is
+ * considered to be where the on-screen pointer is "pointing").
+ * <p>
+ * You must dispose the cursor when it is no longer required.
+ * </p>
+ *
+ * @param device
+ * the device on which to allocate the cursor
+ * @param source
+ * the image data for the cursor
+ * @param hotspotX
+ * the x coordinate of the cursor's hotspot
+ * @param hotspotY
+ * the y coordinate of the cursor's hotspot
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if device is null and there is
+ * no current device</li>
+ * <li>ERROR_NULL_ARGUMENT - if the image is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the hotspot is outside the
+ * bounds of the image</li>
+ * </ul>
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_NO_HANDLES - if a handle could not be obtained
+ * for cursor creation</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+ public Cursor(Device device, ImageData source, int hotspotX, int hotspotY) {
+ this(device, SWT.CURSOR_ARROW);
+ // if (source == null) {
+ // SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ // }
+ // /* Check the hotspots */
+ // if (hotspotX >= source.width || hotspotX < 0 || hotspotY >= source.height || hotspotY < 0) {
+ // SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ // }
+
+ // ImageData mask = source.getTransparencyMask();
+ // int /* long */[] result = new int[2]; // TODO = Image.init(this.device, null, source, mask);
+ // int /* long */hBitmap = result[0];
+ // int /* long */hMask = result[1];
+ // /* Create the icon */
+ // ICONINFO info = new ICONINFO();
+ // info.fIcon = false;
+ // info.hbmColor = hBitmap;
+ // info.hbmMask = hMask;
+ // info.xHotspot = hotspotX;
+ // info.yHotspot = hotspotY;
+ //TODO
+ // handle = OS.CreateIconIndirect(info);
+ // if (handle == 0) {
+ // SWT.error(SWT.ERROR_NO_HANDLES);
+ // }
+ // OS.DeleteObject(hBitmap);
+ // OS.DeleteObject(hMask);
+ //isIcon = true;
+ // init();
+ }
+
+ @Override
+ void destroy() {
+ cursor = null;
+ }
+
+ /**
+ * Compares the argument to the receiver, and returns true if they represent
+ * the <em>same</em> object using a class specific comparison.
+ *
+ * @param object
+ * the object to compare with this object
+ * @return <code>true</code> if the object is the same as this object and
+ * <code>false</code> otherwise
+ *
+ * @see #hashCode
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (!(object instanceof Cursor)) {
+ return false;
+ }
+ Cursor cursor = (Cursor) object;
+ return device == cursor.device && this.cursor == cursor.cursor;
+ }
+
+ /**
+ * Returns an integer hash code for the receiver. Any two objects that
+ * return <code>true</code> when passed to <code>equals</code> must return
+ * the same value for this method.
+ *
+ * @return the receiver's hash
+ *
+ * @see #equals
+ */
+ @Override
+ public int hashCode() {
+ return cursor.hashCode();
+ }
+
+ /**
+ * Returns <code>true</code> if the cursor has been disposed, and
+ * <code>false</code> otherwise.
+ * <p>
+ * This method gets the dispose state for the cursor. When a cursor has been
+ * disposed, it is an error to invoke any other method using the cursor.
+ *
+ * @return <code>true</code> when the cursor is disposed and
+ * <code>false</code> otherwise
+ */
+ @Override
+ public boolean isDisposed() {
+ return cursor == null;
+ }
+
+ /**
+ * Returns a string containing a concise, human-readable description of the
+ * receiver.
+ *
+ * @return a string representation of the receiver
+ */
+ @Override
+ public String toString() {
+ if (isDisposed()) {
+ return "Cursor {*DISPOSED*}"; //$NON-NLS-1$
+ }
+ return "Cursor {" + cursor + "}"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Invokes platform specific functionality to allocate a new cursor.
+ * <p>
+ * <b>IMPORTANT:</b> This method is <em>not</em> part of the public API for
+ * <code>Cursor</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 device
+ * the device on which to allocate the color
+ * @param handle
+ * the handle for the cursor
+ * @return a new cursor object containing the specified device and handle
+ */
+ public static Cursor win32_new(Device device, int handle) {
+ Cursor cursor = new Cursor(device);
+ // TODO
+ // cursor.cursor = handle;
+ return cursor;
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Device.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Device.java
new file mode 100644
index 0000000000..99a3dcb47a
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Device.java
@@ -0,0 +1,920 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.graphics;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.trolltech.qt.gui.QApplication;
+import com.trolltech.qt.gui.QColor;
+import com.trolltech.qt.gui.QFontDatabase;
+import com.trolltech.qt.gui.QPaintDeviceInterface;
+import com.trolltech.qt.gui.QPalette;
+import com.trolltech.qt.gui.QPalette.ColorGroup;
+import com.trolltech.qt.gui.QPalette.ColorRole;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+
+/**
+ * This class is the abstract superclass of all device objects, such as the
+ * Display device and the Printer device. Devices can have a graphics context
+ * (GC) created for them, and they can be drawn on by sending messages to the
+ * associated GC.
+ *
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ */
+public abstract class Device implements Drawable {
+
+ /* Debugging */
+ public static boolean DEBUG;
+ private boolean debug = DEBUG;
+ boolean tracking = DEBUG;
+ private Error[] errors;
+ private Object[] objects;
+ private Object trackingLock;
+
+ /* System Font */
+ Font systemFont;
+ private QColor COLOR_LIST_BACKGROUND;
+ private QColor COLOR_LIST_FOREGROUND;
+ private QColor COLOR_LIST_SELECTION;
+ private QColor COLOR_LIST_SELECTION_TEXT;
+ private QColor COLOR_TITLE_BACKGROUND;
+ private QColor COLOR_TITLE_BACKGROUND_GRADIENT;
+ private QColor COLOR_TITLE_FOREGROUND;
+ private QColor COLOR_TITLE_INACTIVE_BACKGROUND;
+ private QColor COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT;
+ private QColor COLOR_TITLE_INACTIVE_FOREGROUND;
+ private QColor COLOR_WIDGET_BACKGROUND;
+ private QColor COLOR_WIDGET_BORDER;
+ private QColor COLOR_WIDGET_DARK_SHADOW;
+ private QColor COLOR_WIDGET_FOREGROUND;
+ private QColor COLOR_WIDGET_HIGHLIGHT_SHADOW;
+ private QColor COLOR_WIDGET_LIGHT_SHADOW;
+ private QColor COLOR_WIDGET_NORMAL_SHADOW;
+ private QColor COLOR_INFO_FOREGROUND;
+ private QColor COLOR_INFO_BACKGROUND;
+
+ private boolean disposed;
+ private QPaintDeviceInterface paintDevice;
+
+ /*
+ * TEMPORARY CODE. When a graphics object is created and the device
+ * parameter is null, the current Display is used. This presents a problem
+ * because SWT graphics does not reference classes in SWT widgets. The
+ * correct fix is to remove this feature. Unfortunately, too many
+ * application programs rely on this feature.
+ */
+ protected static Device CurrentDevice;
+ protected static Runnable DeviceFinder;
+ static {
+ try {
+ Class.forName("org.eclipse.swt.widgets.Display"); //$NON-NLS-1$
+ } catch (ClassNotFoundException e) {
+ }
+ }
+
+ /*
+ * TEMPORARY CODE.
+ */
+ static synchronized Device getDevice() {
+ if (DeviceFinder != null) {
+ DeviceFinder.run();
+ }
+ Device device = CurrentDevice;
+ CurrentDevice = null;
+ return device;
+ }
+
+ /**
+ * Constructs a new instance of this class.
+ * <p>
+ * You must dispose the device when it is no longer required.
+ * </p>
+ *
+ * @see #create
+ * @see #init
+ *
+ * @since 3.1
+ */
+ public Device() {
+ this(null);
+ }
+
+ /**
+ * Constructs a new instance of this class.
+ * <p>
+ * You must dispose the device when it is no longer required.
+ * </p>
+ *
+ * @param data
+ * the DeviceData which describes the receiver
+ *
+ * @see #create
+ * @see #init
+ * @see DeviceData
+ */
+ public Device(DeviceData data) {
+ synchronized (Device.class) {
+ if (data != null) {
+ debug = data.debug;
+ tracking = data.tracking;
+ }
+ if (tracking) {
+ errors = new Error[128];
+ objects = new Object[128];
+ trackingLock = new Object();
+ }
+ create(data);
+ init();
+ }
+ }
+
+ protected void setPaintDevice(QPaintDeviceInterface paintDevice) {
+ this.paintDevice = paintDevice;
+ }
+
+ /**
+ * 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 device implementors to enforce the standard
+ * SWT invariants.
+ * <p>
+ * Currently, it is an error to invoke any method (other than
+ * <code>isDisposed()</code> and <code>dispose()</code>) on a device that
+ * has had its <code>dispose()</code> method called.
+ * </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>
+ * </ul>
+ */
+ protected void checkDevice() {
+ if (disposed) {
+ SWT.error(SWT.ERROR_DEVICE_DISPOSED);
+ }
+ }
+
+ /**
+ * 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>
+ * <p>
+ * Subclasses are supposed to reimplement this method and not call the
+ * <code>super</code> implementation.
+ * </p>
+ *
+ * @param data
+ * the DeviceData which describes the receiver
+ *
+ * @see #init
+ */
+ protected void create(DeviceData data) {
+ }
+
+ /**
+ * 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>
+ * <p>
+ * Subclasses are supposed to reimplement this method and not call the
+ * <code>super</code> implementation.
+ * </p>
+ *
+ * @see #dispose
+ * @see #release
+ */
+ protected void destroy() {
+ }
+
+ /**
+ * Disposes of the operating system resources associated with the receiver.
+ * After this method has been invoked, the receiver will answer
+ * <code>true</code> when sent the message <code>isDisposed()</code>.
+ *
+ * @see #release
+ * @see #destroy
+ * @see #checkDevice
+ */
+ public void dispose() {
+ synchronized (Device.class) {
+ if (isDisposed()) {
+ return;
+ }
+ checkDevice();
+ release();
+ destroy();
+ disposed = true;
+ if (tracking) {
+ synchronized (trackingLock) {
+ printErrors();
+ objects = null;
+ errors = null;
+ trackingLock = null;
+ }
+ }
+ }
+ }
+
+ void dispose_Object(Object object) {
+ synchronized (trackingLock) {
+ for (int i = 0; i < objects.length; i++) {
+ if (objects[i] == object) {
+ objects[i] = null;
+ errors[i] = null;
+ return;
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns a rectangle describing the receiver's size and location.
+ *
+ * @return the bounding rectangle
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public Rectangle getBounds() {
+ checkDevice();
+ return new Rectangle(0, 0, paintDevice.width(), paintDevice.height());
+ }
+
+ /**
+ * Returns a <code>DeviceData</code> based on the receiver. Modifications
+ * made to this <code>DeviceData</code> will not affect the receiver.
+ *
+ * @return a <code>DeviceData</code> containing the device's data and
+ * attributes
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see DeviceData
+ */
+ public DeviceData getDeviceData() {
+ checkDevice();
+ DeviceData data = new DeviceData();
+ data.debug = debug;
+ data.tracking = tracking;
+ if (tracking) {
+ synchronized (trackingLock) {
+ int count = 0, length = objects.length;
+ for (int i = 0; i < length; i++) {
+ if (objects[i] != null) {
+ count++;
+ }
+ }
+ int index = 0;
+ data.objects = new Object[count];
+ data.errors = new Error[count];
+ for (int i = 0; i < length; i++) {
+ if (objects[i] != null) {
+ data.objects[index] = objects[i];
+ data.errors[index] = errors[i];
+ index++;
+ }
+ }
+ }
+ } else {
+ data.objects = new Object[0];
+ data.errors = new Error[0];
+ }
+ return data;
+ }
+
+ /**
+ * 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_DEVICE_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see #getBounds
+ */
+ public Rectangle getClientArea() {
+ return getBounds();
+ }
+
+ /**
+ * Returns the bit depth of the screen, which is the number of bits it takes
+ * to represent the number of unique colors that the screen is currently
+ * capable of displaying. This number will typically be one of 1, 8, 15, 16,
+ * 24 or 32.
+ *
+ * @return the depth of the screen
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public int getDepth() {
+ checkDevice();
+ return paintDevice.depth();
+ }
+
+ /**
+ * Returns a point whose x coordinate is the horizontal dots per inch of the
+ * display, and whose y coordinate is the vertical dots per inch of the
+ * display.
+ *
+ * @return the horizontal and vertical DPI
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public Point getDPI() {
+ checkDevice();
+ return new Point(paintDevice.physicalDpiX(), paintDevice.physicalDpiY());
+ }
+
+ /**
+ * Returns <code>FontData</code> objects which describe the fonts that match
+ * the given arguments. If the <code>faceName</code> is null, all fonts will
+ * be returned.
+ *
+ * @param faceName
+ * the name of the font to look for, or null
+ * @param scalable
+ * if true only scalable fonts are returned, otherwise only
+ * non-scalable fonts are returned.
+ * @return the matching font data
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public FontData[] getFontList(String faceName, boolean scalable) {
+ checkDevice();
+ QFontDatabase qFontDatabase = null;
+ qFontDatabase = new QFontDatabase();
+ String fontFamilies[] = qFontDatabase.families().toArray(new String[0]);
+ // for storing FontData arrays
+ List<FontData> fontData = new ArrayList<FontData>();
+
+ for (int i = 0; i < fontFamilies.length; i++) {
+ String family = null;
+ if (faceName == null) {
+ family = fontFamilies[i];
+ } else {
+ if (faceName.equals(fontFamilies[i])) {
+ family = fontFamilies[i];
+ } else {
+ continue;
+ }
+ }
+ getFontList(fontData, qFontDatabase, family, scalable);
+ if (faceName != null) {
+ break;
+ }
+ }
+
+ qFontDatabase.dispose(); //TODO_DISPOSE (called many times)
+ qFontDatabase = null;
+
+ if (fontData.size() > 0) {
+ FontData[] result = new FontData[fontData.size()];
+ int size = fontData.size();
+ for (int i = 0; i < size; ++i) {
+ result[i] = fontData.get(i);
+ }
+ return result;
+ } else {
+ return new FontData[0];
+ }
+ }
+
+ private void getFontList(List<FontData> fontData, QFontDatabase qFontDatabase, String family, boolean onlyScalable) {
+ String nativeStyles[] = qFontDatabase.styles(family).toArray(new String[0]);
+ int prevStyle = -1;
+ int i = 0;
+ // Go trough each native style of the font family, map them to SWT
+ // styles
+ // and create a new FontData for each newly found SWT style of the
+ // family.
+ // Still, it may be possible that there are no native styles for a
+ // family,
+ // in which case we add a single FontData with default SWT style:
+ // NORMAL.
+ // In addition we go trough all heights of non scalable font families,
+ // creating a new FontData for all heights of all native styles.
+ do {
+ String nativeStyle = nativeStyles.length > 0 ? nativeStyles[i] : null;
+ boolean isScalable = qFontDatabase.isScalable(family, nativeStyle);
+ int style = SWT.NORMAL;
+ if (qFontDatabase.bold(family, nativeStyle)) {
+ style |= SWT.BOLD;
+ }
+ if (qFontDatabase.italic(family, nativeStyle)) {
+ style |= SWT.ITALIC;
+ }
+ if (style != prevStyle) {
+ prevStyle = style;
+ int[] heights = null;
+ int j = 0;
+ if (onlyScalable && isScalable) {
+ heights = new int[1];
+ heights[0] = FontData.FONT_DEF_HEIGHT;
+ } else if (!onlyScalable && !isScalable) {
+ List<Integer> pointSizes = null;
+ if (nativeStyle == null) {
+ pointSizes = qFontDatabase.pointSizes(family);
+ } else {
+ pointSizes = qFontDatabase.pointSizes(family, nativeStyle);
+ }
+ heights = new int[pointSizes.size()];
+ for (int x = 0; x < pointSizes.size(); x++) {
+ heights[x] = pointSizes.get(x);
+ }
+ }
+ if (heights != null) {
+ do {
+ FontData fd = new FontData(family, heights[j], style);
+ fontData.add(fd);
+ j++;
+ } while (!onlyScalable && !isScalable && j < heights.length);
+ }
+ }
+ i++;
+ } while (i < nativeStyles.length);
+ }
+
+ /**
+ * 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 freed because it was
+ * allocated by the system, not the application.
+ *
+ * @param id
+ * the color constant
+ * @return the matching color
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see SWT
+ */
+ public Color getSystemColor(int id) {
+ checkDevice();
+ int pixel = 0x00000000;
+ switch (id) {
+ case SWT.COLOR_WHITE:
+ return Color.qt_new(this, QColor.white);
+ case SWT.COLOR_BLACK:
+ return Color.qt_new(this, QColor.black);
+ case SWT.COLOR_RED:
+ return Color.qt_new(this, QColor.red);
+ case SWT.COLOR_DARK_RED:
+ return Color.qt_new(this, QColor.darkRed);
+ case SWT.COLOR_GREEN:
+ return Color.qt_new(this, QColor.green);
+ case SWT.COLOR_DARK_GREEN:
+ return Color.qt_new(this, QColor.darkGreen);
+ case SWT.COLOR_YELLOW:
+ return Color.qt_new(this, QColor.yellow);
+ case SWT.COLOR_DARK_YELLOW:
+ return Color.qt_new(this, QColor.darkYellow);
+ case SWT.COLOR_BLUE:
+ return Color.qt_new(this, QColor.blue);
+ case SWT.COLOR_DARK_BLUE:
+ return Color.qt_new(this, QColor.darkBlue);
+ case SWT.COLOR_MAGENTA:
+ return Color.qt_new(this, QColor.magenta);
+ case SWT.COLOR_DARK_MAGENTA:
+ return Color.qt_new(this, QColor.magenta);
+ case SWT.COLOR_CYAN:
+ return Color.qt_new(this, QColor.cyan);
+ case SWT.COLOR_DARK_CYAN:
+ return Color.qt_new(this, QColor.darkCyan);
+ case SWT.COLOR_GRAY:
+ return Color.qt_new(this, QColor.gray);
+ case SWT.COLOR_DARK_GRAY:
+ return Color.qt_new(this, QColor.darkGray);
+ case SWT.COLOR_LIST_BACKGROUND:
+ return Color.qt_new(this, COLOR_LIST_BACKGROUND);
+ case SWT.COLOR_LIST_FOREGROUND:
+ return Color.qt_new(this, COLOR_LIST_FOREGROUND);
+ case SWT.COLOR_LIST_SELECTION:
+ return Color.qt_new(this, COLOR_LIST_SELECTION);
+ case SWT.COLOR_LIST_SELECTION_TEXT:
+ return Color.qt_new(this, COLOR_LIST_SELECTION_TEXT);
+ case SWT.COLOR_TITLE_BACKGROUND:
+ return Color.qt_new(this, COLOR_TITLE_BACKGROUND);
+ case SWT.COLOR_TITLE_BACKGROUND_GRADIENT:
+ return Color.qt_new(this, COLOR_TITLE_BACKGROUND_GRADIENT);
+ case SWT.COLOR_TITLE_FOREGROUND:
+ return Color.qt_new(this, COLOR_TITLE_FOREGROUND);
+ case SWT.COLOR_TITLE_INACTIVE_BACKGROUND:
+ return Color.qt_new(this, COLOR_TITLE_INACTIVE_BACKGROUND);
+ case SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT:
+ return Color.qt_new(this, COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT);
+ case SWT.COLOR_TITLE_INACTIVE_FOREGROUND:
+ return Color.qt_new(this, COLOR_TITLE_INACTIVE_FOREGROUND);
+ case SWT.COLOR_WIDGET_BACKGROUND:
+ return Color.qt_new(this, COLOR_WIDGET_BACKGROUND);
+ case SWT.COLOR_WIDGET_BORDER:
+ return Color.qt_new(this, COLOR_WIDGET_BORDER);
+ case SWT.COLOR_WIDGET_DARK_SHADOW:
+ return Color.qt_new(this, COLOR_WIDGET_DARK_SHADOW);
+ case SWT.COLOR_WIDGET_FOREGROUND:
+ return Color.qt_new(this, COLOR_WIDGET_FOREGROUND);
+ case SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW:
+ return Color.qt_new(this, COLOR_WIDGET_HIGHLIGHT_SHADOW);
+ case SWT.COLOR_WIDGET_LIGHT_SHADOW:
+ return Color.qt_new(this, COLOR_WIDGET_LIGHT_SHADOW);
+ case SWT.COLOR_WIDGET_NORMAL_SHADOW:
+ return Color.qt_new(this, COLOR_WIDGET_NORMAL_SHADOW);
+ case SWT.COLOR_INFO_FOREGROUND:
+ return Color.qt_new(this, COLOR_INFO_FOREGROUND);
+ case SWT.COLOR_INFO_BACKGROUND:
+ return Color.qt_new(this, COLOR_INFO_BACKGROUND);
+ }
+ return Color.qt_new(this, pixel);
+ }
+
+ /**
+ * Returns a reasonable font for applications to use. On some platforms,
+ * this will match the "default font" or "system font" if such can be found.
+ * This font should not be freed because it was allocated by the system, not
+ * the application.
+ * <p>
+ * Typically, applications which want the default look should simply not set
+ * the font on the widgets they create. Widgets are always created with the
+ * correct default font for the class of user-interface component they
+ * represent.
+ * </p>
+ *
+ * @return a font
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public Font getSystemFont() {
+ checkDevice();
+ return Font.qt_new(this, QApplication.font());
+ }
+
+ /**
+ * Returns <code>true</code> if the underlying window system prints out
+ * warning messages on the console, and <code>setWarnings</code> had
+ * previously been called with <code>true</code>.
+ *
+ * @return <code>true</code>if warnings are being handled, and
+ * <code>false</code> otherwise
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public boolean getWarnings() {
+ checkDevice();
+ return false;
+ }
+
+ /**
+ * Initializes any internal resources needed by the device.
+ * <p>
+ * This method is called after <code>create</code>.
+ * </p>
+ * <p>
+ * If subclasses reimplement this method, they must call the
+ * <code>super</code> implementation.
+ * </p>
+ *
+ * @see #create
+ */
+ protected void init() {
+ /* Initialize the system font slot */
+ systemFont = getSystemFont();
+ QPalette palette = QApplication.style().standardPalette();
+ try {
+ // Mapping colors from the QPalette to SWT colors. Not all
+ // colors are 100% right. Use snippet 235 and 235_1 to get
+ // all colors displayed.
+
+ // Info
+ COLOR_INFO_FOREGROUND = palette.color(ColorGroup.Active, ColorRole.ToolTipText);
+ COLOR_INFO_BACKGROUND = palette.color(ColorGroup.Active, ColorRole.ToolTipBase);
+
+ // List
+ COLOR_LIST_BACKGROUND = palette.color(ColorGroup.Active, ColorRole.Base);
+ COLOR_LIST_FOREGROUND = palette.color(ColorGroup.Active, ColorRole.Text);
+ COLOR_LIST_SELECTION = palette.color(ColorGroup.Active, ColorRole.Highlight);
+ COLOR_LIST_SELECTION_TEXT = palette.color(ColorGroup.Active, ColorRole.HighlightedText);
+
+ // Title
+ COLOR_TITLE_BACKGROUND = new QColor(0, 84, 227); // palette.color(ColorGroup.Active, ColorRole.Highlight);
+ // TODO The required blue/grey does not exist in QPalette. Using grey as a substitute.
+ COLOR_TITLE_BACKGROUND_GRADIENT = new QColor(61, 149, 255);// palette.color(ColorGroup.Active, ColorRole.Light);
+ COLOR_TITLE_FOREGROUND = palette.color(ColorGroup.Active, ColorRole.HighlightedText);
+
+ // Inactive highlight
+ COLOR_TITLE_INACTIVE_BACKGROUND = new QColor(122, 150, 223);// palette.color(ColorGroup.Inactive, ColorRole.Dark);
+ // TODO The required shade of grey does not exist in QPalette. Should be a bit lighter.
+ COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT = new QColor(157, 185, 235); //palette.color(ColorGroup.Inactive, ColorRole.Light);
+ // TODO The required shade of grey does not exist in QPalette. Should be a bit lighter.
+ // Even lighter still than background gradient. It's the same at the moment.
+ COLOR_TITLE_INACTIVE_FOREGROUND = new QColor(216, 228, 248); //palette.color(ColorGroup.Inactive, ColorRole.BrightText);
+
+ // Window
+ //QApplication.style().
+ COLOR_WIDGET_BACKGROUND = palette.color(ColorGroup.Active, ColorRole.Window);//new QColor(239, 235, 231);
+ COLOR_WIDGET_DARK_SHADOW = palette.color(ColorGroup.Active, ColorRole.Shadow);
+ COLOR_WIDGET_FOREGROUND = COLOR_WIDGET_BORDER = palette.color(ColorGroup.Active, ColorRole.WindowText);
+ COLOR_WIDGET_HIGHLIGHT_SHADOW = palette.color(ColorGroup.Active, ColorRole.Light);
+
+ COLOR_WIDGET_LIGHT_SHADOW = new QColor(236, 233, 216); //palette.color(ColorGroup.Active, ColorRole.Button);
+ COLOR_WIDGET_NORMAL_SHADOW = new QColor(157, 155, 144); //palette.color(ColorGroup.Active, ColorRole.Mid);
+
+ } finally {
+ palette.dispose();
+ }
+ }
+
+ /**
+ * 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>Device</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 abstract QPaintDeviceInterface internal_new_GC(GCData data);
+
+ /**
+ * 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>Device</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 abstract void internal_dispose_GC(QPaintDeviceInterface paintDevice, GCData data);
+
+ /**
+ * Returns <code>true</code> if the device has been disposed, and
+ * <code>false</code> otherwise.
+ * <p>
+ * This method gets the dispose state for the device. When a device has been
+ * disposed, it is an error to invoke any other method using the device.
+ *
+ * @return <code>true</code> when the device is disposed and
+ * <code>false</code> otherwise
+ */
+ public boolean isDisposed() {
+ synchronized (Device.class) {
+ return disposed;
+ }
+ }
+
+ /**
+ * Loads the font specified by a file. The font will be present in the list
+ * of fonts available to the application.
+ *
+ * @param path
+ * the font file path
+ * @return whether the font was successfully loaded
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if path is null</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see Font
+ *
+ * @since 3.3
+ */
+ public boolean loadFont(String path) {
+ checkDevice();
+ if (path == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ int retCode = QFontDatabase.addApplicationFont(path);
+ return retCode != -1; // -1 == font load failed
+ }
+
+ void new_Object(Object object) {
+ synchronized (trackingLock) {
+ for (int i = 0; i < objects.length; i++) {
+ if (objects[i] == null) {
+ objects[i] = object;
+ errors[i] = new Error();
+ return;
+ }
+ }
+ Object[] newObjects = new Object[objects.length + 128];
+ System.arraycopy(objects, 0, newObjects, 0, objects.length);
+ newObjects[objects.length] = object;
+ objects = newObjects;
+ Error[] newErrors = new Error[errors.length + 128];
+ System.arraycopy(errors, 0, newErrors, 0, errors.length);
+ newErrors[errors.length] = new Error();
+ errors = newErrors;
+ }
+ }
+
+ void printErrors() {
+ if (!DEBUG) {
+ return;
+ }
+ if (tracking) {
+ synchronized (trackingLock) {
+ if (objects == null || errors == null) {
+ return;
+ }
+ int objectCount = 0;
+ int colors = 0, cursors = 0, fonts = 0, gcs = 0, images = 0;
+ int paths = 0, patterns = 0, regions = 0, textLayouts = 0, transforms = 0;
+ for (int i = 0; i < objects.length; i++) {
+ Object object = objects[i];
+ if (object != null) {
+ objectCount++;
+ if (object instanceof Color) {
+ colors++;
+ }
+ if (object instanceof Cursor) {
+ cursors++;
+ }
+ if (object instanceof Font) {
+ fonts++;
+ }
+ if (object instanceof GC) {
+ gcs++;
+ }
+ if (object instanceof Image) {
+ images++;
+ }
+ if (object instanceof Path) {
+ paths++;
+ }
+ if (object instanceof Pattern) {
+ patterns++;
+ }
+ if (object instanceof Region) {
+ regions++;
+ }
+ if (object instanceof TextLayout) {
+ textLayouts++;
+ }
+ if (object instanceof Transform) {
+ transforms++;
+ }
+ }
+ }
+ if (objectCount != 0) {
+ String string = "Summary: "; //$NON-NLS-1$
+ if (colors != 0) {
+ string += colors + " Color(s), ";//$NON-NLS-1$
+ }
+ if (cursors != 0) {
+ string += cursors + " Cursor(s), ";//$NON-NLS-1$
+ }
+ if (fonts != 0) {
+ string += fonts + " Font(s), ";//$NON-NLS-1$
+ }
+ if (gcs != 0) {
+ string += gcs + " GC(s), ";//$NON-NLS-1$
+ }
+ if (images != 0) {
+ string += images + " Image(s), ";//$NON-NLS-1$
+ }
+ if (paths != 0) {
+ string += paths + " Path(s), ";//$NON-NLS-1$
+ }
+ if (patterns != 0) {
+ string += patterns + " Pattern(s), ";//$NON-NLS-1$
+ }
+ if (regions != 0) {
+ string += regions + " Region(s), ";//$NON-NLS-1$
+ }
+ if (textLayouts != 0) {
+ string += textLayouts + " TextLayout(s), ";//$NON-NLS-1$
+ }
+ if (transforms != 0) {
+ string += transforms + " Transforms(s), ";//$NON-NLS-1$
+ }
+ if (string.length() != 0) {
+ string = string.substring(0, string.length() - 2);
+ System.err.println(string);
+ }
+ for (int i = 0; i < errors.length; i++) {
+ if (errors[i] != null) {
+ errors[i].printStackTrace(System.err);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Releases any internal resources back to the operating system and clears
+ * all fields except the device handle.
+ * <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>. </p>
+ * <p>
+ * If subclasses reimplement this method, they must call the
+ * <code>super</code> implementation.
+ * </p>
+ *
+ * @see #dispose
+ * @see #destroy
+ */
+ protected void release() {
+ paintDevice = null;
+ }
+
+ /**
+ * If the underlying window system supports printing warning messages to the
+ * console, setting warnings to <code>false</code> prevents these messages
+ * from being printed. If the argument is <code>true</code> then message
+ * printing is not blocked.
+ *
+ * @param warnings
+ * <code>true</code>if warnings should be printed, and
+ * <code>false</code> otherwise
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void setWarnings(boolean warnings) {
+ checkDevice();
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/DeviceData.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/DeviceData.java
new file mode 100644
index 0000000000..8dd1012d58
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/DeviceData.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.graphics;
+
+public class DeviceData {
+ /*
+ * Debug fields - may not be honoured on some SWT platforms.
+ */
+ public boolean debug;
+ public boolean tracking;
+ public Error[] errors;
+ public Object[] objects;
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Font.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Font.java
new file mode 100644
index 0000000000..0758f4d05f
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Font.java
@@ -0,0 +1,379 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.graphics;
+
+import com.trolltech.qt.gui.QFont;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTError;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.internal.qt.QtSupplementaryFontData;
+import org.eclipse.swt.internal.qt.SWQT;
+
+/**
+ * Instances of this class manage operating system resources that define how
+ * text looks when it is displayed. Fonts may be constructed by providing a
+ * device and either name, size and style information or a <code>FontData</code>
+ * object which encapsulates this data.
+ * <p>
+ * Application code must explicitly invoke the <code>Font.dispose()</code>
+ * method to release the operating system resources managed by each instance
+ * when those instances are no longer required.
+ * </p>
+ *
+ * @see FontData
+ * @see <a href="http://www.eclipse.org/swt/snippets/#font">Font snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Examples:
+ * GraphicsExample, PaintExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ */
+
+public final class Font extends Resource {
+
+ /**
+ * the handle to the OS font 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>
+ */
+ private QFont font;
+
+ boolean extraFontStyle;
+ String xlfd;
+
+ /**
+ * Prevents uninitialized instances from being created outside the package.
+ */
+ Font() {
+ }
+
+ /**
+ * Prevents uninitialized instances from being created outside the package.
+ */
+ Font(Device device) {
+ super(device);
+ }
+
+ /**
+ * Constructs a new font given a device and font data which describes the
+ * desired font's appearance.
+ * <p>
+ * You must dispose the font when it is no longer required.
+ * </p>
+ *
+ * @param device
+ * the device to create the font on
+ * @param fd
+ * the FontData that describes the desired font (must not be
+ * null)
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if device is null and there is
+ * no current device</li>
+ * <li>ERROR_NULL_ARGUMENT - if the fd argument is null</li>
+ * </ul>
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_NO_HANDLES - if a font could not be created from
+ * the given font data</li>
+ * </ul>
+ */
+ public Font(Device device, FontData fd) {
+ super(device);
+ init(fd);
+ init();
+ }
+
+ /**
+ * Constructs a new font given a device and an array of font data which
+ * describes the desired font's appearance.
+ * <p>
+ * You must dispose the font when it is no longer required.
+ * </p>
+ *
+ * @param device
+ * the device to create the font on
+ * @param fds
+ * the array of FontData that describes the desired font (must
+ * not be null)
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if device is null and there is
+ * no current device</li>
+ * <li>ERROR_NULL_ARGUMENT - if the fds argument is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the length of fds is zero</li>
+ * <li>ERROR_NULL_ARGUMENT - if any fd in the array is null</li>
+ * </ul>
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_NO_HANDLES - if a font could not be created from
+ * the given font data</li>
+ * </ul>
+ *
+ * @since 2.1
+ */
+ public Font(Device device, FontData[] fds) {
+ super(device);
+ if (fds == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (fds.length == 0) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ for (int i = 0; i < fds.length; i++) {
+ if (fds[i] == null) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ }
+ init(fds[0]);
+ init();
+ }
+
+ /**
+ * Constructs a new font given a device, a font name, the height of the
+ * desired font in points, and a font style.
+ * <p>
+ * You must dispose the font when it is no longer required.
+ * </p>
+ *
+ * @param device
+ * the device to create the font on
+ * @param name
+ * the name of the font (must not be null)
+ * @param height
+ * the font height in points
+ * @param style
+ * a bit or combination of NORMAL, BOLD, ITALIC
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if device is null and there is
+ * no current device</li>
+ * <li>ERROR_NULL_ARGUMENT - if the name argument is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the height is negative</li>
+ * </ul>
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_NO_HANDLES - if a font could not be created from
+ * the given arguments</li>
+ * </ul>
+ */
+ public Font(Device device, String name, int height, int style) {
+ super(device);
+ if (name == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ init(new FontData(name, height, style));
+ init();
+ }
+
+ public QFont getQFont() {
+ return font;
+ }
+
+ // /*public*/ Font(Device device, String name, float height, int style) {
+ // super(device);
+ // if (name == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ // init(new FontData (name, height, style));
+ // init();
+ // }
+ @Override
+ void destroy() {
+ font.dispose(); // TODO_DISPOSE
+ font = null;
+
+ }
+
+ /**
+ * Compares the argument to the receiver, and returns true if they represent
+ * the <em>same</em> object using a class specific comparison.
+ *
+ * @param object
+ * the object to compare with this object
+ * @return <code>true</code> if the object is the same as this object and
+ * <code>false</code> otherwise
+ *
+ * @see #hashCode
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (!(object instanceof Font)) {
+ return false;
+ }
+ Font font = (Font) object;
+ return this.getQFont().equals(font.getQFont());
+ }
+
+ /**
+ * Returns an array of <code>FontData</code>s representing the receiver. On
+ * Windows, only one FontData will be returned per font. On X however, a
+ * <code>Font</code> object <em>may</em> be composed of multiple X fonts. To
+ * support this case, we return an array of font data objects.
+ *
+ * @return an array of font data objects describing the receiver
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public FontData[] getFontData() {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+
+ String family = font.family();
+ int pointSize = font.pointSize();
+ int weight = font.weight();
+ boolean italic = font.italic();
+
+ int style = SWT.NORMAL;
+ if (weight > SWQT.QT_FONTNORMAL) {
+ style |= SWT.BOLD;
+ }
+ if (italic) {
+ style |= SWT.ITALIC;
+ }
+ FontData data = new FontData(family, pointSize, style);
+ if (xlfd != null) {
+ data.xlfd = xlfd;
+ } else if (extraFontStyle) {
+ data.extraFontData = new QtSupplementaryFontData();
+ QtSupplementaryFontData extraData = data.extraFontData;
+ extraData.underline = font.underline() ? 1 : 0;
+ extraData.overline = font.overline() ? 1 : 0;
+ extraData.strikeOut = font.strikeOut() ? 1 : 0;
+ extraData.stretch = font.stretch();
+ extraData.fixedPitch = font.fixedPitch() ? 1 : 0;
+ extraData.style = font.style();
+ extraData.weight = font.weight();
+ extraData.styleStrategy = font.styleStrategy();
+ }
+ return new FontData[] { data };
+ }
+
+ /**
+ * Returns an integer hash code for the receiver. Any two objects that
+ * return <code>true</code> when passed to <code>equals</code> must return
+ * the same value for this method.
+ *
+ * @return the receiver's hash
+ *
+ * @see #equals
+ */
+ @Override
+ public int hashCode() {
+ if (font == null) {
+ return 0;
+ }
+ return font.toString().hashCode(); // TODO
+ }
+
+ void init(FontData fd) {
+ if (fd == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ int weight = QFont.Weight.Normal.value();
+ boolean italic = false;
+ if (fd.extraFontData != null) {
+ weight = fd.extraFontData.weight;
+ italic = fd.extraFontData.style == QFont.Style.StyleItalic;
+ }
+
+ font = new QFont(fd.name, fd.getHeight(), weight, italic);
+ // TODO font can be BOLD AND ITALIC
+ if (fd.style == SWT.BOLD) {
+ font.setBold(true);
+ }
+ if (fd.style == SWT.ITALIC) {
+ font.setItalic(true);
+ }
+ // int lfHeight = fontData.lfHeight;
+ // fontData.lfHeight = device.computePixels(fd.height);
+ // handle = OS.CreateFontIndirect(logFont);
+ // fontData.lfHeight = lfHeight;
+ // if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+ }
+
+ /**
+ * Returns <code>true</code> if the font has been disposed, and
+ * <code>false</code> otherwise.
+ * <p>
+ * This method gets the dispose state for the font. When a font has been
+ * disposed, it is an error to invoke any other method using the font.
+ *
+ * @return <code>true</code> when the font is disposed and
+ * <code>false</code> otherwise
+ */
+ @Override
+ public boolean isDisposed() {
+ return font == null;
+ }
+
+ /**
+ * Returns a string containing a concise, human-readable description of the
+ * receiver.
+ *
+ * @return a string representation of the receiver
+ */
+ @Override
+ public String toString() {
+ if (isDisposed()) {
+ return "Font {*DISPOSED*}"; //$NON-NLS-1$
+ }
+ return "Font {" + font.family() + "}"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Invokes platform specific functionality to allocate a new font.
+ * <p>
+ * <b>IMPORTANT:</b> This method is <em>not</em> part of the public API for
+ * <code>Font</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 device
+ * the device on which to allocate the color
+ * @param handle
+ * the handle for the font
+ * @return a new font object containing the specified device and handle
+ */
+ public static Font qt_new(Device device, QFont fontParm) {
+ if (fontParm == null) {
+ return null;
+ }
+ if (device == null) {
+ device = Device.getDevice();
+ }
+ if (device == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ Font font = new Font();
+ font.font = fontParm;
+ font.device = device;
+ return font;
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/FontData.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/FontData.java
new file mode 100644
index 0000000000..89db2b04ff
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/FontData.java
@@ -0,0 +1,722 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Portion Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Nokia Corporation - Qt implementation
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.graphics;
+
+import com.trolltech.qt.gui.QFont;
+import com.trolltech.qt.gui.QFont.Style;
+import com.trolltech.qt.gui.QFont.StyleStrategy;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.internal.qt.QtSupplementaryFontData;
+import org.eclipse.swt.internal.qt.SWQT;
+
+/**
+ * Instances of this class describe operating system fonts.
+ * <p>
+ * For platform-independent behaviour, use the get and set methods corresponding
+ * to the following properties:
+ * <dl>
+ * <dt>height</dt>
+ * <dd>the height of the font in points</dd>
+ * <dt>name</dt>
+ * <dd>the face name of the font, which may include the foundry</dd>
+ * <dt>style</dt>
+ * <dd>A bitwise combination of NORMAL, ITALIC and BOLD</dd>
+ * </dl>
+ * If extra, platform-dependent functionality is required:
+ * <ul>
+ * <li>On <em>Windows</em>, the data member of the <code>FontData</code>
+ * corresponds to a Windows <code>LOGFONT</code> structure whose fields may be
+ * retrieved and modified.</li>
+ * <li>On <em>X</em>, the fields of the <code>FontData</code> correspond to the
+ * entries in the font's XLFD name and may be retrieved and modified.
+ * </ul>
+ * Application code does <em>not</em> need to explicitly release the resources
+ * managed by each instance when those instances are no longer required, and
+ * thus no <code>dispose()</code> method is provided.
+ *
+ * @see Font
+ */
+public final class FontData {
+ /**
+ * the font name
+ */
+ String name;
+
+ /**
+ * The height of the font data in points
+ */
+ int height;
+
+ /**
+ * the font style
+ */
+ int style;
+
+ /**
+ * The locales of the font
+ */
+ String lang, country, variant;
+
+ QtSupplementaryFontData extraFontData;
+ String xlfd;
+
+ public static final int FONT_DEF_HEIGHT = 12;
+
+ /**
+ * Constructs a new uninitialized font data.
+ */
+ public FontData() {
+ this("", FONT_DEF_HEIGHT, SWT.NORMAL); //$NON-NLS-1$
+ }
+
+ // The characters in the string must all be decimal digits
+ // the value must be given with radix 10
+
+ /**
+ * Constructs a new FontData given a string representation in the form
+ * generated by the <code>FontData.toString</code> method.
+ * <p>
+ * Note that the representation varies between platforms, and a FontData can
+ * only be created from a string that was generated on the same platform.
+ * </p>
+ *
+ * @param string
+ * the string representation of a <code>FontData</code> (must not
+ * be null)
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument does not
+ * represent a valid description</li>
+ * </ul>
+ *
+ * @see #toString
+ */
+ public FontData(String string) {
+ if (string == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ parseFontDescriptor(string);
+ updateFontData();
+
+ }
+
+ /**
+ * Constructs a new font data given a font name, the height of the desired
+ * font in points, and a font style.
+ *
+ * @param name
+ * the name of the font (must not be null)
+ * @param height
+ * the font height in points
+ * @param style
+ * a bit or combination of NORMAL, BOLD, ITALIC
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - when the font name is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the height is negative</li>
+ * </ul>
+ */
+ public FontData(String name, int height, int style) {
+ if (name == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (height < 0) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ setName(name);
+ setHeight(height);
+ setStyle(style);
+ }
+
+ /**
+ * Compares the argument to the receiver, and returns true if they represent
+ * the <em>same</em> object using a class specific comparison.
+ *
+ * @param object
+ * the object to compare with this object
+ * @return <code>true</code> if the object is the same as this object and
+ * <code>false</code> otherwise
+ *
+ * @see #hashCode
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (!(object instanceof FontData)) {
+ return false;
+ }
+
+ FontData data = (FontData) object;
+
+ if (!(xlfd == null && data.xlfd == null || xlfd != null && data.xlfd != null)) {
+ return false;
+ }
+
+ if (!(extraFontData == null && data.extraFontData == null || extraFontData != null
+ && data.extraFontData != null)) {
+ return false;
+ }
+
+ if (xlfd != null) {
+ return xlfd.trim().equals(data.xlfd.trim());
+ }
+
+ boolean mainFontStyleEqual = name.equals(data.name) && height == data.height && style == data.style;
+ if (mainFontStyleEqual && extraFontData != null) {
+ return mainFontStyleEqual && extraFontData.underline == data.extraFontData.underline
+ && extraFontData.underline == data.extraFontData.underline
+ && extraFontData.overline == data.extraFontData.overline
+ && extraFontData.strikeOut == data.extraFontData.strikeOut
+ && extraFontData.stretch == data.extraFontData.stretch
+ && extraFontData.fixedPitch == data.extraFontData.fixedPitch
+ && extraFontData.style == data.extraFontData.style
+ && extraFontData.weight == data.extraFontData.weight
+ && extraFontData.styleStrategy == data.extraFontData.styleStrategy;
+ } else {
+ return mainFontStyleEqual;
+ }
+ }
+
+ /**
+ * Returns the height of the receiver in points.
+ *
+ * @return the height of this FontData
+ *
+ * @see #setHeight(int)
+ */
+ public int getHeight() {
+ return height;
+ }
+
+ /**
+ * Returns the locale of the receiver.
+ * <p>
+ * The locale determines which platform character set this font is going to
+ * use. Widgets and graphics operations that use this font will convert
+ * UNICODE strings to the platform character set of the specified locale.
+ * </p>
+ * <p>
+ * On platforms where there are multiple character sets for a given
+ * language/country locale, the variant portion of the locale will determine
+ * the character set.
+ * </p>
+ *
+ * @return the <code>String</code> representing a Locale object
+ * @since 3.0
+ */
+ public String getLocale() {
+ StringBuffer buffer = new StringBuffer();
+ char sep = '_';
+ if (lang != null) {
+ buffer.append(lang);
+ buffer.append(sep);
+ }
+ if (country != null) {
+ buffer.append(country);
+ buffer.append(sep);
+ }
+ if (variant != null) {
+ buffer.append(variant);
+ }
+
+ String result = buffer.toString();
+ int length = result.length();
+ if (length > 0) {
+ if (result.charAt(length - 1) == sep) {
+ result = result.substring(0, length - 1);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns the name of the receiver. On platforms that support font
+ * foundries, the return value will be the foundry followed by a dash ("-")
+ * followed by the face name.
+ *
+ * @return the name of this <code>FontData</code>
+ *
+ * @see #setName
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the style of the receiver which is a bitwise OR of one or more of
+ * the <code>SWT</code> constants NORMAL, BOLD and ITALIC.
+ *
+ * @return the style of this <code>FontData</code>
+ *
+ * @see #setStyle
+ */
+ public int getStyle() {
+ return style;
+ }
+
+ /**
+ * Returns an integer hash code for the receiver. Any two objects that
+ * return <code>true</code> when passed to <code>equals</code> must return
+ * the same value for this method.
+ *
+ * @return the receiver's hash
+ *
+ * @see #equals
+ */
+ @Override
+ public int hashCode() {
+ return name.hashCode() ^ height ^ style;
+ }
+
+ void parseFontDescriptor(String string) {
+ int start = 0;
+ int end = string.indexOf('|');
+ if (end == -1) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ String version1 = string.substring(start, end);
+ try {
+ if (Integer.parseInt(version1) != 1) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ } catch (NumberFormatException e) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+
+ start = end + 1;
+ end = string.indexOf('|', start);
+ if (end == -1) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ String name = string.substring(start, end);
+
+ start = end + 1;
+ end = string.indexOf('|', start);
+ if (end == -1) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ int height = 0;
+ try {
+ height = Integer.parseInt(string.substring(start, end));
+ } catch (NumberFormatException e) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+
+ start = end + 1;
+ end = string.indexOf('|', start);
+ if (end == -1) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ int style = 0;
+ try {
+ style = Integer.parseInt(string.substring(start, end));
+ } catch (NumberFormatException e) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+
+ start = end + 1;
+ end = string.indexOf('|', start);
+ setName(name);
+ setHeight(height);
+ setStyle(style);
+ if (end == -1) {
+ return;
+ }
+ String platform = string.substring(start, end);
+
+ start = end + 1;
+ end = string.indexOf('|', start);
+ if (end == -1) {
+ return;
+ }
+ String version2 = string.substring(start, end);
+
+ if (platform.trim().toUpperCase().equals("QT") && version2.equals("1")) { //$NON-NLS-1$ //$NON-NLS-2$
+ try {
+ extraFontData = new QtSupplementaryFontData();
+ start = end + 1;
+ end = string.indexOf('|', start);
+ if (end == -1) {
+ return;
+ }
+ extraFontData.underline = Integer.parseInt(string.substring(start, end));
+ start = end + 1;
+ end = string.indexOf('|', start);
+ if (end == -1) {
+ return;
+ }
+ extraFontData.overline = Integer.parseInt(string.substring(start, end));
+ start = end + 1;
+ end = string.indexOf('|', start);
+ if (end == -1) {
+ return;
+ }
+ extraFontData.strikeOut = Integer.parseInt(string.substring(start, end));
+ start = end + 1;
+ end = string.indexOf('|', start);
+ if (end == -1) {
+ return;
+ }
+ int stretch = Integer.parseInt(string.substring(start, end));
+ if (stretch > 0) {
+ if (stretch > 4000) {
+ stretch = 4000;
+ }
+ extraFontData.stretch = stretch;
+ }
+ start = end + 1;
+ end = string.indexOf('|', start);
+ if (end == -1) {
+ extraFontData = null;
+ return;
+ }
+ extraFontData.fixedPitch = Integer.parseInt(string.substring(start, end));
+ start = end + 1;
+ end = string.indexOf('|', start);
+ if (end == -1) {
+ return;
+ }
+ int fontStyle = Integer.parseInt(string.substring(start, end));
+ if (fontStyle == SWQT.QFONT_STYLE_NORMAL) {
+ extraFontData.style = Style.StyleNormal;
+ }
+ if (fontStyle == SWQT.QFONT_STYLE_ITALIC) {
+ extraFontData.style = Style.StyleItalic;
+ }
+ if (fontStyle == SWQT.QFONT_STYLE_OBLIQUE) {
+ extraFontData.style = Style.StyleOblique;
+ }
+ start = end + 1;
+ end = string.indexOf('|', start);
+ if (end == -1) {
+ return;
+ }
+ int weight = Integer.parseInt(string.substring(start, end));
+ if (weight > -1) {
+ if (weight > 99) {
+ weight = 99;
+ }
+ extraFontData.weight = weight;
+ }
+ start = end + 1;
+ end = string.indexOf('|', start);
+ if (end == -1) {
+ return;
+ }
+ int styleStrategy = Integer.parseInt(string.substring(start, end));
+ int[] strategies = new int[] { SWQT.QFONT_STYLESTRATEGY_PREFERDEFALUT,
+ SWQT.QFONT_STYLESTRATEGY_PREFERBITMAP, SWQT.QFONT_STYLESTRATEGY_PREFERDEVICE,
+ SWQT.QFONT_STYLESTRATEGY_PREFEROUTLINE, SWQT.QFONT_STYLESTRATEGY_FORCEOUTLINE,
+ SWQT.QFONT_STYLESTRATEGY_NOANTIALIAS, SWQT.QFONT_STYLESTRATEGY_PREFERANTIALIAS,
+ SWQT.QFONT_STYLESTRATEGY_OPENGLCOMPATIABLE, SWQT.QFONT_STYLESTRATEGY_NOFONTMERGING };
+ boolean isValidStrategy = styleStrategy == SWQT.QFONT_STYLESTRATEGY_PREFERQUALITY
+ || styleStrategy == SWQT.QFONT_STYLESTRATEGY_PREFERMATCH ? true : false;
+ for (int i = 0; i < strategies.length; i++) {
+ if ((styleStrategy & strategies[i]) == 0) {
+ continue;
+ } else {
+ if (styleStrategy == strategies[i]
+ || styleStrategy == (strategies[i] | SWQT.QFONT_STYLESTRATEGY_PREFERQUALITY)
+ || styleStrategy == (strategies[i] | SWQT.QFONT_STYLESTRATEGY_PREFERMATCH)) {
+ isValidStrategy = true;
+ }
+ break;
+ }
+ }
+ if (isValidStrategy) {
+ if (styleStrategy == SWQT.QFONT_STYLESTRATEGY_FORCEOUTLINE) {
+ extraFontData.styleStrategy = StyleStrategy.ForceOutline;
+ }
+ if (styleStrategy == SWQT.QFONT_STYLESTRATEGY_NOANTIALIAS) {
+ extraFontData.styleStrategy = StyleStrategy.NoAntialias;
+ }
+ if (styleStrategy == SWQT.QFONT_STYLESTRATEGY_NOFONTMERGING) {
+ extraFontData.styleStrategy = StyleStrategy.NoFontMerging;
+ }
+ if (styleStrategy == SWQT.QFONT_STYLESTRATEGY_OPENGLCOMPATIABLE) {
+ extraFontData.styleStrategy = StyleStrategy.OpenGLCompatible;
+ }
+ if (styleStrategy == SWQT.QFONT_STYLESTRATEGY_PREFERANTIALIAS) {
+ extraFontData.styleStrategy = StyleStrategy.PreferAntialias;
+ }
+ if (styleStrategy == SWQT.QFONT_STYLESTRATEGY_PREFERBITMAP) {
+ extraFontData.styleStrategy = StyleStrategy.PreferBitmap;
+ }
+ if (styleStrategy == SWQT.QFONT_STYLESTRATEGY_PREFERDEFALUT) {
+ extraFontData.styleStrategy = StyleStrategy.PreferDefault;
+ }
+ if (styleStrategy == SWQT.QFONT_STYLESTRATEGY_PREFERDEVICE) {
+ extraFontData.styleStrategy = StyleStrategy.PreferDevice;
+ }
+ if (styleStrategy == SWQT.QFONT_STYLESTRATEGY_PREFERMATCH) {
+ extraFontData.styleStrategy = StyleStrategy.PreferMatch;
+ }
+ if (styleStrategy == SWQT.QFONT_STYLESTRATEGY_PREFEROUTLINE) {
+ extraFontData.styleStrategy = StyleStrategy.PreferOutline;
+ }
+ if (styleStrategy == SWQT.QFONT_STYLESTRATEGY_PREFERQUALITY) {
+ extraFontData.styleStrategy = StyleStrategy.PreferQuality;
+ }
+ }
+ } catch (NumberFormatException e) {
+ extraFontData = null;
+ }
+ }
+ // else if (platform.trim().toUpperCase().equals("X11")
+ // && OS.windowServer == OS.WS_X11) {
+ // start = end + 1;
+ // end = string.indexOf('|', start);
+ // if (end == -1)
+ // return;
+ // xlfd = string.substring(start, end);
+ // if (xlfd.length() < 1) {
+ // xlfd = null;
+ // }
+ // }
+
+ }
+
+ /**
+ * Sets the height of the receiver. The parameter is specified in terms of
+ * points, where a point is one seventy-second of an inch.
+ *
+ * @param height
+ * the height of the <code>FontData</code>
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the height is negative</li>
+ * </ul>
+ *
+ * @see #getHeight
+ */
+ public void setHeight(int height) {
+ if (height < 0) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ this.height = height;
+ }
+
+ /**
+ * Sets the locale of the receiver.
+ * <p>
+ * The locale determines which platform character set this font is going to
+ * use. Widgets and graphics operations that use this font will convert
+ * UNICODE strings to the platform character set of the specified locale.
+ * </p>
+ * <p>
+ * On platforms where there are multiple character sets for a given
+ * language/country locale, the variant portion of the locale will determine
+ * the character set.
+ * </p>
+ *
+ * @param locale
+ * the <code>String</code> representing a Locale object
+ * @see java.util.Locale#toString
+ */
+ public void setLocale(String locale) {
+ lang = country = variant = null;
+ if (locale != null) {
+ char sep = '_';
+ int length = locale.length();
+ int firstSep, secondSep;
+
+ firstSep = locale.indexOf(sep);
+ if (firstSep == -1) {
+ firstSep = secondSep = length;
+ } else {
+ secondSep = locale.indexOf(sep, firstSep + 1);
+ if (secondSep == -1) {
+ secondSep = length;
+ }
+ }
+ if (firstSep > 0) {
+ lang = locale.substring(0, firstSep);
+ }
+ if (secondSep > firstSep + 1) {
+ country = locale.substring(firstSep + 1, secondSep);
+ }
+ if (length > secondSep + 1) {
+ variant = locale.substring(secondSep + 1);
+ }
+ }
+ }
+
+ /**
+ * Sets the name of the receiver.
+ * <p>
+ * Some platforms support font foundries. On these platforms, the name of
+ * the font specified in setName() may have one of the following forms:
+ * <ol>
+ * <li>a face name (for example, "courier")</li>
+ * <li>a foundry followed by a dash ("-") followed by a face name (for
+ * example, "adobe-courier")</li>
+ * </ol>
+ * In either case, the name returned from getName() will include the
+ * foundry.
+ * </p>
+ * <p>
+ * On platforms that do not support font foundries, only the face name (for
+ * example, "courier") is used in <code>setName()</code> and
+ * <code>getName()</code>.
+ * </p>
+ *
+ * @param name
+ * the name of the font data (must not be null)
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - when the font name is null</li>
+ * </ul>
+ *
+ * @see #getName
+ */
+ public void setName(String name) {
+ if (name == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ this.name = name;
+ }
+
+ /**
+ * Sets the style of the receiver to the argument which must be a bitwise OR
+ * of one or more of the <code>SWT</code> constants NORMAL, BOLD and ITALIC.
+ * All other style bits are ignored.
+ *
+ * @param style
+ * the new style for this <code>FontData</code>
+ *
+ * @see #getStyle
+ */
+ public void setStyle(int style) {
+ this.style = style;
+ }
+
+ /**
+ * Returns a string representation of the receiver which is suitable for
+ * constructing an equivalent instance using the
+ * <code>FontData(String)</code> constructor.
+ *
+ * @return a string representation of the FontData
+ *
+ * @see FontData
+ */
+ @Override
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("1|"); //$NON-NLS-1$
+ buffer.append(getName());
+ buffer.append("|"); //$NON-NLS-1$
+ buffer.append(getHeight());
+ buffer.append("|"); //$NON-NLS-1$
+ buffer.append(getStyle());
+ buffer.append("|"); //$NON-NLS-1$
+ if (xlfd != null) {
+ buffer.append("X11|1|"); //$NON-NLS-1$
+ buffer.append(xlfd);
+ buffer.append("|"); //$NON-NLS-1$
+ } else if (extraFontData != null) {
+ buffer.append("QT|1|"); //$NON-NLS-1$
+ buffer.append(extraFontData.overline);
+ buffer.append("|"); //$NON-NLS-1$
+ buffer.append(extraFontData.underline);
+ buffer.append("|"); //$NON-NLS-1$
+ buffer.append(extraFontData.strikeOut);
+ buffer.append("|"); //$NON-NLS-1$
+ buffer.append(extraFontData.stretch);
+ buffer.append("|"); //$NON-NLS-1$
+ buffer.append(extraFontData.fixedPitch);
+ buffer.append("|"); //$NON-NLS-1$
+ buffer.append(extraFontData.style);
+ buffer.append("|"); //$NON-NLS-1$
+ buffer.append(extraFontData.weight);
+ buffer.append("|"); //$NON-NLS-1$
+ buffer.append(extraFontData.styleStrategy);
+ buffer.append("|"); //$NON-NLS-1$
+ }
+ return buffer.toString();
+ }
+
+ void updateFontData() {
+ if (extraFontData == null && xlfd == null) {
+ return;
+ }
+
+ boolean italic = (style & SWT.ITALIC) != 0;
+ int weight = SWQT.QT_FONTNORMAL;
+ if ((style & SWT.BOLD) != 0) {
+ weight = SWQT.QT_FONTBOLD;
+ }
+ QFont font = new QFont(name, height, weight, italic);
+
+ if (xlfd != null) {
+ font.setRawName(xlfd);
+
+ } else {
+ if (extraFontData.underline > -1) {
+ font.setUnderline(extraFontData.underline > 0 ? true : false);
+ }
+ if (extraFontData.overline > -1) {
+ font.setOverline(extraFontData.overline > 0 ? true : false);
+ }
+ if (extraFontData.strikeOut > -1) {
+ font.setStrikeOut(extraFontData.strikeOut > 0 ? true : false);
+ }
+ if (extraFontData.stretch > -1) {
+ font.setStretch(extraFontData.stretch);
+ }
+ if (extraFontData.fixedPitch > -1) {
+ font.setFixedPitch(extraFontData.fixedPitch > 0 ? true : false);
+ }
+ if (extraFontData.style != null) {
+ font.setStyle(extraFontData.style);
+ }
+ if (extraFontData.weight > -1) {
+ font.setWeight(extraFontData.weight);
+ }
+ if (extraFontData.styleStrategy != null) {
+ font.setStyleStrategy(extraFontData.styleStrategy);
+ }
+ }
+
+ name = font.family();
+ height = font.pointSize();
+ weight = font.weight();
+ italic = font.italic();
+ style = SWT.NORMAL;
+ if (weight > SWQT.QT_FONTNORMAL) {
+ style |= SWT.BOLD;
+ }
+ if (italic == true) {
+ style |= SWT.ITALIC;
+ }
+ if (extraFontData != null) {
+ extraFontData.underline = font.underline() == true ? 1 : 0;
+ extraFontData.overline = font.overline() == true ? 1 : 0;
+ extraFontData.strikeOut = font.strikeOut() == true ? 1 : 0;
+ extraFontData.stretch = font.stretch();
+ extraFontData.fixedPitch = font.fixedPitch() == true ? 1 : 0;
+ extraFontData.style = font.style();
+ extraFontData.weight = font.weight();
+ extraFontData.styleStrategy = font.styleStrategy();
+ font.dispose();
+ }
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/FontMetrics.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/FontMetrics.java
new file mode 100644
index 0000000000..2be6f6e78e
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/FontMetrics.java
@@ -0,0 +1,165 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.graphics;
+
+import com.trolltech.qt.gui.QFontMetrics;
+
+/**
+ * Instances of this class provide measurement information about fonts including
+ * ascent, descent, height, leading space between rows, and average character
+ * width. <code>FontMetrics</code> are obtained from <code>GC</code>s using the
+ * <code>getFontMetrics()</code> method.
+ *
+ * @see GC#getFontMetrics
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ */
+public final class FontMetrics {
+ private final int ascent;
+ private final int descent;
+ private final int aveCharWidth;
+ private final int leading;
+ private final int height;
+
+ private FontMetrics(int ascent, int descent, int aveCharWidth, int leading, int height) {
+ this.ascent = ascent;
+ this.descent = descent;
+ this.aveCharWidth = aveCharWidth;
+ this.leading = leading;
+ this.height = height;
+ }
+
+ /**
+ * Compares the argument to the receiver, and returns true if they represent
+ * the <em>same</em> object using a class specific comparison.
+ *
+ * @param object
+ * the object to compare with this object
+ * @return <code>true</code> if the object is the same as this object and
+ * <code>false</code> otherwise
+ *
+ * @see #hashCode
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (!(object instanceof FontMetrics)) {
+ return false;
+ }
+ FontMetrics other = (FontMetrics) object;
+ return ascent == other.ascent && descent == other.descent && aveCharWidth == other.aveCharWidth
+ && leading == other.leading && height == other.height;
+ }
+
+ /**
+ * Returns the ascent of the font described by the receiver. A font's
+ * <em>ascent</em> is the distance from the baseline to the top of actual
+ * characters, not including any of the leading area, measured in pixels.
+ *
+ * @return the ascent of the font
+ */
+ public int getAscent() {
+ return ascent;
+ }
+
+ /**
+ * Returns the average character width, measured in pixels, of the font
+ * described by the receiver.
+ *
+ * @return the average character width of the font
+ */
+ public int getAverageCharWidth() {
+ return aveCharWidth;
+ }
+
+ /**
+ * Returns the descent of the font described by the receiver. A font's
+ * <em>descent</em> is the distance from the baseline to the bottom of
+ * actual characters, not including any of the leading area, measured in
+ * pixels.
+ *
+ * @return the descent of the font
+ */
+ public int getDescent() {
+ return descent;
+ }
+
+ /**
+ * Returns the height of the font described by the receiver, measured in
+ * pixels. A font's <em>height</em> is the sum of its ascent, descent and
+ * leading area.
+ *
+ * @return the height of the font
+ *
+ * @see #getAscent
+ * @see #getDescent
+ * @see #getLeading
+ */
+ public int getHeight() {
+ return height;
+ }
+
+ /**
+ * Returns the leading area of the font described by the receiver. A font's
+ * <em>leading area</em> is the space above its ascent which may include
+ * accents or other marks.
+ *
+ * @return the leading space of the font
+ */
+ public int getLeading() {
+ return leading;
+ }
+
+ /**
+ * Returns an integer hash code for the receiver. Any two objects that
+ * return <code>true</code> when passed to <code>equals</code> must return
+ * the same value for this method.
+ *
+ * @return the receiver's hash
+ *
+ * @see #equals
+ */
+ @Override
+ public int hashCode() {
+ return ascent ^ descent ^ aveCharWidth ^ leading ^ height;
+ }
+
+ /**
+ * Invokes platform specific functionality to allocate a new font metrics.
+ * <p>
+ * <b>IMPORTANT:</b> This method is <em>not</em> part of the public API for
+ * <code>FontMetrics</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 metrics
+ * the <code>QFontMetrics</code> containing information about a
+ * font
+ * @return a new font metrics object containing the specified
+ * <code>TEXTMETRIC</code>
+ */
+ public static FontMetrics internal_new(QFontMetrics qfm) {
+ return new FontMetrics(qfm.ascent(), qfm.descent(), qfm.averageCharWidth(), 0, qfm.height());
+ }
+
+ public static FontMetrics internal_new(Font font) {
+ return internal_new(new QFontMetrics(font.getQFont()));
+ }
+
+ public static FontMetrics internal_new(int ascent, int descent, int aveCharWidth, int leading, int height) {
+ return new FontMetrics(ascent, descent, aveCharWidth, leading, height);
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/GC.java
new file mode 100644
index 0000000000..026041b62b
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/GC.java
@@ -0,0 +1,3555 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.graphics;
+
+import com.trolltech.qt.core.QPointF;
+import com.trolltech.qt.core.QRect;
+import com.trolltech.qt.core.Qt.AlignmentFlag;
+import com.trolltech.qt.core.Qt.BGMode;
+import com.trolltech.qt.core.Qt.FillRule;
+import com.trolltech.qt.core.Qt.PenStyle;
+import com.trolltech.qt.core.Qt.SizeMode;
+import com.trolltech.qt.core.Qt.TextFlag;
+import com.trolltech.qt.gui.QApplication;
+import com.trolltech.qt.gui.QBrush;
+import com.trolltech.qt.gui.QColor;
+import com.trolltech.qt.gui.QFontMetrics;
+import com.trolltech.qt.gui.QLinearGradient;
+import com.trolltech.qt.gui.QPaintDeviceInterface;
+import com.trolltech.qt.gui.QPainter;
+import com.trolltech.qt.gui.QPixmap;
+import com.trolltech.qt.gui.QPolygon;
+import com.trolltech.qt.gui.QRegion;
+import com.trolltech.qt.gui.QStyleOptionFocusRect;
+import com.trolltech.qt.gui.QStyle.PrimitiveElement;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTError;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.internal.qt.QtSWTConverter;
+
+/**
+ * Class <code>GC</code> is where all of the drawing capabilities that are
+ * supported by SWT are located. Instances are used to draw on either an
+ * <code>Image</code>, a <code>Control</code>, or directly on a
+ * <code>Display</code>.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>LEFT_TO_RIGHT, RIGHT_TO_LEFT</dd>
+ * </dl>
+ *
+ * <p>
+ * The SWT drawing coordinate system is the two-dimensional space with the
+ * origin (0,0) at the top left corner of the drawing area and with (x,y) values
+ * increasing to the right and downward respectively.
+ * </p>
+ *
+ * <p>
+ * The result of drawing on an image that was created with an indexed palette
+ * using a color that is not in the palette is platform specific. Some platforms
+ * will match to the nearest color while other will draw the color itself. This
+ * happens because the allocated image might use a direct palette on platforms
+ * that do not support indexed palette.
+ * </p>
+ *
+ * <p>
+ * Application code must explicitly invoke the <code>GC.dispose()</code> method
+ * to release the operating system resources managed by each instance when those
+ * instances are no longer required. This is <em>particularly</em> important on
+ * Windows95 and Windows98 where the operating system has a limited number of
+ * device contexts available.
+ * </p>
+ *
+ * <p>
+ * Note: Only one of LEFT_TO_RIGHT and RIGHT_TO_LEFT may be specified.
+ * </p>
+ *
+ * @see org.eclipse.swt.events.PaintEvent
+ * @see <a href="http://www.eclipse.org/swt/snippets/#gc">GC snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Examples:
+ * GraphicsExample, PaintExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ */
+public final class GC extends Resource {
+
+ /**
+ * the handle to the OS device context (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>
+ */
+ private QPaintDeviceInterface paintDevice;
+ private QPainter activePainter;
+ private QRegion activeClipping;
+
+ public int handle;
+
+ private Drawable drawable;
+ private GCData data;
+ private FillRule fillRule;
+
+ private int antialias = SWT.OFF; // TODO make sure this flag does not get lost, currently not interpreted
+
+ private static final int FOREGROUND = 1 << 0;
+ private static final int BACKGROUND = 1 << 1;
+ private static final int FONT = 1 << 2;
+ private static final int LINE_STYLE = 1 << 3;
+ private static final int LINE_WIDTH = 1 << 4;
+ private static final int LINE_CAP = 1 << 5;
+ private static final int LINE_JOIN = 1 << 6;
+ private static final int LINE_MITERLIMIT = 1 << 7;
+ private static final int FOREGROUND_TEXT = 1 << 8;
+ private static final int BACKGROUND_TEXT = 1 << 9;
+ private static final int BRUSH = 1 << 10;
+ private static final int PEN = 1 << 11;
+ private static final int NULL_BRUSH = 1 << 12;
+ private static final int NULL_PEN = 1 << 13;
+ private static final int DRAW_OFFSET = 1 << 14;
+
+ /**
+ * Prevents uninitialized instances from being created outside the package.
+ */
+ GC() {
+ }
+
+ /**
+ * Constructs a new instance of this class which has been configured to draw
+ * on the specified drawable. Sets the foreground color, background color
+ * and font in the GC to match those in the drawable.
+ * <p>
+ * You must dispose the graphics context when it is no longer required.
+ * </p>
+ *
+ * @param drawable
+ * the drawable to draw on
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the drawable is null</li>
+ * <li>ERROR_NULL_ARGUMENT - if there is no current device</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the drawable is an image
+ * that is not a bitmap or an icon - if the drawable is an
+ * image or printer that is already selected into another
+ * graphics context</li>
+ * </ul>
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_NO_HANDLES if a handle could not be obtained for
+ * GC creation</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS if not called from the
+ * thread that created the drawable</li>
+ * </ul>
+ */
+ public GC(Drawable drawable) {
+ this(drawable, SWT.NONE);
+ }
+
+ /**
+ * Constructs a new instance of this class which has been configured to draw
+ * on the specified drawable. Sets the foreground color, background color
+ * and font in the GC to match those in the drawable.
+ * <p>
+ * You must dispose the graphics context when it is no longer required.
+ * </p>
+ *
+ * @param drawable
+ * the drawable to draw on
+ * @param style
+ * the style of GC to construct
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the drawable is null</li>
+ * <li>ERROR_NULL_ARGUMENT - if there is no current device</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the drawable is an image
+ * that is not a bitmap or an icon - if the drawable is an
+ * image or printer that is already selected into another
+ * graphics context</li>
+ * </ul>
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_NO_HANDLES if a handle could not be obtained for
+ * GC creation</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS if not called from the
+ * thread that created the drawable</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+ public GC(Drawable drawable, int style) {
+ if (drawable == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+
+ GCData data = new GCData();
+ data.style = checkStyle(style);
+ QPaintDeviceInterface paintDevice = drawable.internal_new_GC(data);
+ Device device = data.device;
+ if (device == null) {
+ device = Device.getDevice();
+ }
+ if (device == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ this.device = data.device = device;
+ init(drawable, data, paintDevice);
+ init();
+ }
+
+ private QPainter getActivePainter() {
+ if (activePainter == null) {
+ activePainter = new QPainter();
+ // if (paintDevice.paintingActive()) {
+ //System.out.println("new painter for " + paintDevice + "active: " + paintDevice.paintingActive());
+ // //paintDevice.paintEngine().end();
+ // }
+ }
+
+ if (!activePainter.isActive()) {
+ activePainter.begin(paintDevice);
+ }
+
+ if (!activePainter.isActive()) {
+ System.out.println("inactive painter for: " + paintDevice + " painter: " //$NON-NLS-1$ //$NON-NLS-2$
+ + paintDevice.paintEngine().painter());
+ // RuntimeException re = new RuntimeException();
+ // re.printStackTrace();
+ }
+
+ if (activeClipping != null) {
+ activePainter.setClipRegion(activeClipping);
+ }
+ return activePainter;
+ }
+
+ static int checkStyle(int style) {
+ if ((style & SWT.LEFT_TO_RIGHT) != 0) {
+ style &= ~SWT.RIGHT_TO_LEFT;
+ }
+ return style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
+ }
+
+ void init(Drawable drawable, GCData data, QPaintDeviceInterface paintDevice) {
+ this.paintDevice = paintDevice;
+
+ Color foreground = data.foregroundColor;
+ if (foreground != null) {
+ data.state &= ~(FOREGROUND | FOREGROUND_TEXT | PEN);
+ } else {
+ data.foregroundColor = data.device.getSystemColor(SWT.COLOR_BLACK);
+ }
+ Color background = data.backgroundColor;
+ if (background != null) {
+ data.state &= ~(BACKGROUND | BACKGROUND_TEXT | BRUSH);
+ } else {
+ data.backgroundColor = data.device.getSystemColor(SWT.COLOR_WHITE);
+ }
+ data.state &= ~(NULL_BRUSH | NULL_PEN);
+ Font font = data.font;
+ if (font != null) {
+ data.state &= ~FONT;
+ } else {
+ data.font = device.getSystemFont();
+ }
+ Image image = data.image;
+ if (image != null) {
+ image.setMemGC(this);
+ }
+ if ((data.style & SWT.RIGHT_TO_LEFT) != 0) {
+ data.style |= SWT.MIRRORED;
+ }
+ this.drawable = drawable;
+ this.data = data;
+ }
+
+ /**
+ * Copies a rectangular area of the receiver at the specified position into
+ * the image, which must be of type <code>SWT.BITMAP</code>.
+ *
+ * @param image
+ * the image to copy into
+ * @param x
+ * the x coordinate in the receiver of the area to be copied
+ * @param y
+ * the y coordinate in the receiver of the area to be copied
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the image is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the image is not a bitmap
+ * or has been disposed</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void copyArea(Image image, int x, int y) {
+ // TODO
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ if (image == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (!image.isBitmap() || image.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ }
+
+ /**
+ * Copies a rectangular area of the receiver at the source position onto the
+ * receiver at the destination position.
+ *
+ * @param srcX
+ * the x coordinate in the receiver of the area to be copied
+ * @param srcY
+ * the y coordinate in the receiver of the area to be copied
+ * @param width
+ * the width of the area to copy
+ * @param height
+ * the height of the area to copy
+ * @param destX
+ * the x coordinate in the receiver of the area to copy to
+ * @param destY
+ * the y coordinate in the receiver of the area to copy to
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void copyArea(int srcX, int srcY, int width, int height, int destX, int destY) {
+ copyArea(srcX, srcY, width, height, destX, destY, true);
+ }
+
+ /**
+ * Copies a rectangular area of the receiver at the source position onto the
+ * receiver at the destination position.
+ *
+ * @param srcX
+ * the x coordinate in the receiver of the area to be copied
+ * @param srcY
+ * the y coordinate in the receiver of the area to be copied
+ * @param width
+ * the width of the area to copy
+ * @param height
+ * the height of the area to copy
+ * @param destX
+ * the x coordinate in the receiver of the area to copy to
+ * @param destY
+ * the y coordinate in the receiver of the area to copy to
+ * @param paint
+ * if <code>true</code> paint events will be generated for old
+ * and obscured areas
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+ public void copyArea(int srcX, int srcY, int width, int height, int destX, int destY, boolean paint) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ //TODO
+ /*
+ * Feature in WinCE. The function WindowFromDC is not part of the WinCE
+ * SDK. The fix is to remember the HWND.
+ */
+ // int /* long */hwnd = data.hwnd;
+ // if (hwnd == 0) {
+ // OS.BitBlt(handle, destX, destY, width, height, handle, srcX, srcY, OS.SRCCOPY);
+ // } else {
+ // RECT lprcClip = null;
+ // int /* long */hrgn = OS.CreateRectRgn(0, 0, 0, 0);
+ // if (OS.GetClipRgn(handle, hrgn) == 1) {
+ // lprcClip = new RECT();
+ // OS.GetRgnBox(hrgn, lprcClip);
+ // }
+ // OS.DeleteObject(hrgn);
+ // RECT lprcScroll = new RECT();
+ // OS.SetRect(lprcScroll, srcX, srcY, srcX + width, srcY + height);
+ // int flags = paint ? OS.SW_INVALIDATE | OS.SW_ERASE : 0;
+ // int res = OS.ScrollWindowEx(hwnd, destX - srcX, destY - srcY, lprcScroll, lprcClip, 0, null, flags);
+ //
+ // /*
+ // * Feature in WinCE. ScrollWindowEx does not accept combined
+ // * vertical and horizontal scrolling. The fix is to do a BitBlt and
+ // * invalidate the appropriate source area.
+ // */
+ // }
+ }
+
+ /**
+ * Disposes of the operating system resources associated with the graphics
+ * context. Applications must dispose of all GCs which they allocate.
+ *
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS if not called from the
+ * thread that created the drawable</li>
+ * </ul>
+ */
+ @Override
+ void destroy() {
+ if (activePainter != null) {
+ activePainter.end();
+ //System.out.println("end painter for " + paintDevice);
+ activePainter = null;
+ }
+
+ Image image = data.image;
+ if (image != null) {
+ image.setMemGC(null);
+ }
+
+ if (drawable != null) {
+ drawable.internal_dispose_GC(paintDevice, data);
+ }
+ drawable = null;
+ data.image = null;
+ data = null;
+ paintDevice = null;
+ }
+
+ /**
+ * Draws the outline of a circular or elliptical arc within the specified
+ * rectangular area.
+ * <p>
+ * The resulting arc begins at <code>startAngle</code> and extends for
+ * <code>arcAngle</code> degrees, using the current color. Angles are
+ * interpreted such that 0 degrees is at the 3 o'clock position. A positive
+ * value indicates a counter-clockwise rotation while a negative value
+ * indicates a clockwise rotation.
+ * </p>
+ * <p>
+ * The center of the arc is the center of the rectangle whose origin is (
+ * <code>x</code>, <code>y</code>) and whose size is specified by the
+ * <code>width</code> and <code>height</code> arguments.
+ * </p>
+ * <p>
+ * The resulting arc covers an area <code>width + 1</code> pixels wide by
+ * <code>height + 1</code> pixels tall.
+ * </p>
+ *
+ * @param x
+ * the x coordinate of the upper-left corner of the arc to be
+ * drawn
+ * @param y
+ * the y coordinate of the upper-left corner of the arc to be
+ * drawn
+ * @param width
+ * the width of the arc to be drawn
+ * @param height
+ * the height of the arc to be drawn
+ * @param startAngle
+ * the beginning angle
+ * @param arcAngle
+ * the angular extent of the arc, relative to the start angle
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+
+ QPainter painter = getActivePainter();
+ painter.setPen(getForeground().getColor());
+ painter.drawArc(x, y, width, height, startAngle, arcAngle);
+ }
+
+ /**
+ * Draws a rectangle, based on the specified arguments, which has the
+ * appearance of the platform's <em>focus rectangle</em> if the platform
+ * supports such a notion, and otherwise draws a simple rectangle in the
+ * receiver's foreground color.
+ *
+ * @param x
+ * the x coordinate of the rectangle
+ * @param y
+ * the y coordinate of the rectangle
+ * @param width
+ * the width of the rectangle
+ * @param height
+ * the height of the rectangle
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see #drawRectangle(int, int, int, int)
+ */
+ public void drawFocus(int x, int y, int width, int height) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+
+ QPainter painter = getActivePainter();
+ painter.setPen(getForeground().getColor());
+ QStyleOptionFocusRect option = new QStyleOptionFocusRect();
+ option.rect().setRect(x, y, width, height);
+ QApplication.style().drawPrimitive(PrimitiveElement.PE_FrameFocusRect, option, painter);
+ }
+
+ /**
+ * Draws the given image in the receiver at the specified coordinates.
+ *
+ * @param image
+ * the image to draw
+ * @param x
+ * the x coordinate of where to draw
+ * @param y
+ * the y coordinate of where to draw
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the image is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the image has been
+ * disposed</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the given coordinates are
+ * outside the bounds of the image</li>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_NO_HANDLES - if no handles are available to
+ * perform the operation</li>
+ * </ul>
+ */
+ public void drawImage(Image image, int x, int y) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (image == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (image.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+
+ QPainter painter = getActivePainter();
+ QPixmap pic = image.getQPixmap();
+ painter.drawPixmap(x, y, pic);
+ }
+
+ /**
+ * Copies a rectangular area from the source image into a (potentially
+ * different sized) rectangular area in the receiver. If the source and
+ * destination areas are of differing sizes, then the source area will be
+ * stretched or shrunk to fit the destination area as it is copied. The copy
+ * fails if any part of the source rectangle lies outside the bounds of the
+ * source image, or if any of the width or height arguments are negative.
+ *
+ * @param image
+ * the source image
+ * @param srcX
+ * the x coordinate in the source image to copy from
+ * @param srcY
+ * the y coordinate in the source image to copy from
+ * @param srcWidth
+ * the width in pixels to copy from the source
+ * @param srcHeight
+ * the height in pixels to copy from the source
+ * @param destX
+ * the x coordinate in the destination to copy to
+ * @param destY
+ * the y coordinate in the destination to copy to
+ * @param destWidth
+ * the width in pixels of the destination rectangle
+ * @param destHeight
+ * the height in pixels of the destination rectangle
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the image is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the image has been
+ * disposed</li>
+ * <li>ERROR_INVALID_ARGUMENT - if any of the width or height
+ * arguments are negative.
+ * <li>ERROR_INVALID_ARGUMENT - if the source rectangle is
+ * not contained within the bounds of the source image</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_NO_HANDLES - if no handles are available to
+ * perform the operation</li>
+ * </ul>
+ */
+ public void drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY,
+ int destWidth, int destHeight) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (srcWidth == 0 || srcHeight == 0 || destWidth == 0 || destHeight == 0) {
+ return;
+ }
+ if (srcX < 0 || srcY < 0 || srcWidth < 0 || srcHeight < 0 || destWidth < 0 || destHeight < 0) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ if (image == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (image.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+
+ QPainter painter = getActivePainter();
+ painter.drawPixmap(new QRect(destX, destY, destWidth, destHeight), image.getQPixmap(), new QRect(srcX, srcY,
+ srcWidth, srcHeight));
+ }
+
+ /**
+ * Draws a line, using the foreground color, between the points (
+ * <code>x1</code>, <code>y1</code>) and (<code>x2</code>, <code>y2</code>).
+ *
+ * @param x1
+ * the first point's x coordinate
+ * @param y1
+ * the first point's y coordinate
+ * @param x2
+ * the second point's x coordinate
+ * @param y2
+ * the second point's y coordinate
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void drawLine(int x1, int y1, int x2, int y2) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+
+ QPainter painter = getActivePainter();
+ painter.setPen(getForeground().getColor());
+ painter.drawLine(x1, y1, x2, y2);
+ }
+
+ /**
+ * Draws the outline of an oval, using the foreground color, within the
+ * specified rectangular area.
+ * <p>
+ * The result is a circle or ellipse that fits within the rectangle
+ * specified by the <code>x</code>, <code>y</code>, <code>width</code>, and
+ * <code>height</code> arguments.
+ * </p>
+ * <p>
+ * The oval covers an area that is <code>width + 1</code> pixels wide and
+ * <code>height + 1</code> pixels tall.
+ * </p>
+ *
+ * @param x
+ * the x coordinate of the upper left corner of the oval to be
+ * drawn
+ * @param y
+ * the y coordinate of the upper left corner of the oval to be
+ * drawn
+ * @param width
+ * the width of the oval to be drawn
+ * @param height
+ * the height of the oval to be drawn
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void drawOval(int x, int y, int width, int height) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+
+ QPainter painter = getActivePainter();
+ painter.setPen(getForeground().getColor());
+ painter.drawEllipse(x, y, width, height);
+ }
+
+ /**
+ * Draws the path described by the parameter.
+ * <p>
+ * This operation requires the operating system's advanced graphics
+ * subsystem which may not be available on some platforms.
+ * </p>
+ *
+ * @param path
+ * the path to draw
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parameter is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the parameter has been
+ * disposed</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are
+ * not available</li>
+ * </ul>
+ *
+ * @see Path
+ *
+ * @since 3.1
+ */
+ public void drawPath(Path path) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ if (path == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (path.handle == 0) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ //checkGC(DRAW);
+ //TODO
+ // int /* long */gdipGraphics = data.gdipGraphics;
+ // Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend);
+ // Gdip.Graphics_DrawPath(gdipGraphics, data.gdipPen, path.handle);
+ // Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset, Gdip.MatrixOrderPrepend);
+ }
+ }
+
+ /**
+ * Draws a pixel, using the foreground color, at the specified point (
+ * <code>x</code>, <code>y</code>).
+ * <p>
+ * Note that the receiver's line attributes do not affect this operation.
+ * </p>
+ *
+ * @param x
+ * the point's x coordinate
+ * @param y
+ * the point's y coordinate
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+ public void drawPoint(int x, int y) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+
+ QPainter painter = getActivePainter();
+ painter.setPen(getForeground().getColor());
+ painter.drawPoint(x, y);
+ }
+
+ /**
+ * Draws the closed polygon which is defined by the specified array of
+ * integer coordinates, using the receiver's foreground color. The array
+ * contains alternating x and y values which are considered to represent
+ * points which are the vertices of the polygon. Lines are drawn between
+ * each consecutive pair, and between the first pair and last pair in the
+ * array.
+ *
+ * @param pointArray
+ * an array of alternating x and y values which are the vertices
+ * of the polygon
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT if pointArray is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void drawPolygon(int[] pointArray) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ validatePointArray(pointArray);
+ QPainter painter = getActivePainter();
+ painter.setPen(getForeground().getColor());
+ painter.drawPolygon(createPolygonFromArray(pointArray));
+ }
+
+ /**
+ * Draws the polyline which is defined by the specified array of integer
+ * coordinates, using the receiver's foreground color. The array contains
+ * alternating x and y values which are considered to represent points which
+ * are the corners of the polyline. Lines are drawn between each consecutive
+ * pair, but not between the first pair and last pair in the array.
+ *
+ * @param pointArray
+ * an array of alternating x and y values which are the corners
+ * of the polyline
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the point array is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void drawPolyline(int[] pointArray) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (pointArray == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ validatePointArray(pointArray);
+ QPainter painter = getActivePainter();
+ painter.setPen(getForeground().getColor());
+ painter.drawPolyline(createPolygonFromArray(pointArray));
+ }
+
+ /**
+ * Draws the outline of the rectangle specified by the arguments, using the
+ * receiver's foreground color. The left and right edges of the rectangle
+ * are at <code>x</code> and <code>x + width</code>. The top and bottom
+ * edges are at <code>y</code> and <code>y + height</code>.
+ *
+ * @param x
+ * the x coordinate of the rectangle to be drawn
+ * @param y
+ * the y coordinate of the rectangle to be drawn
+ * @param width
+ * the width of the rectangle to be drawn
+ * @param height
+ * the height of the rectangle to be drawn
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void drawRectangle(int x, int y, int width, int height) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+
+ QPainter painter = getActivePainter();
+ painter.setPen(getForeground().getColor());
+ painter.drawRect(x, y, width, height);
+ }
+
+ /**
+ * Draws the outline of the specified rectangle, using the receiver's
+ * foreground color. The left and right edges of the rectangle are at
+ * <code>rect.x</code> and <code>rect.x + rect.width</code>. The top and
+ * bottom edges are at <code>rect.y</code> and
+ * <code>rect.y + rect.height</code>.
+ *
+ * @param rect
+ * the rectangle to draw
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void drawRectangle(Rectangle rect) {
+ if (rect == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ drawRectangle(rect.x, rect.y, rect.width, rect.height);
+ }
+
+ /**
+ * Draws the outline of the round-cornered rectangle specified by the
+ * arguments, using the receiver's foreground color. The left and right
+ * edges of the rectangle are at <code>x</code> and <code>x + width</code>.
+ * The top and bottom edges are at <code>y</code> and
+ * <code>y + height</code>. The <em>roundness</em> of the corners is
+ * specified by the <code>arcWidth</code> and <code>arcHeight</code>
+ * arguments, which are respectively the width and height of the ellipse
+ * used to draw the corners.
+ *
+ * @param x
+ * the x coordinate of the rectangle to be drawn
+ * @param y
+ * the y coordinate of the rectangle to be drawn
+ * @param width
+ * the width of the rectangle to be drawn
+ * @param height
+ * the height of the rectangle to be drawn
+ * @param arcWidth
+ * the width of the arc
+ * @param arcHeight
+ * the height of the arc
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void drawRoundRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+
+ QPainter painter = getActivePainter();
+ painter.setPen(getForeground().getColor());
+ painter.drawRoundedRect(x, y, width, height, arcWidth, arcHeight, SizeMode.AbsoluteSize);
+ }
+
+ /**
+ * Draws the given string, using the receiver's current font and foreground
+ * color. No tab expansion or carriage return processing will be performed.
+ * The background of the rectangular area where the string is being drawn
+ * will be filled with the receiver's background color.
+ *
+ * @param string
+ * the string to be drawn
+ * @param x
+ * the x coordinate of the top left corner of the rectangular
+ * area where the string is to be drawn
+ * @param y
+ * the y coordinate of the top left corner of the rectangular
+ * area where the string is to be drawn
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void drawString(String string, int x, int y) {
+ drawString(string, x, y, false);
+ }
+
+ /**
+ * Draws the given string, using the receiver's current font and foreground
+ * color. No tab expansion or carriage return processing will be performed.
+ * If <code>isTransparent</code> is <code>true</code>, then the background
+ * of the rectangular area where the string is being drawn will not be
+ * modified, otherwise it will be filled with the receiver's background
+ * color.
+ *
+ * @param string
+ * the string to be drawn
+ * @param x
+ * the x coordinate of the top left corner of the rectangular
+ * area where the string is to be drawn
+ * @param y
+ * the y coordinate of the top left corner of the rectangular
+ * area where the string is to be drawn
+ * @param isTransparent
+ * if <code>true</code> the background will be transparent,
+ * otherwise it will be opaque
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void drawString(String string, int x, int y, boolean isTransparent) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+
+ QPainter painter = getActivePainter();
+ if (isTransparent) {
+ painter.setBackgroundMode(BGMode.TransparentMode);
+ } else {
+ painter.setBackgroundMode(BGMode.OpaqueMode);
+ painter.setBackground(new QBrush(getBackground().getColor()));
+ }
+ painter.setFont(data.font.getQFont());
+ painter.setPen(getForeground().getColor());
+ //System.out.println("drawText(" + x + ", " + y + ", " + string + ")");
+
+ painter.drawText(x, y + getHightCorrection(painter), string);
+ }
+
+ private int getHightCorrection(QPainter painter) {
+ QFontMetrics fm = painter.fontMetrics();
+ return fm.ascent();
+ }
+
+ /**
+ * Draws the given string, using the receiver's current font and foreground
+ * color. Tab expansion and carriage return processing are performed. The
+ * background of the rectangular area where the text is being drawn will be
+ * filled with the receiver's background color.
+ *
+ * @param string
+ * the string to be drawn
+ * @param x
+ * the x coordinate of the top left corner of the rectangular
+ * area where the text is to be drawn
+ * @param y
+ * the y coordinate of the top left corner of the rectangular
+ * area where the text is to be drawn
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void drawText(String string, int x, int y) {
+ drawText(string, x, y, SWT.DRAW_DELIMITER | SWT.DRAW_TAB);
+ }
+
+ /**
+ * Draws the given string, using the receiver's current font and foreground
+ * color. Tab expansion and carriage return processing are performed. If
+ * <code>isTransparent</code> is <code>true</code>, then the background of
+ * the rectangular area where the text is being drawn will not be modified,
+ * otherwise it will be filled with the receiver's background color.
+ *
+ * @param string
+ * the string to be drawn
+ * @param x
+ * the x coordinate of the top left corner of the rectangular
+ * area where the text is to be drawn
+ * @param y
+ * the y coordinate of the top left corner of the rectangular
+ * area where the text is to be drawn
+ * @param isTransparent
+ * if <code>true</code> the background will be transparent,
+ * otherwise it will be opaque
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void drawText(String string, int x, int y, boolean isTransparent) {
+ int flags = SWT.DRAW_DELIMITER | SWT.DRAW_TAB;
+ if (isTransparent) {
+ flags |= SWT.DRAW_TRANSPARENT;
+ }
+ drawText(string, x, y, flags);
+ }
+
+ /**
+ * Draws the given string, using the receiver's current font and foreground
+ * color. Tab expansion, line delimiter and mnemonic processing are
+ * performed according to the specified flags. If <code>flags</code>
+ * includes <code>DRAW_TRANSPARENT</code>, then the background of the
+ * rectangular area where the text is being drawn will not be modified,
+ * otherwise it will be filled with the receiver's background color.
+ * <p>
+ * The parameter <code>flags</code> may be a combination of:
+ * <dl>
+ * <dt><b>DRAW_DELIMITER</b></dt>
+ * <dd>draw multiple lines</dd>
+ * <dt><b>DRAW_TAB</b></dt>
+ * <dd>expand tabs</dd>
+ * <dt><b>DRAW_MNEMONIC</b></dt>
+ * <dd>underline the mnemonic character</dd>
+ * <dt><b>DRAW_TRANSPARENT</b></dt>
+ * <dd>transparent background</dd>
+ * </dl>
+ * </p>
+ *
+ * @param string
+ * the string to be drawn
+ * @param x
+ * the x coordinate of the top left corner of the rectangular
+ * area where the text is to be drawn
+ * @param y
+ * the y coordinate of the top left corner of the rectangular
+ * area where the text is to be drawn
+ * @param flags
+ * the flags specifying how to process the text
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void drawText(String string, int x, int y, int flags) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+
+ QPainter painter = getActivePainter();
+ if ((flags & SWT.DRAW_TRANSPARENT) != 0) {
+ painter.setBackgroundMode(BGMode.TransparentMode);
+ painter.setBackground(new QBrush(getBackground().getColor()));
+ }
+
+ int translatedFlags = translateTextFlags(flags);
+
+ painter.setPen(getForeground().getColor());
+
+ QRect r = painter.boundingRect(0, 0, 0, 0, translatedFlags, string);
+
+ //System.out.println("drawText(" + x + ", " + y + ", " + r.width() + ", " + r.height() + ", " + string + ")");
+ painter.drawText(x, y, r.width(), r.height(), translatedFlags, string);
+ }
+
+ /**
+ * @param flags
+ * @return
+ */
+ private int translateTextFlags(int flags) {
+ int translatedFlags = AlignmentFlag.AlignTop.value() | AlignmentFlag.AlignLeft.value();
+ if ((flags & SWT.DRAW_DELIMITER) == 0) {
+ translatedFlags |= TextFlag.TextSingleLine.value();
+ }
+ if ((flags & SWT.DRAW_TAB) != 0) {
+ translatedFlags |= TextFlag.TextExpandTabs.value();
+ }
+ if ((flags & SWT.DRAW_MNEMONIC) != 0) {
+ translatedFlags |= TextFlag.TextShowMnemonic.value();
+ }
+ return translatedFlags;
+ }
+
+ /**
+ * Compares the argument to the receiver, and returns true if they represent
+ * the <em>same</em> object using a class specific comparison.
+ *
+ * @param object
+ * the object to compare with this object
+ * @return <code>true</code> if the object is the same as this object and
+ * <code>false</code> otherwise
+ *
+ * @see #hashCode
+ */
+ @Override
+ public boolean equals(Object object) {
+ return object == this || object instanceof GC && paintDevice == ((GC) object).paintDevice;
+ }
+
+ /**
+ * Fills the interior of a circular or elliptical arc within the specified
+ * rectangular area, with the receiver's background color.
+ * <p>
+ * The resulting arc begins at <code>startAngle</code> and extends for
+ * <code>arcAngle</code> degrees, using the current color. Angles are
+ * interpreted such that 0 degrees is at the 3 o'clock position. A positive
+ * value indicates a counter-clockwise rotation while a negative value
+ * indicates a clockwise rotation.
+ * </p>
+ * <p>
+ * The center of the arc is the center of the rectangle whose origin is (
+ * <code>x</code>, <code>y</code>) and whose size is specified by the
+ * <code>width</code> and <code>height</code> arguments.
+ * </p>
+ * <p>
+ * The resulting arc covers an area <code>width + 1</code> pixels wide by
+ * <code>height + 1</code> pixels tall.
+ * </p>
+ *
+ * @param x
+ * the x coordinate of the upper-left corner of the arc to be
+ * filled
+ * @param y
+ * the y coordinate of the upper-left corner of the arc to be
+ * filled
+ * @param width
+ * the width of the arc to be filled
+ * @param height
+ * the height of the arc to be filled
+ * @param startAngle
+ * the beginning angle
+ * @param arcAngle
+ * the angular extent of the arc, relative to the start angle
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see #drawArc
+ */
+ public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+
+ QPainter painter = getActivePainter();
+ painter.setBrush(getBackground().getColor());
+ //painter.setPen(getBackground().getColor());
+ painter.setPen(PenStyle.NoPen);
+ painter.drawArc(x, y, width, height, startAngle, arcAngle);
+ }
+
+ /**
+ * Fills the interior of the specified rectangle with a gradient sweeping
+ * from left to right or top to bottom progressing from the receiver's
+ * foreground color to its background color.
+ *
+ * @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, may be negative
+ * (inverts direction of gradient if horizontal)
+ * @param height
+ * the height of the rectangle to be filled, may be negative
+ * (inverts direction of gradient if vertical)
+ * @param vertical
+ * if true sweeps from top to bottom, else sweeps from left to
+ * right
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see #drawRectangle(int, int, int, int)
+ */
+ public void fillGradientRectangle(int x, int y, int width, int height, boolean vertical) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (width == 0 || height == 0) {
+ return;
+ }
+ // if (true) {
+ // return;
+ // }
+
+ QColor fromColor = getForeground().getColor();
+ QColor toColor = getBackground().getColor();
+
+ boolean swapColors = false;
+ if (width < 0) {
+ x += width;
+ width = -width;
+ if (!vertical) {
+ swapColors = true;
+ }
+ }
+ if (height < 0) {
+ y += height;
+ height = -height;
+ if (vertical) {
+ swapColors = true;
+ }
+ }
+ if (swapColors) {
+ QColor tmp = fromColor;
+ fromColor = toColor;
+ toColor = tmp;
+ }
+ if (fromColor.equals(toColor)) {
+ fillRectangle(x, y, width, height);
+ return;
+ }
+
+ QPointF p1 = new QPointF(), p2 = new QPointF();
+ p1.setX(x);
+ p1.setY(y);
+ if (vertical) {
+ p2.setX(p1.x());
+ p2.setY(p1.y() + height);
+ } else {
+ p2.setX(p1.x() + width);
+ p2.setY(p1.y());
+ }
+ QPainter painter = getActivePainter();
+ QLinearGradient fade = new QLinearGradient(p1, p2);
+ fade.setColorAt(0.0, fromColor);
+ fade.setColorAt(1.0, toColor);
+ QBrush brush = new QBrush(fade);
+ painter.fillRect(x, y, width, height, brush);
+ }
+
+ /**
+ * Fills the interior of an oval, within the specified rectangular area,
+ * with the receiver's background color.
+ *
+ * @param x
+ * the x coordinate of the upper left corner of the oval to be
+ * filled
+ * @param y
+ * the y coordinate of the upper left corner of the oval to be
+ * filled
+ * @param width
+ * the width of the oval to be filled
+ * @param height
+ * the height of the oval to be filled
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see #drawOval
+ */
+ public void fillOval(int x, int y, int width, int height) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+
+ QPainter painter = getActivePainter();
+ painter.setBrush(getBackground().getColor());
+ painter.setPen(getBackground().getColor());
+ painter.drawEllipse(x, y, width, height);
+ }
+
+ /**
+ * Fills the path described by the parameter.
+ * <p>
+ * This operation requires the operating system's advanced graphics
+ * subsystem which may not be available on some platforms.
+ * </p>
+ *
+ * @param path
+ * the path to fill
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parameter is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the parameter has been
+ * disposed</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are
+ * not available</li>
+ * </ul>
+ *
+ * @see Path
+ *
+ * @since 3.1
+ */
+ public void fillPath(Path path) {
+ //TODO
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ if (path == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (path.handle == 0) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ }
+
+ /**
+ * Fills the interior of the closed polygon which is defined by the
+ * specified array of integer coordinates, using the receiver's background
+ * color. The array contains alternating x and y values which are considered
+ * to represent points which are the vertices of the polygon. Lines are
+ * drawn between each consecutive pair, and between the first pair and last
+ * pair in the array.
+ *
+ * @param pointArray
+ * an array of alternating x and y values which are the vertices
+ * of the polygon
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT if pointArray is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see #drawPolygon
+ */
+ public void fillPolygon(int[] pointArray) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ validatePointArray(pointArray);
+ QPainter painter = getActivePainter();
+ painter.setBrush(getBackground().getColor());
+ painter.setPen(getBackground().getColor());
+ painter.drawPolygon(createPolygonFromArray(pointArray), FillRule.WindingFill);
+ }
+
+ private void validatePointArray(int[] pointArray) {
+ if (pointArray == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (pointArray.length % 2 != 0) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+
+ }
+
+ public static QPolygon createPolygonFromArray(int[] pointArray) {
+ QPolygon polygon = new QPolygon();
+ for (int i = 0; i < pointArray.length; i += 2) {
+ polygon.add(pointArray[i], pointArray[i + 1]);
+ }
+ return polygon;
+ }
+
+ /**
+ * Fills the interior of the rectangle specified by the arguments, using the
+ * receiver's background color.
+ *
+ * @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 SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see #drawRectangle(int, int, int, int)
+ */
+ public void fillRectangle(int x, int y, int width, int height) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (width < 0) {
+ x = x + width;
+ width = -width;
+ }
+ if (height < 0) {
+ y = y + height;
+ height = -height;
+ }
+ QPainter painter = getActivePainter();
+ painter.fillRect(x, y, width, height, getBackground().getColor());
+ }
+
+ /**
+ * Fills the interior of the specified rectangle, using the receiver's
+ * background color.
+ *
+ * @param rect
+ * the rectangle to be filled
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see #drawRectangle(int, int, int, int)
+ */
+ public void fillRectangle(Rectangle rect) {
+ if (rect == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ fillRectangle(rect.x, rect.y, rect.width, rect.height);
+ }
+
+ /**
+ * Fills the interior of the round-cornered rectangle specified by the
+ * arguments, using the receiver's background color.
+ *
+ * @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
+ * @param arcWidth
+ * the width of the arc
+ * @param arcHeight
+ * the height of the arc
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see #drawRoundRectangle
+ */
+ public void fillRoundRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+
+ QPainter painter = getActivePainter();
+ painter.setBrush(getBackground().getColor());
+ painter.setPen(getBackground().getColor());
+ painter.drawRoundedRect(x, y, width, height, arcWidth, arcHeight);
+ }
+
+ void flush() {
+ }
+
+ /**
+ * Returns the <em>advance width</em> of the specified character in the font
+ * which is currently selected into the receiver.
+ * <p>
+ * The advance width is defined as the horizontal distance the cursor should
+ * move after printing the character in the selected font.
+ * </p>
+ *
+ * @param ch
+ * the character to measure
+ * @return the distance in the x direction to move past the character before
+ * painting the next
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public int getAdvanceWidth(char ch) {
+
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+
+ QPainter activePainter = getActivePainter();
+ return activePainter.fontMetrics().width(ch);
+ // //checkGC(FONT);
+ // int tch = ch;
+ // if (ch > 0x7F) {
+ // TCHAR buffer = new TCHAR(getCodePage(), ch, false);
+ // tch = buffer.tcharAt(0);
+ // }
+ // int[] width = new int[1];
+ // OS.GetCharWidth(handle, tch, tch, width);
+ // return width[0];
+ }
+
+ /**
+ * Returns the receiver's alpha value. The alpha value is between 0
+ * (transparent) and 255 (opaque).
+ *
+ * @return the alpha value
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+ public int getAlpha() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return data.alpha;
+ }
+
+ /**
+ * Returns the receiver's anti-aliasing setting value, which will be one of
+ * <code>SWT.DEFAULT</code>, <code>SWT.OFF</code> or <code>SWT.ON</code>.
+ * Note that this controls anti-aliasing for all <em>non-text drawing</em>
+ * operations.
+ *
+ * @return the anti-aliasing setting
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see #getTextAntialias
+ *
+ * @since 3.1
+ */
+ public int getAntialias() {
+ return antialias;
+ // if (handle == 0) {
+ // SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ // }
+ // if (data.gdipGraphics == 0)
+ // return SWT.DEFAULT;
+ // int mode = Gdip.Graphics_GetSmoothingMode(data.gdipGraphics);
+ // switch (mode) {
+ // case Gdip.SmoothingModeDefault:
+ // return SWT.DEFAULT;
+ // case Gdip.SmoothingModeHighSpeed:
+ // case Gdip.SmoothingModeNone:
+ // return SWT.OFF;
+ // case Gdip.SmoothingModeAntiAlias:
+ // case Gdip.SmoothingModeAntiAlias8x8:
+ // case Gdip.SmoothingModeHighQuality:
+ // return SWT.ON;
+ // }
+ // return SWT.DEFAULT;
+ }
+
+ /**
+ * Returns the background color.
+ *
+ * @return the receiver's background color
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public Color getBackground() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return data.backgroundColor;
+ }
+
+ /**
+ * Returns the background pattern. The default value is <code>null</code>.
+ *
+ * @return the receiver's background pattern
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see Pattern
+ *
+ * @since 3.1
+ */
+ public Pattern getBackgroundPattern() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return data.backgroundPattern;
+ }
+
+ /**
+ * Returns the width of the specified character in the font selected into
+ * the receiver.
+ * <p>
+ * The width is defined as the space taken up by the actual character, not
+ * including the leading and tailing whitespace or overhang.
+ * </p>
+ *
+ * @param ch
+ * the character to measure
+ * @return the width of the character
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public int getCharWidth(char ch) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ //checkGC(FONT);
+ // TODO
+ return 10;
+ }
+
+ /**
+ * Returns the bounding rectangle of the receiver's clipping region. If no
+ * clipping region is set, the return value will be a rectangle which covers
+ * the entire bounds of the object the receiver is drawing on.
+ *
+ * @return the bounding rectangle of the clipping region
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public Rectangle getClipping() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+
+ QPainter painter = getActivePainter();
+ if (painter.hasClipping()) {
+ return QtSWTConverter.convert(painter.clipRegion());
+ } else {
+ return new Rectangle(0, 0, paintDevice.width(), paintDevice.height());
+ }
+ }
+
+ /**
+ * Sets the region managed by the argument to the current clipping region of
+ * the receiver.
+ *
+ * @param region
+ * the region to fill with the clipping region
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the region is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the region is disposed</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void getClipping(Region region) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (region == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (region.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+
+ QPainter painter = getActivePainter();
+ Rectangle rect;
+ if (painter.hasClipping()) {
+ rect = QtSWTConverter.convert(painter.clipRegion());
+ } else {
+ rect = new Rectangle(0, 0, paintDevice.width(), paintDevice.height());
+ }
+ region.add(rect);
+ }
+
+ /**
+ * Returns the receiver's fill rule, which will be one of
+ * <code>SWT.FILL_EVEN_ODD</code> or <code>SWT.FILL_WINDING</code>.
+ *
+ * @return the receiver's fill rule
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+ public int getFillRule() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (fillRule == null || fillRule.equals(FillRule.WindingFill)) {
+ return SWT.FILL_WINDING;
+ }
+ return SWT.FILL_EVEN_ODD;
+ }
+
+ /**
+ * Sets the receiver's fill rule to the parameter, which must be one of
+ * <code>SWT.FILL_EVEN_ODD</code> or <code>SWT.FILL_WINDING</code>.
+ *
+ * @param rule
+ * the new fill rule
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the rule is not one of
+ * <code>SWT.FILL_EVEN_ODD</code> or
+ * <code>SWT.FILL_WINDING</code></li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+ public void setFillRule(int rule) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ switch (rule) {
+ case SWT.FILL_WINDING:
+ fillRule = FillRule.WindingFill;
+ break;
+ case SWT.FILL_EVEN_ODD:
+ fillRule = FillRule.OddEvenFill;
+ break;
+ default:
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ }
+
+ /**
+ * Returns the font currently being used by the receiver to draw and measure
+ * text.
+ *
+ * @return the receiver's font
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public Font getFont() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return data.font;
+ }
+
+ /**
+ * Returns a FontMetrics which contains information about the font currently
+ * being used by the receiver to draw and measure text.
+ *
+ * @return font metrics for the receiver's font
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public FontMetrics getFontMetrics() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ //checkGC(FONT);
+ //if (!paintDevice.paintingActive()) {
+ return FontMetrics.internal_new(data.font);
+ // }
+ // QPainter painter = getActivePainter();
+ // painter.setFont(data.font.getQFont());
+ // try {
+ // return FontMetrics.internal_new(painter.fontMetrics());
+ // } finally {
+ // painter.end();
+ // }
+
+ }
+
+ /**
+ * Returns the receiver's foreground color.
+ *
+ * @return the color used for drawing foreground things
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public Color getForeground() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return data.foregroundColor;
+ }
+
+ /**
+ * Returns the foreground pattern. The default value is <code>null</code>.
+ *
+ * @return the receiver's foreground pattern
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see Pattern
+ *
+ * @since 3.1
+ */
+ public Pattern getForegroundPattern() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return data.foregroundPattern;
+ }
+
+ /**
+ * Returns the GCData.
+ * <p>
+ * <b>IMPORTANT:</b> This method is <em>not</em> part of the public API for
+ * <code>GC</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>
+ *
+ * @return the receiver's GCData
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see GCData
+ *
+ * @since 3.2
+ * @noreference This method is not intended to be referenced by clients.
+ */
+ public GCData getGCData() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return data;
+ }
+
+ /**
+ * Returns the receiver's interpolation setting, which will be one of
+ * <code>SWT.DEFAULT</code>, <code>SWT.NONE</code>, <code>SWT.LOW</code> or
+ * <code>SWT.HIGH</code>.
+ *
+ * @return the receiver's interpolation setting
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+ public int getInterpolation() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return SWT.DEFAULT;
+ //TODO
+ // int mode = Gdip.Graphics_GetInterpolationMode(data.gdipGraphics);
+ // switch (mode) {
+ // case Gdip.InterpolationModeDefault:
+ // return SWT.DEFAULT;
+ // case Gdip.InterpolationModeNearestNeighbor:
+ // return SWT.NONE;
+ // case Gdip.InterpolationModeBilinear:
+ // case Gdip.InterpolationModeLowQuality:
+ // return SWT.LOW;
+ // case Gdip.InterpolationModeBicubic:
+ // case Gdip.InterpolationModeHighQualityBilinear:
+ // case Gdip.InterpolationModeHighQualityBicubic:
+ // case Gdip.InterpolationModeHighQuality:
+ // return SWT.HIGH;
+ // }
+ // return SWT.DEFAULT;
+ }
+
+ /**
+ * Returns the receiver's line attributes.
+ *
+ * @return the line attributes used for drawing lines
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.3
+ */
+ public LineAttributes getLineAttributes() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ float[] dashes = null;
+ if (data.lineDashes != null) {
+ dashes = new float[data.lineDashes.length];
+ System.arraycopy(data.lineDashes, 0, dashes, 0, dashes.length);
+ }
+ return new LineAttributes(data.lineWidth, data.lineCap, data.lineJoin, data.lineStyle, dashes,
+ data.lineDashesOffset, data.lineMiterLimit);
+ }
+
+ /**
+ * Returns the receiver's line cap style, which will be one of the constants
+ * <code>SWT.CAP_FLAT</code>, <code>SWT.CAP_ROUND</code>, or
+ * <code>SWT.CAP_SQUARE</code>.
+ *
+ * @return the cap style used for drawing lines
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+ public int getLineCap() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return data.lineCap;
+ }
+
+ /**
+ * Returns the receiver's line dash style. The default value is
+ * <code>null</code>.
+ *
+ * @return the line dash style used for drawing lines
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+ public int[] getLineDash() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (data.lineDashes == null) {
+ return null;
+ }
+ int[] lineDashes = new int[data.lineDashes.length];
+ for (int i = 0; i < lineDashes.length; i++) {
+ lineDashes[i] = (int) data.lineDashes[i];
+ }
+ return lineDashes;
+ }
+
+ /**
+ * Returns the receiver's line join style, which will be one of the
+ * constants <code>SWT.JOIN_MITER</code>, <code>SWT.JOIN_ROUND</code>, or
+ * <code>SWT.JOIN_BEVEL</code>.
+ *
+ * @return the join style used for drawing lines
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+ public int getLineJoin() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return data.lineJoin;
+ }
+
+ /**
+ * Returns the receiver's line style, which will be one of the constants
+ * <code>SWT.LINE_SOLID</code>, <code>SWT.LINE_DASH</code>,
+ * <code>SWT.LINE_DOT</code>, <code>SWT.LINE_DASHDOT</code> or
+ * <code>SWT.LINE_DASHDOTDOT</code>.
+ *
+ * @return the style used for drawing lines
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public int getLineStyle() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return data.lineStyle;
+ }
+
+ /**
+ * Returns the width that will be used when drawing lines for all of the
+ * figure drawing operations (that is, <code>drawLine</code>,
+ * <code>drawRectangle</code>, <code>drawPolyline</code>, and so forth.
+ *
+ * @return the receiver's line width
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public int getLineWidth() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return (int) data.lineWidth;
+ }
+
+ /**
+ * 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.
+ * </p>
+ *
+ * @return the style bits
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 2.1.2
+ */
+ public int getStyle() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return data.style;
+ }
+
+ /**
+ * Returns the receiver's text drawing anti-aliasing setting value, which
+ * will be one of <code>SWT.DEFAULT</code>, <code>SWT.OFF</code> or
+ * <code>SWT.ON</code>. Note that this controls anti-aliasing <em>only</em>
+ * for text drawing operations.
+ *
+ * @return the anti-aliasing setting
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see #getAntialias
+ *
+ * @since 3.1
+ */
+ public int getTextAntialias() {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ // if (data.gdipGraphics == 0)
+ return SWT.DEFAULT;
+ // TODO
+ // int mode = Gdip.Graphics_GetTextRenderingHint(data.gdipGraphics);
+ // switch (mode) {
+ // case Gdip.TextRenderingHintSystemDefault:
+ // return SWT.DEFAULT;
+ // case Gdip.TextRenderingHintSingleBitPerPixel:
+ // case Gdip.TextRenderingHintSingleBitPerPixelGridFit:
+ // return SWT.OFF;
+ // case Gdip.TextRenderingHintAntiAlias:
+ // case Gdip.TextRenderingHintAntiAliasGridFit:
+ // case Gdip.TextRenderingHintClearTypeGridFit:
+ // return SWT.ON;
+ // }
+ // return SWT.DEFAULT;
+ }
+
+ /**
+ * Sets the parameter to the transform that is currently being used by the
+ * receiver.
+ *
+ * @param transform
+ * the destination to copy the transform into
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parameter is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the parameter has been
+ * disposed</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see Transform
+ *
+ * @since 3.1
+ */
+ public void getTransform(Transform transform) {
+ //TODO
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ if (transform == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (transform.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ // int /* long */gdipGraphics = data.gdipGraphics;
+ // if (gdipGraphics != 0) {
+ // Gdip.Graphics_GetTransform(gdipGraphics, transform.handle);
+ // int /* long */identity = identity();
+ // Gdip.Matrix_Invert(identity);
+ // Gdip.Matrix_Multiply(transform.handle, identity, Gdip.MatrixOrderAppend);
+ // Gdip.Matrix_delete(identity);
+ // } else {
+ // transform.setElements(1, 0, 0, 1, 0, 0);
+ // }
+ }
+ }
+
+ /**
+ * Returns <code>true</code> if this GC is drawing in the mode where the
+ * resulting color in the destination is the <em>exclusive or</em> of the
+ * color values in the source and the destination, and <code>false</code> if
+ * it is drawing in the mode where the destination color is being replaced
+ * with the source color value.
+ *
+ * @return <code>true</code> true if the receiver is in XOR mode, and false
+ * otherwise
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public boolean getXORMode() {
+ //TODO
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ // int rop2 = 0;
+ // rop2 = OS.GetROP2(handle);
+ return false; //rop2 == OS.R2_XORPEN;
+ }
+
+ /**
+ * If the argument is <code>true</code>, puts the receiver in a drawing mode
+ * where the resulting color in the destination is the <em>exclusive or</em>
+ * of the color values in the source and the destination, and if the
+ * argument is <code>false</code>, puts the receiver in a drawing mode where
+ * the destination color is replaced with the source color value.
+ * <p>
+ * Note that this mode in fundamentally unsupportable on certain platforms,
+ * notably Carbon (Mac OS X). Clients that want their code to run on all
+ * platforms need to avoid this method.
+ * </p>
+ *
+ * @param xor
+ * if <code>true</code>, then <em>xor</em> mode is used,
+ * otherwise <em>source copy</em> mode is used
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @deprecated this functionality is not supported on some platforms
+ */
+ @Deprecated
+ public void setXORMode(boolean xor) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ //TODO
+ //OS.SetROP2(handle, xor ? OS.R2_XORPEN : OS.R2_COPYPEN);
+ }
+
+ /**
+ * Returns an integer hash code for the receiver. Any two objects that
+ * return <code>true</code> when passed to <code>equals</code> must return
+ * the same value for this method.
+ *
+ * @return the receiver's hash
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see #equals
+ */
+ @Override
+ public int hashCode() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return paintDevice.hashCode();
+ }
+
+ /**
+ * Returns <code>true</code> if the receiver has a clipping region set into
+ * it, and <code>false</code> otherwise. If this method returns false, the
+ * receiver will draw on all available space in the destination. If it
+ * returns true, it will draw only in the area that is covered by the region
+ * that can be accessed with <code>getClipping(region)</code>.
+ *
+ * @return <code>true</code> if the GC has a clipping region, and
+ * <code>false</code> otherwise
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public boolean isClipped() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return activeClipping != null;
+ }
+
+ /**
+ * Returns <code>true</code> if the GC has been disposed, and
+ * <code>false</code> otherwise.
+ * <p>
+ * This method gets the dispose state for the GC. When a GC has been
+ * disposed, it is an error to invoke any other method using the GC.
+ *
+ * @return <code>true</code> when the GC is disposed and <code>false</code>
+ * otherwise
+ */
+ @Override
+ public boolean isDisposed() {
+ return paintDevice == null;
+ }
+
+ /**
+ * Sets the receiver to always use the operating system's advanced graphics
+ * subsystem for all graphics operations if the argument is
+ * <code>true</code>. If the argument is <code>false</code>, the advanced
+ * graphics subsystem is no longer used, advanced graphics state is cleared
+ * and the normal graphics subsystem is used from now on.
+ * <p>
+ * Normally, the advanced graphics subsystem is invoked automatically when
+ * any one of the alpha, antialias, patterns, interpolation, paths, clipping
+ * or transformation operations in the receiver is requested. When the
+ * receiver is switched into advanced mode, the advanced graphics subsystem
+ * performs both advanced and normal graphics operations. Because the two
+ * subsystems are different, their output may differ. Switching to advanced
+ * graphics before any graphics operations are performed ensures that the
+ * output is consistent.
+ * </p>
+ * <p>
+ * Advanced graphics may not be installed for the operating system. In this
+ * case, this operation does nothing. Some operating system have only one
+ * graphics subsystem, so switching from normal to advanced graphics does
+ * nothing. However, switching from advanced to normal graphics will always
+ * clear the advanced graphics state, even for operating systems that have
+ * only one graphics subsystem.
+ * </p>
+ *
+ * @param advanced
+ * the new advanced graphics state
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see #setAlpha
+ * @see #setAntialias
+ * @see #setBackgroundPattern
+ * @see #setClipping(Path)
+ * @see #setForegroundPattern
+ * @see #setLineAttributes
+ * @see #setInterpolation
+ * @see #setTextAntialias
+ * @see #setTransform
+ * @see #getAdvanced
+ *
+ * @since 3.1
+ */
+ public void setAdvanced(boolean advanced) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ }
+
+ /**
+ * Returns <code>true</code> if receiver is using the operating system's
+ * advanced graphics subsystem. Otherwise, <code>false</code> is returned to
+ * indicate that normal graphics are in use.
+ * <p>
+ * Advanced graphics may not be installed for the operating system. In this
+ * case, <code>false</code> is always returned. Some operating system have
+ * only one graphics subsystem. If this subsystem supports advanced
+ * graphics, then <code>true</code> is always returned. If any graphics
+ * operation such as alpha, antialias, patterns, interpolation, paths,
+ * clipping or transformation has caused the receiver to switch from regular
+ * to advanced graphics mode, <code>true</code> is returned. If the receiver
+ * has been explicitly switched to advanced mode and this mode is supported,
+ * <code>true</code> is returned.
+ * </p>
+ *
+ * @return the advanced value
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see #setAdvanced
+ *
+ * @since 3.1
+ */
+ public boolean getAdvanced() {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ // Qt is Advanced :)
+ return true;
+ }
+
+ /**
+ * Sets the receiver's anti-aliasing value to the parameter, which must be
+ * one of <code>SWT.DEFAULT</code>, <code>SWT.OFF</code> or
+ * <code>SWT.ON</code>. Note that this controls anti-aliasing for all
+ * <em>non-text drawing</em> operations.
+ * <p>
+ * This operation requires the operating system's advanced graphics
+ * subsystem which may not be available on some platforms.
+ * </p>
+ *
+ * @param antialias
+ * the anti-aliasing setting
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the parameter is not one
+ * of <code>SWT.DEFAULT</code>, <code>SWT.OFF</code> or
+ * <code>SWT.ON</code></li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are
+ * not available</li>
+ * </ul>
+ *
+ * @see #getAdvanced
+ * @see #setAdvanced
+ * @see #setTextAntialias
+ *
+ * @since 3.1
+ */
+ public void setAntialias(int antialias) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ this.antialias = antialias;
+ // if (handle == 0) {
+ // SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ // TODO
+ // if (data.gdipGraphics == 0 && antialias == SWT.DEFAULT)
+ // return;
+ // int mode = 0;
+ // switch (antialias) {
+ // case SWT.DEFAULT:
+ // mode = Gdip.SmoothingModeDefault;
+ // break;
+ // case SWT.OFF:
+ // mode = Gdip.SmoothingModeNone;
+ // break;
+ // case SWT.ON:
+ // mode = Gdip.SmoothingModeAntiAlias;
+ // break;
+ // default:
+ // SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ // }
+ // }
+ }
+
+ /**
+ * Sets the receiver's alpha value which must be between 0 (transparent) and
+ * 255 (opaque).
+ * <p>
+ * This operation requires the operating system's advanced graphics
+ * subsystem which may not be available on some platforms.
+ * </p>
+ *
+ * @param alpha
+ * the alpha value
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are
+ * not available</li>
+ * </ul>
+ *
+ * @see #getAdvanced
+ * @see #setAdvanced
+ *
+ * @since 3.1
+ */
+ public void setAlpha(int alpha) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ //TODO
+ data.alpha = alpha & 0xFF;
+ data.state &= ~(BACKGROUND | FOREGROUND);
+ }
+
+ /**
+ * Sets the background color. The background color is used for fill
+ * operations and as the background color when text is drawn.
+ *
+ * @param color
+ * the new background color for the receiver
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the color is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the color has been
+ * disposed</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void setBackground(Color color) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (color == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (color.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ if (data.backgroundPattern == null && data.backgroundColor.equals(color)) {
+ return;
+ }
+ data.backgroundPattern = null;
+ data.backgroundColor = color;
+ data.state &= ~(BACKGROUND | BACKGROUND_TEXT);
+ }
+
+ /**
+ * Sets the background pattern. The default value is <code>null</code>.
+ * <p>
+ * This operation requires the operating system's advanced graphics
+ * subsystem which may not be available on some platforms.
+ * </p>
+ *
+ * @param pattern
+ * the new background pattern
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the parameter has been
+ * disposed</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are
+ * not available</li>
+ * </ul>
+ *
+ * @see Pattern
+ * @see #getAdvanced
+ * @see #setAdvanced
+ *
+ * @since 3.1
+ */
+ public void setBackgroundPattern(Pattern pattern) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (pattern != null && pattern.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ if (data.backgroundPattern == pattern) {
+ return;
+ }
+ data.backgroundPattern = pattern;
+ data.state &= ~BACKGROUND;
+ }
+
+ /**
+ * Sets the area of the receiver which can be changed by drawing operations
+ * to the rectangular area specified by the arguments.
+ *
+ * @param x
+ * the x coordinate of the clipping rectangle
+ * @param y
+ * the y coordinate of the clipping rectangle
+ * @param width
+ * the width of the clipping rectangle
+ * @param height
+ * the height of the clipping rectangle
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void setClipping(int x, int y, int width, int height) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ activeClipping = new QRegion(x, y, width, height);
+ }
+
+ /**
+ * Sets the area of the receiver which can be changed by drawing operations
+ * to the path specified by the argument.
+ * <p>
+ * This operation requires the operating system's advanced graphics
+ * subsystem which may not be available on some platforms.
+ * </p>
+ *
+ * @param path
+ * the clipping path.
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the path has been disposed
+ * </li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are
+ * not available</li>
+ * </ul>
+ *
+ * @see Path
+ * @see #getAdvanced
+ * @see #setAdvanced
+ *
+ * @since 3.1
+ */
+ public void setClipping(Path path) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (path != null && path.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ if (path == null) {
+ activeClipping = null;
+ }
+ //TODO
+ }
+
+ /**
+ * Sets the area of the receiver which can be changed by drawing operations
+ * to the rectangular area specified by the argument. Specifying
+ * <code>null</code> for the rectangle reverts the receiver's clipping area
+ * to its original value.
+ *
+ * @param rect
+ * the clipping rectangle or <code>null</code>
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void setClipping(Rectangle rect) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (rect != null) {
+ activeClipping = new QRegion(rect.x, rect.y, rect.width, rect.height);
+ } else {
+ activeClipping = null;
+ }
+ }
+
+ /**
+ * Sets the area of the receiver which can be changed by drawing operations
+ * to the region specified by the argument. Specifying <code>null</code> for
+ * the region reverts the receiver's clipping area to its original value.
+ *
+ * @param region
+ * the clipping region or <code>null</code>
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the region has been
+ * disposed</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void setClipping(Region region) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (region != null && region.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ if (region != null) {
+ activeClipping = region.getQRegion();
+ } else {
+ activeClipping = null;
+ }
+ }
+
+ /**
+ * Sets the font which will be used by the receiver to draw and measure text
+ * to the argument. If the argument is null, then a default font appropriate
+ * for the platform will be used instead.
+ *
+ * @param font
+ * the new font for the receiver, or null to indicate a default
+ * font
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the font has been disposed
+ * </li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void setFont(Font font) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (font != null && font.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ data.font = font != null ? font : data.device.getSystemFont();
+ data.state &= ~FONT;
+ }
+
+ /**
+ * Sets the foreground color. The foreground color is used for drawing
+ * operations including when text is drawn.
+ *
+ * @param color
+ * the new foreground color for the receiver
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the color is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the color has been
+ * disposed</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void setForeground(Color color) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (color == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (color.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ if (data.foregroundPattern == null && color.equals(data.foregroundColor)) {
+ return;
+ }
+ data.foregroundPattern = null;
+ data.foregroundColor = color;
+ data.state &= ~(FOREGROUND | FOREGROUND_TEXT);
+ }
+
+ /**
+ * Sets the foreground pattern. The default value is <code>null</code>.
+ * <p>
+ * This operation requires the operating system's advanced graphics
+ * subsystem which may not be available on some platforms.
+ * </p>
+ *
+ * @param pattern
+ * the new foreground pattern
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the parameter has been
+ * disposed</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are
+ * not available</li>
+ * </ul>
+ *
+ * @see Pattern
+ * @see #getAdvanced
+ * @see #setAdvanced
+ *
+ * @since 3.1
+ */
+ public void setForegroundPattern(Pattern pattern) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (pattern != null && pattern.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ // if (data.gdipGraphics == 0 && pattern == null)
+ // return;
+ // initGdip();
+ if (data.foregroundPattern == pattern) {
+ return;
+ }
+ data.foregroundPattern = pattern;
+ data.state &= ~FOREGROUND;
+ }
+
+ /**
+ * Sets the receiver's interpolation setting to the parameter, which must be
+ * one of <code>SWT.DEFAULT</code>, <code>SWT.NONE</code>,
+ * <code>SWT.LOW</code> or <code>SWT.HIGH</code>.
+ * <p>
+ * This operation requires the operating system's advanced graphics
+ * subsystem which may not be available on some platforms.
+ * </p>
+ *
+ * @param interpolation
+ * the new interpolation setting
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the rule is not one of
+ * <code>SWT.DEFAULT</code>, <code>SWT.NONE</code>,
+ * <code>SWT.LOW</code> or <code>SWT.HIGH</code>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are
+ * not available</li>
+ * </ul>
+ *
+ * @see #getAdvanced
+ * @see #setAdvanced
+ *
+ * @since 3.1
+ */
+ public void setInterpolation(int interpolation) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ //TODO
+ //if (data.gdipGraphics == 0 && interpolation == SWT.DEFAULT)
+ // int mode = 0;
+ // switch (interpolation) {
+ // case SWT.DEFAULT:
+ // mode = Gdip.InterpolationModeDefault;
+ // break;
+ // case SWT.NONE:
+ // mode = Gdip.InterpolationModeNearestNeighbor;
+ // break;
+ // case SWT.LOW:
+ // mode = Gdip.InterpolationModeLowQuality;
+ // break;
+ // case SWT.HIGH:
+ // mode = Gdip.InterpolationModeHighQuality;
+ // break;
+ // default:
+ // SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ // }
+ // initGdip();
+ //Gdip.Graphics_SetInterpolationMode(data.gdipGraphics, mode);
+ }
+
+ /**
+ * Sets the receiver's line attributes.
+ * <p>
+ * This operation requires the operating system's advanced graphics
+ * subsystem which may not be available on some platforms.
+ * </p>
+ *
+ * @param attributes
+ * the line attributes
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the attributes is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if any of the line attributes
+ * is not valid</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are
+ * not available</li>
+ * </ul>
+ *
+ * @see LineAttributes
+ * @see #getAdvanced
+ * @see #setAdvanced
+ *
+ * @since 3.3
+ */
+ public void setLineAttributes(LineAttributes attributes) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (attributes == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ int mask = 0;
+ float lineWidth = attributes.width;
+ if (lineWidth != data.lineWidth) {
+ mask |= LINE_WIDTH | DRAW_OFFSET;
+ }
+ int lineStyle = attributes.style;
+ if (lineStyle != data.lineStyle) {
+ mask |= LINE_STYLE;
+ switch (lineStyle) {
+ case SWT.LINE_SOLID:
+ case SWT.LINE_DASH:
+ case SWT.LINE_DOT:
+ case SWT.LINE_DASHDOT:
+ case SWT.LINE_DASHDOTDOT:
+ break;
+ case SWT.LINE_CUSTOM:
+ if (attributes.dash == null) {
+ lineStyle = SWT.LINE_SOLID;
+ }
+ break;
+ default:
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ }
+ int join = attributes.join;
+ if (join != data.lineJoin) {
+ mask |= LINE_JOIN;
+ switch (join) {
+ case SWT.CAP_ROUND:
+ case SWT.CAP_FLAT:
+ case SWT.CAP_SQUARE:
+ break;
+ default:
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ }
+ int cap = attributes.cap;
+ if (cap != data.lineCap) {
+ mask |= LINE_CAP;
+ switch (cap) {
+ case SWT.JOIN_MITER:
+ case SWT.JOIN_ROUND:
+ case SWT.JOIN_BEVEL:
+ break;
+ default:
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ }
+ float[] dashes = attributes.dash;
+ float[] lineDashes = data.lineDashes;
+ if (dashes != null && dashes.length > 0) {
+ boolean changed = lineDashes == null || lineDashes.length != dashes.length;
+ for (int i = 0; i < dashes.length; i++) {
+ float dash = dashes[i];
+ if (dash <= 0) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ if (!changed && lineDashes[i] != dash) {
+ changed = true;
+ }
+ }
+ if (changed) {
+ float[] newDashes = new float[dashes.length];
+ System.arraycopy(dashes, 0, newDashes, 0, dashes.length);
+ dashes = newDashes;
+ mask |= LINE_STYLE;
+ } else {
+ dashes = lineDashes;
+ }
+ } else {
+ if (lineDashes != null && lineDashes.length > 0) {
+ mask |= LINE_STYLE;
+ } else {
+ dashes = lineDashes;
+ }
+ }
+ float dashOffset = attributes.dashOffset;
+ if (dashOffset != data.lineDashesOffset) {
+ mask |= LINE_STYLE;
+ }
+ float miterLimit = attributes.miterLimit;
+ if (miterLimit != data.lineMiterLimit) {
+ mask |= LINE_MITERLIMIT;
+ }
+ // initGdip();
+ if (mask == 0) {
+ return;
+ }
+ data.lineWidth = lineWidth;
+ data.lineStyle = lineStyle;
+ data.lineCap = cap;
+ data.lineJoin = join;
+ data.lineDashes = dashes;
+ data.lineDashesOffset = dashOffset;
+ data.lineMiterLimit = miterLimit;
+ data.state &= ~mask;
+ }
+
+ /**
+ * Sets the receiver's line cap style to the argument, which must be one of
+ * the constants <code>SWT.CAP_FLAT</code>, <code>SWT.CAP_ROUND</code>, or
+ * <code>SWT.CAP_SQUARE</code>.
+ *
+ * @param cap
+ * the cap style to be used for drawing lines
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the style is not valid</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+ public void setLineCap(int cap) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+
+ if (data.lineCap == cap) {
+ return;
+ }
+ switch (cap) {
+ case SWT.CAP_ROUND:
+ case SWT.CAP_FLAT:
+ case SWT.CAP_SQUARE:
+ break;
+ default:
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ data.lineCap = cap;
+ data.state &= ~LINE_CAP;
+ }
+
+ /**
+ * Sets the receiver's line dash style to the argument. The default value is
+ * <code>null</code>. If the argument is not <code>null</code>, the
+ * receiver's line style is set to <code>SWT.LINE_CUSTOM</code>, otherwise
+ * it is set to <code>SWT.LINE_SOLID</code>.
+ *
+ * @param dashes
+ * the dash style to be used for drawing lines
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if any of the values in the
+ * array is less than or equal 0</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+ public void setLineDash(int[] dashes) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ float[] lineDashes = data.lineDashes;
+ if (dashes != null && dashes.length > 0) {
+ boolean changed = data.lineStyle != SWT.LINE_CUSTOM || lineDashes == null
+ || lineDashes.length != dashes.length;
+ for (int i = 0; i < dashes.length; i++) {
+ int dash = dashes[i];
+ if (dash <= 0) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ if (!changed && lineDashes[i] != dash) {
+ changed = true;
+ }
+ }
+ if (!changed) {
+ return;
+ }
+ data.lineDashes = new float[dashes.length];
+ for (int i = 0; i < dashes.length; i++) {
+ data.lineDashes[i] = dashes[i];
+ }
+ data.lineStyle = SWT.LINE_CUSTOM;
+ } else {
+ if (data.lineStyle == SWT.LINE_SOLID && (lineDashes == null || lineDashes.length == 0)) {
+ return;
+ }
+ data.lineDashes = null;
+ data.lineStyle = SWT.LINE_SOLID;
+ }
+ data.state &= ~LINE_STYLE;
+ }
+
+ /**
+ * Sets the receiver's line join style to the argument, which must be one of
+ * the constants <code>SWT.JOIN_MITER</code>, <code>SWT.JOIN_ROUND</code>,
+ * or <code>SWT.JOIN_BEVEL</code>.
+ *
+ * @param join
+ * the join style to be used for drawing lines
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the style is not valid</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+ public void setLineJoin(int join) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (data.lineJoin == join) {
+ return;
+ }
+ switch (join) {
+ case SWT.JOIN_MITER:
+ case SWT.JOIN_ROUND:
+ case SWT.JOIN_BEVEL:
+ break;
+ default:
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ data.lineJoin = join;
+ data.state &= ~LINE_JOIN;
+ }
+
+ /**
+ * Sets the receiver's line style to the argument, which must be one of the
+ * constants <code>SWT.LINE_SOLID</code>, <code>SWT.LINE_DASH</code>,
+ * <code>SWT.LINE_DOT</code>, <code>SWT.LINE_DASHDOT</code> or
+ * <code>SWT.LINE_DASHDOTDOT</code>.
+ *
+ * @param lineStyle
+ * the style to be used for drawing lines
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the style is not valid</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void setLineStyle(int lineStyle) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (data.lineStyle == lineStyle) {
+ return;
+ }
+ switch (lineStyle) {
+ case SWT.LINE_SOLID:
+ case SWT.LINE_DASH:
+ case SWT.LINE_DOT:
+ case SWT.LINE_DASHDOT:
+ case SWT.LINE_DASHDOTDOT:
+ break;
+ case SWT.LINE_CUSTOM:
+ if (data.lineDashes == null) {
+ lineStyle = SWT.LINE_SOLID;
+ }
+ break;
+ default:
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ data.lineStyle = lineStyle;
+ data.state &= ~LINE_STYLE;
+ }
+
+ /**
+ * Sets the width that will be used when drawing lines for all of the figure
+ * drawing operations (that is, <code>drawLine</code>,
+ * <code>drawRectangle</code>, <code>drawPolyline</code>, and so forth.
+ * <p>
+ * Note that line width of zero is used as a hint to indicate that the
+ * fastest possible line drawing algorithms should be used. This means that
+ * the output may be different from line width one.
+ * </p>
+ *
+ * @param lineWidth
+ * the width of a line
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void setLineWidth(int lineWidth) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+
+ if (data.lineWidth == lineWidth) {
+ return;
+ }
+ data.lineWidth = lineWidth;
+ data.state &= ~(LINE_WIDTH | DRAW_OFFSET);
+ }
+
+ /**
+ * Sets the receiver's text anti-aliasing value to the parameter, which must
+ * be one of <code>SWT.DEFAULT</code>, <code>SWT.OFF</code> or
+ * <code>SWT.ON</code>. Note that this controls anti-aliasing only for all
+ * <em>text drawing</em> operations.
+ * <p>
+ * This operation requires the operating system's advanced graphics
+ * subsystem which may not be available on some platforms.
+ * </p>
+ *
+ * @param antialias
+ * the anti-aliasing setting
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the parameter is not one
+ * of <code>SWT.DEFAULT</code>, <code>SWT.OFF</code> or
+ * <code>SWT.ON</code></li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are
+ * not available</li>
+ * </ul>
+ *
+ * @see #getAdvanced
+ * @see #setAdvanced
+ * @see #setAntialias
+ *
+ * @since 3.1
+ */
+ public void setTextAntialias(int antialias) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ //TODO
+ // if (data.gdipGraphics == 0 && antialias == SWT.DEFAULT)
+ // return;
+ // int textMode = 0;
+ // switch (antialias) {
+ // case SWT.DEFAULT:
+ // textMode = Gdip.TextRenderingHintSystemDefault;
+ // break;
+ // case SWT.OFF:
+ // textMode = Gdip.TextRenderingHintSingleBitPerPixelGridFit;
+ // break;
+ // case SWT.ON:
+ // int[] type = new int[1];
+ // OS.SystemParametersInfo(OS.SPI_GETFONTSMOOTHINGTYPE, 0, type, 0);
+ // if (type[0] == OS.FE_FONTSMOOTHINGCLEARTYPE) {
+ // textMode = Gdip.TextRenderingHintClearTypeGridFit;
+ // } else {
+ // textMode = Gdip.TextRenderingHintAntiAliasGridFit;
+ // }
+ // break;
+ // default:
+ // SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ // }
+ // // initGdip();
+ // Gdip.Graphics_SetTextRenderingHint(data.gdipGraphics, textMode);
+ }
+
+ /**
+ * Sets the transform that is currently being used by the receiver. If the
+ * argument is <code>null</code>, the current transform is set to the
+ * identity transform.
+ * <p>
+ * This operation requires the operating system's advanced graphics
+ * subsystem which may not be available on some platforms.
+ * </p>
+ *
+ * @param transform
+ * the transform to set
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the parameter has been
+ * disposed</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are
+ * not available</li>
+ * </ul>
+ *
+ * @see Transform
+ * @see #getAdvanced
+ * @see #setAdvanced
+ *
+ * @since 3.1
+ */
+ public void setTransform(Transform transform) {
+ //TODO
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ if (transform != null && transform.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ // if (data.gdipGraphics == 0 && transform == null)
+ // return;
+ // // initGdip();
+ // int /* long */identity = identity();
+ // if (transform != null) {
+ // Gdip.Matrix_Multiply(identity, transform.handle, Gdip.MatrixOrderPrepend);
+ // }
+ // Gdip.Graphics_SetTransform(data.gdipGraphics, identity);
+ // Gdip.Matrix_delete(identity);
+ // data.state &= ~DRAW_OFFSET;
+ }
+ }
+
+ /**
+ * Returns the extent of the given string. No tab expansion or carriage
+ * return processing will be performed.
+ * <p>
+ * The <em>extent</em> of a string is the width and height of the
+ * rectangular area it would cover if drawn in a particular font (in this
+ * case, the current font in the receiver).
+ * </p>
+ *
+ * @param string
+ * the string to measure
+ * @return a point containing the extent of the string
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public Point stringExtent(String string) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+
+ return _textExtent(getActivePainter(), string, 0);
+ }
+
+ /**
+ * Returns the extent of the given string. Tab expansion and carriage return
+ * processing are performed.
+ * <p>
+ * The <em>extent</em> of a string is the width and height of the
+ * rectangular area it would cover if drawn in a particular font (in this
+ * case, the current font in the receiver).
+ * </p>
+ *
+ * @param string
+ * the string to measure
+ * @return a point containing the extent of the string
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public Point textExtent(String string) {
+ return textExtent(string, SWT.DRAW_DELIMITER | SWT.DRAW_TAB);
+ }
+
+ /**
+ * Returns the extent of the given string. Tab expansion, line delimiter and
+ * mnemonic processing are performed according to the specified flags, which
+ * can be a combination of:
+ * <dl>
+ * <dt><b>DRAW_DELIMITER</b></dt>
+ * <dd>draw multiple lines</dd>
+ * <dt><b>DRAW_TAB</b></dt>
+ * <dd>expand tabs</dd>
+ * <dt><b>DRAW_MNEMONIC</b></dt>
+ * <dd>underline the mnemonic character</dd>
+ * <dt><b>DRAW_TRANSPARENT</b></dt>
+ * <dd>transparent background</dd>
+ * </dl>
+ * <p>
+ * The <em>extent</em> of a string is the width and height of the
+ * rectangular area it would cover if drawn in a particular font (in this
+ * case, the current font in the receiver).
+ * </p>
+ *
+ * @param string
+ * the string to measure
+ * @param flags
+ * the flags specifying how to process the text
+ * @return a point containing the extent of the string
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public Point textExtent(String string, int flags) {
+ if (paintDevice == null) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (string == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ QPainter painter = getActivePainter();
+ return _textExtent(painter, string, flags);
+ }
+
+ private Point _textExtent(QPainter painter, String string, int flags) {
+ int qFlags = translateTextFlags(flags);
+ painter.setFont(data.font.getQFont());
+ QRect rect = painter.boundingRect((QRect) null, qFlags, string);
+ //System.out.println("textExtent: " + string + " -> " + rect.width() + "x" + rect.height());
+ return new Point(rect.width(), rect.height());
+ }
+
+ /**
+ * Invokes platform specific functionality to allocate a new graphics
+ * context.
+ * <p>
+ * <b>IMPORTANT:</b> This method is <em>not</em> part of the public API for
+ * <code>GC</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 drawable
+ * the Drawable for the receiver.
+ * @param data
+ * the data for the receiver.
+ *
+ * @return a new <code>GC</code>
+ */
+ public static GC qt_new(Drawable drawable, GCData data) {
+ GC gc = new GC();
+ QPaintDeviceInterface paintDevice = drawable.internal_new_GC(data);
+ gc.device = data.device;
+ gc.init(drawable, data, paintDevice);
+ return gc;
+ }
+
+ /**
+ * Invokes platform specific functionality to wrap a graphics context.
+ * <p>
+ * <b>IMPORTANT:</b> This method is <em>not</em> part of the public API for
+ * <code>GC</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 Windows HDC.
+ * @param data
+ * the data for the receiver.
+ *
+ * @return a new <code>GC</code>
+ */
+ public static GC qt_new(Drawable drawable, QPaintDeviceInterface paintDevice, GCData data) {
+ GC gc = new GC();
+ gc.device = data.device;
+ gc.init(drawable, data, paintDevice);
+ return gc;
+ }
+
+ /**
+ * Returns a string containing a concise, human-readable description of the
+ * receiver.
+ *
+ * @return a string representation of the receiver
+ */
+ @Override
+ public String toString() {
+ if (isDisposed()) {
+ return "GC {*DISPOSED*}"; //$NON-NLS-1$
+ }
+ return "GC {" + paintDevice + "}"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/GCData.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/GCData.java
new file mode 100644
index 0000000000..a5050c0fdd
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/GCData.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.graphics;
+
+import org.eclipse.swt.SWT;
+
+/**
+ * Instances of this class are descriptions of GCs in terms of unallocated
+ * platform-specific data fields.
+ * <p>
+ * <b>IMPORTANT:</b> This class is <em>not</em> part of the public API for SWT.
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+
+public final class GCData {
+ public Device device;
+ public int style, state = -1;
+ public Color foregroundColor = null;
+ public Color backgroundColor = null;
+ public Font font;
+ public Pattern foregroundPattern;
+ public Pattern backgroundPattern;
+ public int lineStyle = SWT.LINE_SOLID;
+ public float lineWidth;
+ public int lineCap = SWT.CAP_FLAT;
+ public int lineJoin = SWT.JOIN_MITER;
+ public float lineDashesOffset;
+ public float[] lineDashes;
+ public float lineMiterLimit = 10;
+ public int alpha = 0xFF;
+ public Image image;
+ public int layout = -1;
+ public int uiState = 0;
+ public boolean focusDrawn;
+ public int handle;
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Image.java
new file mode 100644
index 0000000000..fe3374b526
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Image.java
@@ -0,0 +1,978 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.graphics;
+
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
+
+import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.gui.QIcon;
+import com.trolltech.qt.gui.QImage;
+import com.trolltech.qt.gui.QPaintDeviceInterface;
+import com.trolltech.qt.gui.QPixmap;
+import com.trolltech.qt.gui.QImage.Format;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTError;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Instances of this class are graphics which have been prepared for display on
+ * a specific device. That is, they are ready to paint using methods such as
+ * <code>GC.drawImage()</code> and display on widgets with, for example,
+ * <code>Button.setImage()</code>.
+ * <p>
+ * If loaded from a file format that supports it, an <code>Image</code> may have
+ * transparency, meaning that certain pixels are specified as being transparent
+ * when drawn. Examples of file formats that support transparency are GIF and
+ * PNG.
+ * </p>
+ * <p>
+ * There are two primary ways to use <code>Images</code>. The first is to load a
+ * graphic file from disk and create an <code>Image</code> from it. This is done
+ * using an <code>Image</code> constructor, for example:
+ *
+ * <pre>
+ * Image i = new Image(device, &quot;C:\\graphic.bmp&quot;);
+ * </pre>
+ *
+ * A graphic file may contain a color table specifying which colors the image
+ * was intended to possess. In the above example, these colors will be mapped to
+ * the closest available color in SWT. It is possible to get more control over
+ * the mapping of colors as the image is being created, using code of the form:
+ *
+ * <pre>
+ * ImageData data = new ImageData(&quot;C:\\graphic.bmp&quot;);
+ * RGB[] rgbs = data.getRGBs();
+ * // At this point, rgbs contains specifications of all
+ * // the colors contained within this image. You may
+ * // allocate as many of these colors as you wish by
+ * // using the Color constructor Color(RGB), then
+ * // create the image:
+ * Image i = new Image(device, data);
+ * </pre>
+ * <p>
+ * Applications which require even greater control over the image loading
+ * process should use the support provided in class <code>ImageLoader</code>.
+ * </p>
+ * <p>
+ * Application code must explicitly invoke the <code>Image.dispose()</code>
+ * method to release the operating system resources managed by each instance
+ * when those instances are no longer required.
+ * </p>
+ *
+ * @see Color
+ * @see ImageData
+ * @see ImageLoader
+ * @see <a href="http://www.eclipse.org/swt/snippets/#image">Image snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Examples:
+ * GraphicsExample, ImageAnalyzer</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ */
+public final class Image extends Resource implements Drawable {
+
+ /**
+ * specifies whether the receiver is a bitmap or an icon (one of
+ * <code>SWT.BITMAP</code>, <code>SWT.ICON</code>)
+ */
+ private int type = SWT.BITMAP;
+
+ private int transparentPixel = -1;
+
+ /**
+ * The GC the image is currently selected in.
+ */
+ private GC memGC;
+
+ /**
+ * The global alpha value to be used for every pixel.
+ */
+ private int alpha = -1;
+
+ private boolean hasMask = false;
+
+ //private QImage image;
+ private QIcon icon;
+ private QPixmap pixmap;
+
+ Image(Device device) {
+ super(device);
+ }
+
+ /**
+ * Constructs an empty instance of this class with the specified width and
+ * height. The result may be drawn upon by creating a GC and using any of
+ * its drawing operations, as shown in the following example:
+ *
+ * <pre>
+ * Image i = new Image(device, width, height);
+ * GC gc = new GC(i);
+ * gc.drawRectangle(0, 0, 50, 50);
+ * gc.dispose();
+ * </pre>
+ * <p>
+ * Note: Some platforms may have a limitation on the size of image that can
+ * be created (size depends on width, height, and depth). For example,
+ * Windows 95, 98, and ME do not allow images larger than 16M.
+ * </p>
+ *
+ * @param device
+ * the device on which to create the image
+ * @param width
+ * the width of the new image
+ * @param height
+ * the height of the new image
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if device is null and there is
+ * no current device</li>
+ * <li>ERROR_INVALID_ARGUMENT - if either the width or height
+ * is negative or zero</li>
+ * </ul>
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_NO_HANDLES if a handle could not be obtained for
+ * image creation</li>
+ * </ul>
+ */
+ public Image(Device device, int width, int height) {
+ super(device);
+ init(width, height);
+ init();
+ }
+
+ /**
+ * Constructs a new instance of this class based on the provided image, with
+ * an appearance that varies depending on the value of the flag. The
+ * possible flag values are:
+ * <dl>
+ * <dt><b>{@link SWT#IMAGE_COPY}</b></dt>
+ * <dd>the result is an identical copy of srcImage</dd>
+ * <dt><b>{@link SWT#IMAGE_DISABLE}</b></dt>
+ * <dd>the result is a copy of srcImage which has a <em>disabled</em> look</dd>
+ * <dt><b>{@link SWT#IMAGE_GRAY}</b></dt>
+ * <dd>the result is a copy of srcImage which has a <em>gray scale</em> look
+ * </dd>
+ * </dl>
+ *
+ * @param device
+ * the device on which to create the image
+ * @param srcImage
+ * the image to use as the source
+ * @param flag
+ * the style, either <code>IMAGE_COPY</code>,
+ * <code>IMAGE_DISABLE</code> or <code>IMAGE_GRAY</code>
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if device is null and there is
+ * no current device</li>
+ * <li>ERROR_NULL_ARGUMENT - if srcImage is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the flag is not one of
+ * <code>IMAGE_COPY</code>, <code>IMAGE_DISABLE</code> or
+ * <code>IMAGE_GRAY</code></li>
+ * <li>ERROR_INVALID_ARGUMENT - if the image has been
+ * disposed</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_INVALID_IMAGE - if the image is not a bitmap or
+ * an icon, or is otherwise in an invalid state</li>
+ * <li>ERROR_UNSUPPORTED_DEPTH - if the depth of the image is
+ * not supported</li>
+ * </ul>
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_NO_HANDLES if a handle could not be obtained for
+ * image creation</li>
+ * </ul>
+ */
+ public Image(Device device, Image srcImage, int flag) {
+ super(device);
+ if (srcImage == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (srcImage.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ device = this.device;
+ this.type = srcImage.type;
+ switch (flag) {
+ case SWT.IMAGE_COPY:
+ this.pixmap = new QPixmap(srcImage.pixmap);
+ break;
+ case SWT.IMAGE_DISABLE:
+ this.pixmap = createDisabledImage(srcImage);
+ break;
+ case SWT.IMAGE_GRAY:
+ this.pixmap = createGrayImage(srcImage);
+ break;
+ default:
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ init();
+ }
+
+ /**
+ * Constructs an empty instance of this class with the width and height of
+ * the specified rectangle. The result may be drawn upon by creating a GC
+ * and using any of its drawing operations, as shown in the following
+ * example:
+ *
+ * <pre>
+ * Image i = new Image(device, boundsRectangle);
+ * GC gc = new GC(i);
+ * gc.drawRectangle(0, 0, 50, 50);
+ * gc.dispose();
+ * </pre>
+ * <p>
+ * Note: Some platforms may have a limitation on the size of image that can
+ * be created (size depends on width, height, and depth). For example,
+ * Windows 95, 98, and ME do not allow images larger than 16M.
+ * </p>
+ *
+ * @param device
+ * the device on which to create the image
+ * @param bounds
+ * a rectangle specifying the image's width and height (must not
+ * be null)
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if device is null and there is
+ * no current device</li>
+ * <li>ERROR_NULL_ARGUMENT - if the bounds rectangle is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if either the rectangle's
+ * width or height is negative</li>
+ * </ul>
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_NO_HANDLES if a handle could not be obtained for
+ * image creation</li>
+ * </ul>
+ */
+ public Image(Device device, Rectangle bounds) {
+ super(device);
+ if (bounds == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ init(bounds.width, bounds.height);
+ init();
+ }
+
+ /**
+ * Constructs an instance of this class from the given
+ * <code>ImageData</code>.
+ *
+ * @param device
+ * the device on which to create the image
+ * @param data
+ * the image data to create the image from (must not be null)
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if device is null and there is
+ * no current device</li>
+ * <li>ERROR_NULL_ARGUMENT - if the image data is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_UNSUPPORTED_DEPTH - if the depth of the
+ * ImageData is not supported</li>
+ * </ul>
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_NO_HANDLES if a handle could not be obtained for
+ * image creation</li>
+ * </ul>
+ */
+ public Image(Device device, ImageData data) {
+ super(device);
+ init(data);
+ init();
+ }
+
+ /**
+ * Constructs an instance of this class, whose type is <code>SWT.ICON</code>
+ * , from the two given <code>ImageData</code> objects. The two images must
+ * be the same size. Pixel transparency in either image will be ignored.
+ * <p>
+ * The mask image should contain white wherever the icon is to be visible,
+ * and black wherever the icon is to be transparent. In addition, the source
+ * image should contain black wherever the icon is to be transparent.
+ * </p>
+ *
+ * @param device
+ * the device on which to create the icon
+ * @param source
+ * the color data for the icon
+ * @param mask
+ * the mask data for the icon
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if device is null and there is
+ * no current device</li>
+ * <li>ERROR_NULL_ARGUMENT - if either the source or mask is
+ * null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if source and mask are
+ * different sizes</li>
+ * </ul>
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_NO_HANDLES if a handle could not be obtained for
+ * image creation</li>
+ * </ul>
+ */
+ public Image(Device device, ImageData source, ImageData mask) {
+ super(device);
+ if (source == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (mask == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (source.width != mask.width || source.height != mask.height) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ mask = ImageData.convertMask(mask);
+ ImageData image = new ImageData(source.width, source.height, source.depth, source.palette, source.scanlinePad,
+ source.data);
+ image.maskPad = mask.scanlinePad;
+ image.maskData = mask.data;
+ init(image);
+ }
+
+ /**
+ * Constructs an instance of this class by loading its representation from
+ * the specified input stream. Throws an error if an error occurs while
+ * loading the image, or if the result is an image of an unsupported type.
+ * Application code is still responsible for closing the input stream.
+ * <p>
+ * This constructor is provided for convenience when loading a single image
+ * only. If the stream contains multiple images, only the first one will be
+ * loaded. To load multiple images, use <code>ImageLoader.load()</code>.
+ * </p>
+ * <p>
+ * This constructor may be used to load a resource as follows:
+ * </p>
+ *
+ * <pre>
+ * static Image loadImage(Display display, Class clazz, String string) {
+ * InputStream stream = clazz.getResourceAsStream(string);
+ * if (stream == null)
+ * return null;
+ * Image image = null;
+ * try {
+ * image = new Image(display, stream);
+ * } catch (SWTException ex) {
+ * } finally {
+ * try {
+ * stream.close();
+ * } catch (IOException ex) {
+ * }
+ * }
+ * return image;
+ * }
+ * </pre>
+ *
+ * @param device
+ * the device on which to create the image
+ * @param stream
+ * the input stream to load the image from
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if device is null and there is
+ * no current device</li>
+ * <li>ERROR_NULL_ARGUMENT - if the stream is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_IO - if an IO error occurs while reading from
+ * the stream</li>
+ * <li>ERROR_INVALID_IMAGE - if the image stream contains
+ * invalid data</li>
+ * <li>ERROR_UNSUPPORTED_DEPTH - if the image stream
+ * describes an image with an unsupported depth</li>
+ * <li>ERROR_UNSUPPORTED_FORMAT - if the image stream
+ * contains an unrecognized format</li>
+ * </ul>
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_NO_HANDLES if a handle could not be obtained for
+ * image creation</li>
+ * </ul>
+ */
+ public Image(Device device, InputStream stream) {
+ super(device);
+ init(new ImageData(stream));
+ init();
+ }
+
+ /**
+ * Constructs an instance of this class by loading its representation from
+ * the file with the specified name. Throws an error if an error occurs
+ * while loading the image, or if the result is an image of an unsupported
+ * type.
+ * <p>
+ * This constructor is provided for convenience when loading a single image
+ * only. If the specified file contains multiple images, only the first one
+ * will be used.
+ *
+ * @param device
+ * the device on which to create the image
+ * @param filename
+ * the name of the file to load the image from
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if device is null and there is
+ * no current device</li> <li>ERROR_NULL_ARGUMENT - if the
+ * file name is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_IO - if an IO error occurs while reading from
+ * the file</li> <li>ERROR_INVALID_IMAGE - if the image file
+ * contains invalid data </li> <li>ERROR_UNSUPPORTED_DEPTH -
+ * if the image file describes an image with an unsupported
+ * depth</li> <li>ERROR_UNSUPPORTED_FORMAT - if the image
+ * file contains an unrecognized format</li>
+ * </ul>
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_NO_HANDLES if a handle could not be obtained for
+ * image creation</li>
+ * </ul>
+ */
+ public Image(Device device, String filename) {
+ super(device);
+ if (filename == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ initNative(filename);
+ if (this.pixmap == null) {
+ init(new ImageData(filename));
+ }
+ init();
+ }
+
+ void init(int width, int height) {
+ if (width <= 0 || height <= 0) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ this.type = SWT.BITMAP;
+ pixmap = new QPixmap(width, height); //, Format.Format_ARGB32
+ }
+
+ void init(ImageData imageData) {
+ if (imageData == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+
+ this.type = SWT.BITMAP;
+
+ Format format = getImageFormat(imageData);
+ byte[] buffer = imageData2RawData(imageData, format);
+ QImage image = new QImage(buffer, imageData.width, imageData.height, format);
+
+ if (imageData.colorTable != null) {
+ image.setColorTable(imageData.colorTable);
+ }
+
+ if (imageData.maskData != null) {
+ hasMask = true;
+ }
+ updateAlphaChannel(image, imageData);
+
+ pixmap = QPixmap.fromImage(image);
+
+ try {
+ this.transparentPixel = getTransparentPixel(imageData);
+ } catch (Error e) {
+ pixmap = null;
+ throw e;
+ }
+ }
+
+ private Format getImageFormat(ImageData imageData) {
+ switch (imageData.depth) {
+ case 32:
+ return Format.Format_ARGB32;
+ case 24:
+ return Format.Format_RGB888;
+ case 16:
+ return Format.Format_RGB16;
+ case 8:
+ case 4:
+ return Format.Format_Indexed8;
+ case 1:
+ return Format.Format_Mono;
+ default:
+ throw new RuntimeException("invalid color depth"); //$NON-NLS-1$
+ }
+ }
+
+ private void updateAlphaChannel(QImage image, ImageData imageData) {
+ Format format = null;
+ byte[] data = null;
+ if (imageData.maskData != null) {
+ // Mask data is 1 bit/pixel
+ data = imageData.maskData;
+ format = Format.Format_Mono;
+ } else if (imageData.alpha != -1) {
+ data = new byte[image.width() * image.height()];
+ Arrays.fill(data, (byte) alpha);
+ format = Format.Format_Indexed8;
+ } else if (imageData.alphaData != null) {
+ data = imageData.alphaData;
+ format = Format.Format_Indexed8;
+ }
+ if (data != null) {
+ QImage alpha = new QImage(data, imageData.width, imageData.height, format);
+ image.setAlphaChannel(alpha);
+ }
+ }
+
+ private byte[] imageData2RawData(ImageData image, Format format) {
+ PaletteData palette = image.palette;
+ if (!((image.depth == 1 || image.depth == 2 || image.depth == 4 || image.depth == 8) && !palette.isDirect
+ || image.depth == 8 || (image.depth == 16 || image.depth == 24 || image.depth == 32)
+ && palette.isDirect)) {
+ SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
+ }
+
+ byte[] buffer = image.data;
+ if (format.equals(Format.Format_RGB888)) {
+ // swap red and blue bytes
+ for (int i = 0; i < buffer.length - 2; i += 3) {
+ byte tmp = buffer[i + 2];
+ buffer[i + 2] = buffer[i];
+ buffer[i] = tmp;
+ }
+ }
+
+ return buffer;
+ }
+
+ private int getTransparentPixel(ImageData image) {
+ if (image.transparentPixel != -1) {
+ PaletteData palette = image.palette;
+ RGB rgb = null;
+ if (palette.isDirect) {
+ rgb = palette.getRGB(image.transparentPixel);
+ } else {
+ if (image.transparentPixel < palette.colors.length) {
+ rgb = palette.getRGB(image.transparentPixel);
+ }
+ }
+
+ if (rgb != null) {
+ return rgb.red << 24 | rgb.green << 16 | rgb.blue << 8 | 0xFF;
+ }
+ }
+ return -1;
+ }
+
+ void initNative(String filename) {
+ if (filename.toLowerCase().endsWith(".ico")) { //$NON-NLS-1$
+ this.type = SWT.ICON;
+ icon = new QIcon(filename);
+ } else {
+ this.type = SWT.BITMAP;
+ pixmap = new QPixmap(filename);
+ }
+ }
+
+ private QPixmap createGrayImage(Image srcImage) {
+ return srcImage.getQPixmap(); //.convertToFormat(Format.Format_Indexed8, ImageConversionFlag.ThresholdDither);
+ }
+
+ private QPixmap createDisabledImage(Image srcImage) {
+ // TODO the same as gray?
+ return createGrayImage(srcImage);
+ }
+
+ private QImage getQImage() {
+ return pixmap.toImage();
+ }
+
+ public QIcon getQIcon() {
+ // fallback strategy if image is a bitmap
+ if (icon == null) {
+ icon = new QIcon(getQPixmap());
+ }
+ return icon;
+ }
+
+ public QPixmap getQPixmap() {
+ // if (pixmap == null) {
+ // if (image != null) {
+ // pixmap = QPixmap.fromImage(image);
+ // } else if (icon != null) {
+ // pixmap = icon.pixmap(getDefaultIconSize());
+ // }
+ // }
+ return pixmap;
+ }
+
+ public QSize getDefaultIconSize() {
+ List<QSize> sizes = getQIcon().availableSizes();
+ if (sizes.isEmpty()) {
+ return new QSize();
+ }
+ return sizes.get(0);
+ }
+
+ public boolean isIcon() {
+ return type == SWT.ICON;
+ }
+
+ public boolean isBitmap() {
+ return type == SWT.BITMAP;
+ }
+
+ @Override
+ void destroy() {
+ if (memGC != null) {
+ memGC.dispose();
+ memGC = null;
+ }
+ // image = null;
+ // icon = null;
+ pixmap = null;
+ }
+
+ /**
+ * Compares the argument to the receiver, and returns true if they represent
+ * the <em>same</em> object using a class specific comparison.
+ *
+ * @param object
+ * the object to compare with this object
+ * @return <code>true</code> if the object is the same as this object and
+ * <code>false</code> otherwise
+ *
+ * @see #hashCode
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (!(object instanceof Image)) {
+ return false;
+ }
+ Image other = (Image) object;
+ return device == other.device && pixmap == other.pixmap && transparentPixel == other.transparentPixel;
+ }
+
+ /**
+ * Returns the color to which to map the transparent pixel, or null if the
+ * receiver has no transparent pixel.
+ * <p>
+ * There are certain uses of Images that do not support transparency (for
+ * example, setting an image into a button or label). In these cases, it may
+ * be desired to simulate transparency by using the background color of the
+ * widget to paint the transparent pixels of the image. Use this method to
+ * check which color will be used in these cases in place of transparency.
+ * This value may be set with setBackground().
+ * <p>
+ *
+ * @return the background color of the image, or null if there is no
+ * transparency in the image
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public Color getBackground() {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (transparentPixel == -1) {
+ return null;
+ }
+ int red = transparentPixel >> 16 & 0xFF;
+ int green = transparentPixel >> 8 & 0xFF;
+ int blue = transparentPixel >> 0 & 0xFF;
+ return new Color(device, red, green, blue);
+ }
+
+ /**
+ * Returns the bounds of the receiver. The rectangle will always have x and
+ * y values of 0, and the width and height of the image.
+ *
+ * @return a rectangle specifying the image's bounds
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * <li>ERROR_INVALID_IMAGE - if the image is not a bitmap or
+ * an icon</li>
+ * </ul>
+ */
+ public Rectangle getBounds() {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+
+ return new Rectangle(0, 0, pixmap.width(), pixmap.height());
+ }
+
+ /**
+ * Returns an <code>ImageData</code> based on the receiver Modifications
+ * made to this <code>ImageData</code> will not affect the Image.
+ *
+ * @return an <code>ImageData</code> containing the image's data and
+ * attributes
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * <li>ERROR_INVALID_IMAGE - if the image is not a bitmap or
+ * an icon</li>
+ * </ul>
+ *
+ * @see ImageData
+ */
+ public ImageData getImageData() {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+
+ QImage image = getQImage();
+
+ PaletteData palette = new PaletteData(0x00FF0000, 0x00FF00, 0x00FF);
+ ImageData imageData = new ImageData(image.width(), image.height(), image.depth(), palette, 4, image
+ .copyOfBytes());
+ imageData.bytesPerLine = image.bytesPerLine();
+ imageData.transparentPixel = -1;
+ imageData.alpha = alpha;
+ imageData.alphaData = getAlphaData(image);
+
+ if (image.numColors() > 0) {
+ List<Integer> colorTable = image.colorTable();
+ imageData.colorTable = colorTable;
+ }
+
+ return imageData;
+ }
+
+ private byte[] getAlphaData(QImage image) {
+ if (hasMask) {
+ // Mask data is 1 bit/pixel
+ if (image.hasAlphaChannel()) {
+ QImage alpha = image.alphaChannel();
+ alpha.convertToFormat(Format.Format_Mono);
+ return alpha.copyOfBytes();
+ } else {
+ int maskSize = image.width() * image.height() / 8;
+ byte[] alphaData = new byte[maskSize];
+ Arrays.fill(alphaData, (byte) 0xFF);
+ return alphaData;
+ //imageData.maskPad = 8;
+ }
+ } else if (alpha != -1) {
+ byte[] alphaData = new byte[image.width() * image.height()];
+ Arrays.fill(alphaData, (byte) alpha);
+ return alphaData;
+ } else if (image.hasAlphaChannel()) {
+ QImage alpha = image.alphaChannel();
+ return alpha.copyOfBytes();
+ }
+ return null;
+ }
+
+ public static Image qt_new(Display device, int type, QIcon qIcon) {
+ Image image = new Image(device);
+ image.type = type;
+ image.icon = qIcon;
+ return image;
+ }
+
+ /**
+ * Returns an integer hash code for the receiver. Any two objects that
+ * return <code>true</code> when passed to <code>equals</code> must return
+ * the same value for this method.
+ *
+ * @return the receiver's hash
+ *
+ * @see #equals
+ */
+ @Override
+ public int hashCode() {
+ return pixmap != null ? (int) pixmap.hashCode() : 0;
+ }
+
+ /**
+ * 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>Image</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 QPaintDeviceInterface internal_new_GC(GCData data) {
+ data.backgroundColor = getBackground();
+ data.device = device;
+ return pixmap;
+ }
+
+ /**
+ * 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>Image</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(QPaintDeviceInterface paintDevice, GCData data) {
+ }
+
+ /**
+ * Returns <code>true</code> if the image has been disposed, and
+ * <code>false</code> otherwise.
+ * <p>
+ * This method gets the dispose state for the image. When an image has been
+ * disposed, it is an error to invoke any other method using the image.
+ *
+ * @return <code>true</code> when the image is disposed and
+ * <code>false</code> otherwise
+ */
+ @Override
+ public boolean isDisposed() {
+ return pixmap == null && icon == null;
+ }
+
+ /**
+ * Sets the color to which to map the transparent pixel.
+ * <p>
+ * There are certain uses of <code>Images</code> that do not support
+ * transparency (for example, setting an image into a button or label). In
+ * these cases, it may be desired to simulate transparency by using the
+ * background color of the widget to paint the transparent pixels of the
+ * image. This method specifies the color that will be used in these cases.
+ * For example:
+ *
+ * <pre>
+ * Button b = new Button();
+ * image.setBackground(b.getBackground());
+ * b.setImage(image);
+ * </pre>
+ *
+ * </p>
+ * <p>
+ * The image may be modified by this operation (in effect, the transparent
+ * regions may be filled with the supplied color). Hence this operation is
+ * not reversible and it is not legal to call this function twice or with a
+ * null argument.
+ * </p>
+ * <p>
+ * This method has no effect if the receiver does not have a transparent
+ * pixel value.
+ * </p>
+ *
+ * @param color
+ * the color to use when a transparent pixel is specified
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the color is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the color has been
+ * disposed</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void setBackground(Color color) {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (color == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (color.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ if (transparentPixel == -1) {
+ return;
+ }
+ return; // TODO function disabled
+ // byte red = (byte) ((transparentPixel >> 16) & 0xFF);
+ // byte green = (byte) ((transparentPixel >> 8) & 0xFF);
+ // byte blue = (byte) ((transparentPixel >> 0) & 0xFF);
+ // byte newRed = (byte) ((int) (color.handle[0] * 255) & 0xFF);
+ // byte newGreen = (byte) ((int) (color.handle[1] * 255) & 0xFF);
+ // byte newBlue = (byte) ((int) (color.handle[2] * 255) & 0xFF);
+ // NSBitmapImageRep imageRep = getRepresentation();
+ // long /* int */bpr = imageRep.bytesPerRow();
+ // long /* int */data = imageRep.bitmapData();
+ // byte[] line = new byte[(int) bpr];
+ // for (int i = 0, offset = 0; i < height; i++, offset += bpr) {
+ // OS.memmove(line, data + offset, bpr);
+ // for (int j = 0; j < line.length; j += 4) {
+ // if (line[j + 1] == red && line[j + 2] == green
+ // && line[j + 3] == blue) {
+ // line[j + 1] = newRed;
+ // line[j + 2] = newGreen;
+ // line[j + 3] = newBlue;
+ // }
+ // }
+ // OS.memmove(data + offset, line, bpr);
+ // }
+ // transparentPixel = (newRed & 0xFF) << 16 | (newGreen & 0xFF) << 8
+ // | (newBlue & 0xFF);
+ }
+
+ /**
+ * Returns a string containing a concise, human-readable description of the
+ * receiver.
+ *
+ * @return a string representation of the receiver
+ */
+ @Override
+ public String toString() {
+ if (isDisposed()) {
+ return "Image {*DISPOSED*}"; //$NON-NLS-1$
+ }
+ return "Image {pixmap: " + pixmap + ", icon: " + icon + " }"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ public void setMemGC(GC gc) {
+ this.memGC = gc;
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Region.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Region.java
new file mode 100644
index 0000000000..23c2ec90e0
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/Region.java
@@ -0,0 +1,776 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.graphics;
+
+import com.trolltech.qt.core.QPoint;
+import com.trolltech.qt.core.QRect;
+import com.trolltech.qt.gui.QRegion;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTError;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.internal.qt.QtSWTConverter;
+
+/**
+ * Instances of this class represent areas of an x-y coordinate system that are
+ * aggregates of the areas covered by a number of polygons.
+ * <p>
+ * Application code must explicitly invoke the <code>Region.dispose()</code>
+ * method to release the operating system resources managed by each instance
+ * when those instances are no longer required.
+ * </p>
+ *
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * GraphicsExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ */
+
+public final class Region extends Resource {
+
+ /**
+ * the OS resource for the region (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>
+ */
+ private QRegion region;
+
+ /**
+ * Constructs a new empty region.
+ *
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_NO_HANDLES if a handle could not be obtained for
+ * region creation</li>
+ * </ul>
+ */
+ public Region() {
+ this(null);
+ }
+
+ /**
+ * Constructs a new empty region.
+ * <p>
+ * You must dispose the region when it is no longer required.
+ * </p>
+ *
+ * @param device
+ * the device on which to allocate the region
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if device is null and there is
+ * no current device</li>
+ * </ul>
+ * @exception SWTError
+ * <ul>
+ * <li>ERROR_NO_HANDLES if a handle could not be obtained for
+ * region creation</li>
+ * </ul>
+ *
+ * @see #dispose
+ *
+ * @since 3.0
+ */
+ public Region(Device device) {
+ super(device);
+ region = new QRegion();
+ init();
+ }
+
+ /**
+ * Constructs a new region given a handle to the operating system resources
+ * that it should represent.
+ *
+ * @param handle
+ * the handle for the result
+ */
+ Region(Device device, QRegion region) {
+ super(device);
+ this.region = region;
+ }
+
+ QRegion getQRegion() {
+ return region;
+ }
+
+ /**
+ * Adds the given polygon to the collection of polygons the receiver
+ * maintains to describe its area.
+ *
+ * @param pointArray
+ * points that describe the polygon to merge with the receiver
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.0
+ *
+ */
+ public void add(int[] pointArray) {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (pointArray == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ QRegion rg = new QRegion(GC.createPolygonFromArray(pointArray));
+ region = region.united(rg);
+ }
+
+ /**
+ * Adds the given rectangle to the collection of polygons the receiver
+ * maintains to describe its area.
+ *
+ * @param rect
+ * the rectangle to merge with the receiver
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or
+ * height is negative</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void add(Rectangle rect) {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (rect == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ region = region.unite(QtSWTConverter.convert(rect));
+ }
+
+ /**
+ * Adds the given rectangle to the collection of polygons the receiver
+ * maintains to describe its area.
+ *
+ * @param x
+ * the x coordinate of the rectangle
+ * @param y
+ * the y coordinate of the rectangle
+ * @param width
+ * the width coordinate of the rectangle
+ * @param height
+ * the height coordinate of the rectangle
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or
+ * height is negative</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+ public void add(int x, int y, int width, int height) {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (width < 0 || height < 0) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ region = region.united(new QRect(x, y, width, height));
+ }
+
+ /**
+ * Adds all of the polygons which make up the area covered by the argument
+ * to the collection of polygons the receiver maintains to describe its
+ * area.
+ *
+ * @param region
+ * the region to merge
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been
+ * disposed</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public void add(Region region) {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (region == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (region.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ this.region = this.region.united(region.getQRegion());
+ }
+
+ /**
+ * Returns <code>true</code> if the point specified by the arguments is
+ * inside the area specified by the receiver, and <code>false</code>
+ * otherwise.
+ *
+ * @param x
+ * the x coordinate of the point to test for containment
+ * @param y
+ * the y coordinate of the point to test for containment
+ * @return <code>true</code> if the region contains the point and
+ * <code>false</code> otherwise
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public boolean contains(int x, int y) {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return region.contains(new QPoint(x, y));
+ }
+
+ /**
+ * Returns <code>true</code> if the given point is inside the area specified
+ * by the receiver, and <code>false</code> otherwise.
+ *
+ * @param pt
+ * the point to test for containment
+ * @return <code>true</code> if the region contains the point and
+ * <code>false</code> otherwise
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public boolean contains(Point pt) {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (pt == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ return region.contains(QtSWTConverter.convert(pt));
+ }
+
+ @Override
+ void destroy() {
+ region = null;
+ }
+
+ /**
+ * Compares the argument to the receiver, and returns true if they represent
+ * the <em>same</em> object using a class specific comparison.
+ *
+ * @param object
+ * the object to compare with this object
+ * @return <code>true</code> if the object is the same as this object and
+ * <code>false</code> otherwise
+ *
+ * @see #hashCode
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof Region)) {
+ return false;
+ }
+ return region.equals(((Region) object).getQRegion());
+ }
+
+ /**
+ * Returns a rectangle which represents the rectangular union of the
+ * collection of polygons the receiver maintains to describe its area.
+ *
+ * @return a bounding rectangle for the region
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see Rectangle#union
+ */
+ public Rectangle getBounds() {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return QtSWTConverter.convert(region.boundingRect());
+ }
+
+ /**
+ * Returns an integer hash code for the receiver. Any two objects that
+ * return <code>true</code> when passed to <code>equals</code> must return
+ * the same value for this method.
+ *
+ * @return the receiver's hash
+ *
+ * @see #equals
+ */
+ @Override
+ public int hashCode() {
+ return region.hashCode();
+ }
+
+ /**
+ * Intersects the given rectangle to the collection of polygons the receiver
+ * maintains to describe its area.
+ *
+ * @param rect
+ * the rectangle to intersect with the receiver
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or
+ * height is negative</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+ public void intersect(Rectangle rect) {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (rect == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ intersect(rect.x, rect.y, rect.width, rect.height);
+ }
+
+ /**
+ * Intersects the given rectangle to the collection of polygons the receiver
+ * maintains to describe its area.
+ *
+ * @param x
+ * the x coordinate of the rectangle
+ * @param y
+ * the y coordinate of the rectangle
+ * @param width
+ * the width coordinate of the rectangle
+ * @param height
+ * the height coordinate of the rectangle
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or
+ * height is negative</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+ public void intersect(int x, int y, int width, int height) {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (width < 0 || height < 0) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ region = region.intersect(new QRect(x, y, width, height));
+ }
+
+ /**
+ * Intersects all of the polygons which make up the area covered by the
+ * argument to the collection of polygons the receiver maintains to describe
+ * its area.
+ *
+ * @param region
+ * the region to intersect
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been
+ * disposed</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+ public void intersect(Region region) {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (region == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (region.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ this.region = this.region.intersected(region.getQRegion());
+ }
+
+ /**
+ * Returns <code>true</code> if the rectangle described by the arguments
+ * intersects with any of the polygons the receiver maintains to describe
+ * its area, and <code>false</code> otherwise.
+ *
+ * @param x
+ * the x coordinate of the origin of the rectangle
+ * @param y
+ * the y coordinate of the origin of the rectangle
+ * @param width
+ * the width of the rectangle
+ * @param height
+ * the height of the rectangle
+ * @return <code>true</code> if the rectangle intersects with the receiver,
+ * and <code>false</code> otherwise
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see Rectangle#intersects(Rectangle)
+ */
+ public boolean intersects(int x, int y, int width, int height) {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return region.intersects(new QRect(x, y, width, height));
+ }
+
+ /**
+ * Returns <code>true</code> if the given rectangle intersects with any of
+ * the polygons the receiver maintains to describe its area and
+ * <code>false</code> otherwise.
+ *
+ * @param rect
+ * the rectangle to test for intersection
+ * @return <code>true</code> if the rectangle intersects with the receiver,
+ * and <code>false</code> otherwise
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see Rectangle#intersects(Rectangle)
+ */
+ public boolean intersects(Rectangle rect) {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (rect == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ return intersects(rect.x, rect.y, rect.width, rect.height);
+ }
+
+ /**
+ * Returns <code>true</code> if the region has been disposed, and
+ * <code>false</code> otherwise.
+ * <p>
+ * This method gets the dispose state for the region. When a region has been
+ * disposed, it is an error to invoke any other method using the region.
+ *
+ * @return <code>true</code> when the region is disposed, and
+ * <code>false</code> otherwise
+ */
+ @Override
+ public boolean isDisposed() {
+ return region == null;
+ }
+
+ /**
+ * Returns <code>true</code> if the receiver does not cover any area in the
+ * (x, y) coordinate plane, and <code>false</code> if the receiver does
+ * cover some area in the plane.
+ *
+ * @return <code>true</code> if the receiver is empty, and
+ * <code>false</code> otherwise
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ */
+ public boolean isEmpty() {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ return region.isEmpty();
+ }
+
+ /**
+ * Subtracts the given polygon from the collection of polygons the receiver
+ * maintains to describe its area.
+ *
+ * @param pointArray
+ * points that describe the polygon to merge with the receiver
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+ public void subtract(int[] pointArray) {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (pointArray == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ QRegion rg = new QRegion(GC.createPolygonFromArray(pointArray));
+ region = region.subtracted(rg);
+ }
+
+ /**
+ * Subtracts the given rectangle from the collection of polygons the
+ * receiver maintains to describe its area.
+ *
+ * @param rect
+ * the rectangle to subtract from the receiver
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or
+ * height is negative</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+ public void subtract(Rectangle rect) {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (rect == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ subtract(rect.x, rect.y, rect.width, rect.height);
+ }
+
+ /**
+ * Subtracts the given rectangle from the collection of polygons the
+ * receiver maintains to describe its area.
+ *
+ * @param x
+ * the x coordinate of the rectangle
+ * @param y
+ * the y coordinate of the rectangle
+ * @param width
+ * the width coordinate of the rectangle
+ * @param height
+ * the height coordinate of the rectangle
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or
+ * height is negative</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+ public void subtract(int x, int y, int width, int height) {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (width < 0 || height < 0) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ region = region.subtracted(new QRegion(x, y, width, height));
+ }
+
+ /**
+ * Subtracts all of the polygons which make up the area covered by the
+ * argument from the collection of polygons the receiver maintains to
+ * describe its area.
+ *
+ * @param region
+ * the region to subtract
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the argument has been
+ * disposed</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+ public void subtract(Region region) {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (region == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (region.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ this.region = this.region.subtracted(region.getQRegion());
+ }
+
+ /**
+ * Translate all of the polygons the receiver maintains to describe its area
+ * by the specified point.
+ *
+ * @param x
+ * the x coordinate of the point to translate
+ * @param y
+ * the y coordinate of the point to translate
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+ public void translate(int x, int y) {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ region = region.translated(x, y);
+ }
+
+ /**
+ * Translate all of the polygons the receiver maintains to describe its area
+ * by the specified point.
+ *
+ * @param pt
+ * the point to translate
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
+ * </ul>
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+ public void translate(Point pt) {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ }
+ if (pt == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ translate(pt.x, pt.y);
+ }
+
+ /**
+ * Returns a string containing a concise, human-readable description of the
+ * receiver.
+ *
+ * @return a string representation of the receiver
+ */
+ @Override
+ public String toString() {
+ if (isDisposed()) {
+ return "Region {*DISPOSED*}"; //$NON-NLS-1$
+ }
+ return "Region {" + region + "}"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Invokes platform specific functionality to allocate a new region.
+ * <p>
+ * <b>IMPORTANT:</b> This method is <em>not</em> part of the public API for
+ * <code>Region</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 device
+ * the device on which to allocate the region
+ * @param handle
+ * the handle for the region
+ * @return a new region object containing the specified device and handle
+ */
+ public static Region win32_new(Device device, QRegion region) {
+ return new Region(device, region);
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/DragNDropListener.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/DragNDropListener.java
new file mode 100644
index 0000000000..2850edc6d3
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/DragNDropListener.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 compeople AG 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:
+ * compeople AG - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal.qt;
+
+import com.trolltech.qt.gui.QDragEnterEvent;
+import com.trolltech.qt.gui.QDragLeaveEvent;
+import com.trolltech.qt.gui.QDragMoveEvent;
+import com.trolltech.qt.gui.QDropEvent;
+
+public interface DragNDropListener {
+
+ public void dragEnter(QDragEnterEvent event);
+
+ public void dragLeave(QDragLeaveEvent event);
+
+ public void dragMove(QDragMoveEvent event);
+
+ public void drop(QDropEvent event);
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/FontConverter.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/FontConverter.java
new file mode 100644
index 0000000000..cd042cf785
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/FontConverter.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 compeople AG 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:
+ * compeople AG - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal.qt;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import com.trolltech.qt.gui.QFont;
+import com.trolltech.qt.gui.QFont.Weight;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+
+/**
+ * @author kriese
+ *
+ */
+public class FontConverter {
+
+ private List<FontNameTuple> fontNames;
+ private List<FontStyleTuple> fontStyles;
+
+ public FontConverter() {
+ fontNames = new LinkedList<FontNameTuple>();
+ fontNames.add(new FontNameTuple("Arial", "Times")); //$NON-NLS-1$ //$NON-NLS-2$
+
+ fontStyles = new LinkedList<FontStyleTuple>();
+ fontStyles.add(new FontStyleTuple(SWT.BOLD, QFont.Weight.Bold));
+ fontStyles.add(new FontStyleTuple(SWT.NORMAL, QFont.Weight.Normal));
+ }
+
+ public QFont getQtFont(Font swtFont) {
+
+ FontNameTuple tuple = null;
+ for (FontNameTuple f : fontNames) {
+ if (f.getSwtFontName().equals(swtFont.getFontData()[0].getName())) {
+ tuple = f;
+ }
+ }
+
+ // swtFont.getFontData()[0].get
+
+ FontStyleTuple style = null;
+ for (FontStyleTuple s : fontStyles) {
+ if (s.getSwtStyle() == swtFont.getFontData()[0].getStyle()) {
+ style = s;
+ }
+ }
+
+ if (null != tuple) {
+
+ if (null != style) {
+ return new QFont(tuple.getQtFontName(), swtFont.getFontData()[0].getHeight(), style.getQtStyle()
+ .value());
+ }
+
+ return new QFont(tuple.getQtFontName(), swtFont.getFontData()[0].getHeight());
+ }
+
+ return null;
+ }
+
+ private static class FontStyleTuple {
+ private QFont.Weight qtStyle;
+ private int swtStyle;
+
+ public FontStyleTuple(int swtStyle, Weight qtStyle) {
+ super();
+ this.qtStyle = qtStyle;
+ this.swtStyle = swtStyle;
+ }
+
+ public QFont.Weight getQtStyle() {
+ return qtStyle;
+ }
+
+ public int getSwtStyle() {
+ return swtStyle;
+ }
+ }
+
+ private static class FontNameTuple {
+ private String swtFontName;
+ private String qtFontName;
+
+ public FontNameTuple(String swtFontName, String qtFontName) {
+ this.swtFontName = swtFontName;
+ this.qtFontName = qtFontName;
+ }
+
+ public String getSwtFontName() {
+ return swtFontName;
+ }
+
+ public String getQtFontName() {
+ return qtFontName;
+ }
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/KeyUtil.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/KeyUtil.java
new file mode 100644
index 0000000000..9d25fa7a1f
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/KeyUtil.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 compeople AG 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:
+ * compeople AG - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal.qt;
+
+import com.trolltech.qt.core.Qt.Key;
+import com.trolltech.qt.core.Qt.KeyboardModifier;
+import com.trolltech.qt.core.Qt.KeyboardModifiers;
+import com.trolltech.qt.gui.QKeyEvent;
+
+import org.eclipse.swt.SWT;
+
+/**
+ * Helper class for Key translation SWT &lt;-&gt; Qt
+ */
+public class KeyUtil {
+ /* Key Mappings */
+ private static final int[][] KeyTable = {
+ /* Keyboard and Mouse Masks */
+ { Key.Key_Alt.value(), SWT.ALT }, { Key.Key_AltGr.value(), SWT.ALT }, { Key.Key_Meta.value(), SWT.ALT },
+ { Key.Key_Shift.value(), SWT.SHIFT }, { Key.Key_Control.value(), SWT.CONTROL },
+ /* Non-Numeric Keypad Keys */
+ { Key.Key_Up.value(), SWT.ARROW_UP }, { Key.Key_Down.value(), SWT.ARROW_DOWN },
+ { Key.Key_Left.value(), SWT.ARROW_LEFT }, { Key.Key_Right.value(), SWT.ARROW_RIGHT },
+ { Key.Key_PageUp.value(), SWT.PAGE_UP }, { Key.Key_PageDown.value(), SWT.PAGE_DOWN },
+ { Key.Key_Home.value(), SWT.HOME }, { Key.Key_End.value(), SWT.END },
+ { Key.Key_Insert.value(), SWT.INSERT },
+ /* Virtual and Ascii Keys */
+ { Key.Key_Space.value(), ' ' }, { Key.Key_Backspace.value(), SWT.BS }, { Key.Key_Return.value(), SWT.CR },
+ { Key.Key_Delete.value(), SWT.DEL }, { Key.Key_Escape.value(), SWT.ESC },
+ { Key.Key_Enter.value(), SWT.CR }, { Key.Key_Tab.value(), SWT.TAB }, { Key.Key_Backtab.value(), SWT.TAB },
+ /* Functions Keys */
+ { Key.Key_F1.value(), SWT.F1 }, { Key.Key_F2.value(), SWT.F2 }, { Key.Key_F3.value(), SWT.F3 },
+ { Key.Key_F4.value(), SWT.F4 }, { Key.Key_F5.value(), SWT.F5 }, { Key.Key_F6.value(), SWT.F6 },
+ { Key.Key_F7.value(), SWT.F7 }, { Key.Key_F8.value(), SWT.F8 }, { Key.Key_F9.value(), SWT.F9 },
+ { Key.Key_F10.value(), SWT.F10 }, { Key.Key_F11.value(), SWT.F11 }, { Key.Key_F12.value(), SWT.F12 },
+ { Key.Key_F13.value(), SWT.F13 }, { Key.Key_F14.value(), SWT.F14 }, { Key.Key_F15.value(), SWT.F15 },
+ /* Other keys */
+ { Key.Key_CapsLock.value(), SWT.CAPS_LOCK }, { Key.Key_NumLock.value(), SWT.NUM_LOCK },
+ { Key.Key_ScrollLock.value(), SWT.SCROLL_LOCK }, { Key.Key_Pause.value(), SWT.PAUSE },
+ { Key.Key_Print.value(), SWT.PRINT_SCREEN }, { Key.Key_Help.value(), SWT.HELP },
+
+ };
+
+ private static final int[][] KeyPadKeyTable = {
+ /* Numeric Keypad Keys */
+ { Key.Key_Asterisk.value(), SWT.KEYPAD_MULTIPLY }, { Key.Key_Plus.value(), SWT.KEYPAD_ADD },
+ { Key.Key_Enter.value(), SWT.KEYPAD_CR }, { Key.Key_Minus.value(), SWT.KEYPAD_SUBTRACT },
+ { Key.Key_Period.value(), SWT.KEYPAD_DECIMAL }, { Key.Key_Slash.value(), SWT.KEYPAD_DIVIDE },
+ { Key.Key_0.value(), SWT.KEYPAD_0 }, { Key.Key_1.value(), SWT.KEYPAD_1 },
+ { Key.Key_2.value(), SWT.KEYPAD_2 }, { Key.Key_3.value(), SWT.KEYPAD_3 },
+ { Key.Key_4.value(), SWT.KEYPAD_4 }, { Key.Key_5.value(), SWT.KEYPAD_5 },
+ { Key.Key_6.value(), SWT.KEYPAD_6 }, { Key.Key_7.value(), SWT.KEYPAD_7 },
+ { Key.Key_8.value(), SWT.KEYPAD_8 }, { Key.Key_9.value(), SWT.KEYPAD_9 },
+ { Key.Key_Equal.value(), SWT.KEYPAD_EQUAL }, };
+
+ private KeyUtil() {
+ // utility class
+ }
+
+ public static int translateKey(int key) {
+ for (int i = 0; i < KeyTable.length; i++) {
+ if (KeyTable[i][0] == key) {
+ return KeyTable[i][1];
+ }
+ }
+ return 0;
+ }
+
+ public static int untranslateKey(int key) {
+ for (int i = 0; i < KeyTable.length; i++) {
+ if (KeyTable[i][1] == key) {
+ return KeyTable[i][0];
+ }
+ }
+ return 0;
+ }
+
+ // Converts keys from Qt to SWT
+ public static final int translateKey(QKeyEvent qEvent) {
+ int key = qEvent.key();
+ boolean keypad = qEvent.modifiers().isSet(KeyboardModifier.KeypadModifier);
+ if (keypad) {
+ for (int i = 0; i < KeyPadKeyTable.length; i++) {
+ if (KeyPadKeyTable[i][0] == key) {
+ return KeyPadKeyTable[i][1];
+ }
+ }
+ }
+ for (int i = 0; i < KeyTable.length; i++) {
+ if (KeyTable[i][0] == key) {
+ return KeyTable[i][1];
+ }
+ }
+ return 0;
+ }
+
+ // Converts modifiers from Qt to SWT
+ public static final int translateModifiers(KeyboardModifiers nativeModifiers) {
+ int modifiers = 0;
+ if (nativeModifiers.isSet(KeyboardModifier.AltModifier)) {
+ modifiers |= SWT.ALT;
+ }
+ if (nativeModifiers.isSet(KeyboardModifier.ShiftModifier)) {
+ modifiers |= SWT.SHIFT;
+ }
+ if (nativeModifiers.isSet(KeyboardModifier.ControlModifier)) {
+ modifiers |= SWT.CONTROL;
+ }
+ return modifiers;
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/QtSWTConverter.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/QtSWTConverter.java
new file mode 100644
index 0000000000..e67a631c38
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/QtSWTConverter.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 compeople AG 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:
+ * compeople AG - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal.qt;
+
+import com.trolltech.qt.core.QPoint;
+import com.trolltech.qt.core.QRect;
+import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.gui.QColor;
+import com.trolltech.qt.gui.QRegion;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.graphics.Region;
+
+/**
+ * @author J�rgen Becker
+ *
+ */
+public class QtSWTConverter {
+
+ private QtSWTConverter() {
+ // utility class
+ }
+
+ public static Rectangle convert(QRect rect) {
+ if (rect == null) {
+ return null;
+ }
+ return new Rectangle(rect.x(), rect.y(), rect.width(), rect.height());
+ }
+
+ public static QRect convert(Rectangle rect) {
+ if (rect == null) {
+ return null;
+ }
+ return new QRect(rect.x, rect.y, rect.width, rect.height);
+ }
+
+ public static Point convert(QSize size) {
+ if (size == null) {
+ return null;
+ }
+ return new Point(size.width(), size.height());
+ }
+
+ public static Point convert(QPoint point) {
+ if (point == null) {
+ return null;
+ }
+ return new Point(point.x(), point.y());
+ }
+
+ public static Point convertPosition(QRect rect) {
+ if (rect == null) {
+ return null;
+ }
+ return new Point(rect.x(), rect.y());
+ }
+
+ public static Point convertSize(QRect rect) {
+ if (rect == null) {
+ return null;
+ }
+ return new Point(rect.width(), rect.height());
+ }
+
+ public static QPoint convert(Point point) {
+ if (point == null) {
+ return null;
+ }
+ return new QPoint(point.x, point.y);
+ }
+
+ public static QColor convert(Color color) {
+ if (color == null) {
+ return null;
+ }
+ return new QColor(color.getRed(), color.getGreen(), color.getBlue());
+ }
+
+ public static Color convert(QColor color) {
+ if (color == null) {
+ return null;
+ }
+ return new Color(null, color.red(), color.green(), color.blue());
+ }
+
+ public static QRegion convert(Region region) {
+ if (region == null) {
+ return null;
+ }
+ return new QRegion(convert(region.getBounds()));
+ }
+
+ public static Rectangle convert(QRegion region) {
+ if (region == null) {
+ return null;
+ }
+ return convert(region.boundingRect());
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/QtSupplementaryFontData.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/QtSupplementaryFontData.java
new file mode 100644
index 0000000000..b7343e54d0
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/QtSupplementaryFontData.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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:
+ * Nokia Corporation - initial implementation
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+
+package org.eclipse.swt.internal.qt;
+
+import com.trolltech.qt.gui.QFont.Style;
+import com.trolltech.qt.gui.QFont.StyleStrategy;
+
+public final class QtSupplementaryFontData {
+ public int underline = -1;
+ public int overline = -1;
+ public int strikeOut = -1;
+ public int stretch = -1;
+ public int fixedPitch = -1;
+ public Style style = null;
+ public int weight = -1;
+ public StyleStrategy styleStrategy = null;
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/SWQT.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/SWQT.java
new file mode 100644
index 0000000000..e1761859b4
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/SWQT.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010s compeople AG 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:
+ * compeople AG - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal.qt;
+
+public class SWQT {
+
+ /* Widget Event Constants */
+
+ /**
+ * The null event type (value is 0).
+ *
+ * @since 3.0
+ */
+ public static final int StyleSheetChange = 1024;
+
+ /**
+ *
+ */
+ public static final String STYLESHEET_KEY = "stylesheet"; //$NON-NLS-1$
+
+ // Qt QFont::Weight
+ public static final int QT_FONTNORMAL = 50;
+ public static final int QT_FONTBOLD = 75;
+
+ // QFont::Style
+ public static final int QFONT_STYLE_NORMAL = 0;
+ public static final int QFONT_STYLE_ITALIC = 1;
+ public static final int QFONT_STYLE_OBLIQUE = 2;
+
+ // QFont::StyleStrategy
+ public static final int QFONT_STYLESTRATEGY_PREFERDEFALUT = 0x0001;
+ public static final int QFONT_STYLESTRATEGY_PREFERBITMAP = 0x0002;
+ public static final int QFONT_STYLESTRATEGY_PREFERDEVICE = 0x0004;
+ public static final int QFONT_STYLESTRATEGY_PREFEROUTLINE = 0x0008;
+ public static final int QFONT_STYLESTRATEGY_FORCEOUTLINE = 0x0010;
+ public static final int QFONT_STYLESTRATEGY_NOANTIALIAS = 0x0100;
+ public static final int QFONT_STYLESTRATEGY_PREFERANTIALIAS = 0x0080;
+ public static final int QFONT_STYLESTRATEGY_OPENGLCOMPATIABLE = 0x0200;
+ public static final int QFONT_STYLESTRATEGY_NOFONTMERGING = 0x8000;
+ public static final int QFONT_STYLESTRATEGY_PREFERMATCH = 0x0020;
+ public static final int QFONT_STYLESTRATEGY_PREFERQUALITY = 0x0040;
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/SignalConnector.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/SignalConnector.java
new file mode 100644
index 0000000000..08414ac5ec
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/SignalConnector.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 compeople AG 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:
+ * compeople AG - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal.qt;
+
+import com.trolltech.qt.QSignalEmitter.AbstractSignal;
+
+/**
+ * A {@code SignalConnector} is the representation of a certain signal,
+ * receiver, method tuple. This tuple allows connecting and disconnecting from
+ * the signal - without the need of constantly repeating (error-prone) the
+ * necessary parameters.
+ */
+public class SignalConnector {
+
+ private final AbstractSignal signal;
+ private final Object receiver;
+ private final String method;
+
+ /**
+ * Create a {@code SignalConnector} from the given parameters.
+ *
+ * @param signal
+ * the signal
+ * @param receiver
+ * the receiver of the signal
+ * @param method
+ * the reveiver's method
+ */
+ public SignalConnector(final AbstractSignal signal, final Object receiver, final String method) {
+ this.signal = signal;
+ this.receiver = receiver;
+ this.method = method;
+ }
+
+ /**
+ * Connect the signal.
+ *
+ * @return this object.
+ */
+ public SignalConnector connect() {
+ signal.connect(receiver, method);
+ return this;
+ }
+
+ /**
+ * Disconnect the signal.
+ */
+ public void disconnect() {
+ signal.disconnect(receiver, method);
+ }
+
+ /**
+ * Run the given {@code Runnable} with disconnecting before and
+ * re-connection afterwards.
+ *
+ * @param runnable
+ */
+ public void runDisconnected(final Runnable runnable) {
+ try {
+ disconnect();
+ runnable.run();
+ } finally {
+ connect();
+ }
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/StylableScrollArea.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/StylableScrollArea.java
new file mode 100644
index 0000000000..ef6bef9263
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/StylableScrollArea.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2009 compeople AG 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:
+ * compeople AG - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal.qt;
+
+import com.trolltech.qt.QtPropertyResetter;
+import com.trolltech.qt.gui.QColor;
+import com.trolltech.qt.gui.QScrollArea;
+
+public class StylableScrollArea extends QScrollArea {
+ private QColor gradientStart = new QColor(0, 0, 255);
+ private QColor gradientEnd = new QColor(0, 255, 0);
+ private QColor text = new QColor(0, 0, 0);
+ private QColor border = new QColor(255, 255, 255);
+
+ public QColor getGradientStart() {
+ return gradientStart;
+ }
+
+ public void setGradientStart(QColor gradientStart) {
+ this.gradientStart = gradientStart;
+ }
+
+ @QtPropertyResetter(name = "gradientStart")
+ public void resetGradientStart() {
+ gradientStart = new QColor(0, 0, 255);
+ }
+
+ public QColor getGradientEnd() {
+ return gradientEnd;
+ }
+
+ public void setGradientEnd(QColor gradientEnd) {
+ this.gradientEnd = gradientEnd;
+ }
+
+ public QColor getText() {
+ return text;
+ }
+
+ public void setText(QColor text) {
+ this.text = text;
+ }
+
+ public QColor getBorder() {
+ return border;
+ }
+
+ public void setBorder(QColor border) {
+ this.border = border;
+ }
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/ToString.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/ToString.java
new file mode 100644
index 0000000000..288a2dfe22
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/internal/qt/ToString.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 compeople AG 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:
+ * compeople AG - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal.qt;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+
+/**
+ * Generic .toString() that collects all Java bean properties.
+ */
+public final class ToString {
+
+ private static final String SEPARATOR = ", "; //$NON-NLS-1$
+
+ private ToString() {
+
+ }
+
+ /**
+ * Collect all Java bean properties of the given object and return them as a
+ * printable string.
+ *
+ * @param object
+ * @return toString()
+ */
+ public static String of(Object object) {
+ if (object == null) {
+ return "NULL"; //$NON-NLS-1$
+ }
+ try {
+ return of(object, Introspector.getBeanInfo(object.getClass()));
+ } catch (IntrospectionException e) {
+ return e.toString();
+ }
+ }
+
+ /**
+ * Collect all Java bean properties of the given object but stop
+ * introspection at the given stop class and return them as a printable
+ * string.
+ *
+ * @param object
+ * @param stopClass
+ * if {@code null} stop class will be the super class of the
+ * given object
+ * @return toString()
+ */
+ public static String of(Object object, Class<?> stopClass) {
+ if (object == null) {
+ return "NULL"; //$NON-NLS-1$
+ }
+ if (stopClass == null) {
+ stopClass = object.getClass().getSuperclass();
+ }
+ String result = object.toString() + " - "; //$NON-NLS-1$
+ try {
+ result = result + of(object, Introspector.getBeanInfo(object.getClass(), stopClass));
+ } catch (IntrospectionException e) {
+ result = result + e.toString();
+ }
+ return result;
+ }
+
+ @SuppressWarnings("nls")
+ private static String of(Object object, BeanInfo beanInfo) {
+ StringBuilder bob = new StringBuilder(object.getClass().getSimpleName()).append(" (");
+ PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
+ for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
+ Method readMethod = propertyDescriptor.getReadMethod();
+ try {
+ if (readMethod != null && !propertyDescriptor.getName().equals("class")) {
+ Object value = readMethod.invoke(object, (Object[]) null);
+ if (value != null && value.toString().startsWith(value.getClass().getName() + "@")) {
+ value = "..";
+ }
+ bob.append(propertyDescriptor.getName()).append('=').append(value).append(SEPARATOR);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ if (bob.toString().endsWith(SEPARATOR)) {
+ bob.setLength(bob.length() - SEPARATOR.length());
+ }
+ bob.append(" )");
+ return bob.toString();
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Button.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Button.java
new file mode 100644
index 0000000000..b3319910ac
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Button.java
@@ -0,0 +1,801 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.core.Qt.CheckState;
+import com.trolltech.qt.gui.QAbstractButton;
+import com.trolltech.qt.gui.QApplication;
+import com.trolltech.qt.gui.QCheckBox;
+import com.trolltech.qt.gui.QMouseEvent;
+import com.trolltech.qt.gui.QPushButton;
+import com.trolltech.qt.gui.QRadioButton;
+import com.trolltech.qt.gui.QSizePolicy;
+import com.trolltech.qt.gui.QWidget;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#button">Button
+ * snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public class Button extends Control {
+ private Image image;
+ private Image image2;
+ private Image disabledImage;
+ private static/* final */boolean COMMAND_LINK = false;
+
+ /**
+ * 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));
+ }
+
+ @Override
+ protected void connectSignals() {
+ getQButton().released.connect(this, "clickEvent()"); //$NON-NLS-1$
+ }
+
+ @Override
+ protected QWidget createQWidget(int style) {
+ int marginLeft = 0;
+ int marginTop = 0;
+ int marginRight = 0;
+ int marginBottom = 0;
+ QAbstractButton tb;
+ if ((style & SWT.CHECK) != 0) {
+ tb = new MyQCheckBox();
+ marginTop = 0;
+ marginBottom = 2;
+ } else if ((style & SWT.RADIO) != 0) {
+ tb = new MyQRadioButton();
+ if ((getParent().style & SWT.NO_RADIO_GROUP) != 0) {
+ tb.setAutoExclusive(false);
+ }
+ marginTop = 3;
+ marginBottom = 0;
+ } else {
+ tb = new MyQPushButton();
+ if ((style & SWT.TOGGLE) != 0) {
+ tb.setCheckable(true);
+ }
+ if ((style & SWT.FLAT) != 0) {
+ ((QPushButton) tb).setFlat(true);
+ }
+ // In SWT, push buttons do not inherit color from
+ // their parent, not even with INHERIT_FORCE.
+ tb.setPalette(QApplication.palette());
+ marginTop = 3;
+ }
+ tb.setSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum);
+ tb.setContentsMargins(marginLeft, marginTop, marginRight, marginBottom);
+ return tb;
+ }
+
+ QAbstractButton getQButton() {
+ return (QAbstractButton) getQWidget();
+ }
+
+ /**
+ * Adds the listener to the collection of listeners who will be notified
+ * when the control is selected by the user, 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 by the
+ * user. <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 clickEvent() {
+ sendEvent(SWT.Selection);
+ }
+
+ static int checkStyle(int style) {
+ style = checkBits(style, SWT.PUSH, SWT.ARROW, SWT.CHECK, SWT.RADIO, SWT.TOGGLE, COMMAND_LINK ? SWT.COMMAND : 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 click() {
+ getQButton().click();
+ }
+
+ // public Point computeSize( int wHint, int hHint, boolean changed ) {
+ // checkWidget();
+ // Point size = super.computeSize( wHint, hHint, changed );
+ // size.x += 2;
+ // return size;
+ // }
+
+ /**
+ * 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 <code>true</code> if the receiver is grayed, and false otherwise.
+ * When the widget 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>
+ *
+ * @since 3.4
+ */
+ public boolean getGrayed() {
+ checkWidget();
+ if ((style & SWT.CHECK) == 0) {
+ return false;
+ }
+ QCheckBox box = (QCheckBox) getQButton();
+ if (box.isTristate()) {
+ return CheckState.PartiallyChecked.equals(box.checkState());
+ }
+ return false;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Returns the widget message. When the widget is created with the style
+ * <code>SWT.COMMAND</code>, the message text is displayed to provide
+ * further information for the user.
+ *
+ * @return the widget message
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - 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 */String getMessage() {
+ checkWidget();
+ return getQButton().whatsThis();
+ }
+
+ @Override
+ 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 getQButton().isChecked();
+ }
+
+ /**
+ * 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 ""; //$NON-NLS-1$
+ }
+ return getQButton().text();
+ }
+
+ @Override
+ boolean isTabItem() {
+ if ((style & SWT.PUSH) != 0) {
+ return isTabGroup();
+ }
+ return super.isTabItem();
+ }
+
+ @Override
+ boolean mnemonicHit(char ch) {
+ if (!setFocus()) {
+ return false;
+ }
+ /*
+ * Feature in Windows. When a radio button gets focus, it selects the
+ * button in WM_SETFOCUS. Therefore, it is not necessary to click the
+ * button or send events because this has already happened in
+ * WM_SETFOCUS.
+ */
+ if ((style & SWT.RADIO) == 0) {
+ click();
+ }
+ return true;
+ }
+
+ @Override
+ boolean mnemonicMatch(char key) {
+ char mnemonic = findMnemonic(getText());
+ if (mnemonic == '\0') {
+ return false;
+ }
+ return Character.toUpperCase(key) == Character.toUpperCase(mnemonic);
+ }
+
+ @Override
+ void releaseWidget() {
+ super.releaseWidget();
+ if (disabledImage != null) {
+ disabledImage.dispose();
+ disabledImage = null;
+ }
+ if (image2 != null) {
+ image2.dispose();
+ image2 = null;
+ }
+ image = null;
+ }
+
+ /**
+ * Removes the listener from the collection of listeners who will be
+ * notified when the control is selected by the user.
+ *
+ * @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 selectRadio() {
+ /*
+ * This code is intentionally commented. When two groups of radio
+ * buttons with the same parent are separated by another control, the
+ * correct behavior should be that the two groups act independently.
+ * This is consistent with radio tool and menu items. The commented code
+ * implements this behavior.
+ */
+ // int index = 0;
+ // Control [] children = parent._getChildren ();
+ // while (index < children.length && children [index] != this) index++;
+ // int i = index - 1;
+ // while (i >= 0 && children [i].setRadioSelection (false)) --i;
+ // int j = index + 1;
+ // while (j < children.length && children [j].setRadioSelection (false))
+ // j++;
+ // setSelection (true);
+ Control[] children = parent._getChildren();
+ for (int i = 0; i < children.length; i++) {
+ Control child = children[i];
+ if (this != child) {
+ child.setRadioSelection(false);
+ }
+ }
+ setSelection(true);
+ }
+
+ /**
+ * 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();
+ // TODO how to change it for the qt control
+ 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);
+ 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);
+ }
+
+ void setDefault(boolean value) {
+ if ((style & SWT.PUSH) == 0) {
+ return;
+ }
+ ((QPushButton) getQButton()).setDefault(value);
+ }
+
+ @Override
+ boolean setFixedFocus() {
+ /*
+ * Feature in Windows. When a radio button gets focus, it selects the
+ * button in WM_SETFOCUS. The fix is to not assign focus to an
+ * unselected radio button.
+ */
+ if ((style & SWT.RADIO) != 0 && !getSelection()) {
+ return false;
+ }
+ return super.setFixedFocus();
+ }
+
+ /**
+ * Sets the receiver's image to the argument, which may be <code>null</code>
+ * indicating that no image should be displayed.
+ * <p>
+ * Note that a Button can display an image and text simultaneously on
+ * Windows (starting with XP), GTK+ and OSX. On other platforms, a Button
+ * that has an image and text set into it will display the image or text
+ * that was set most recently.
+ * </p>
+ *
+ * @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;
+
+ getQButton().setIcon(image.getQIcon());
+ getQButton().setIconSize(image.getDefaultIconSize());
+ }
+
+ /**
+ * Sets the grayed state of the receiver. This state change only applies if
+ * the control was created with the SWT.CHECK style.
+ *
+ * @param grayed
+ * the new grayed 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.4
+ */
+ public void setGrayed(boolean grayed) {
+ checkWidget();
+ if ((style & SWT.CHECK) == 0) {
+ return;
+ }
+ QCheckBox box = (QCheckBox) getQButton();
+ box.setTristate(true);
+ box.setCheckState(CheckState.PartiallyChecked);
+ }
+
+ /**
+ * Sets the widget message. When the widget is created with the style
+ * <code>SWT.COMMAND</code>, the message text is displayed to provide
+ * further information for the user.
+ *
+ * @param message
+ * the new message
+ *
+ * @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.3
+ */
+ /* public */void setMessage(String message) {
+ checkWidget();
+ if (message == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ getQButton().setWhatsThis(message);
+ }
+
+ @Override
+ boolean setRadioFocus(boolean tabbing) {
+ if ((style & SWT.RADIO) == 0 || !getSelection()) {
+ return false;
+ }
+ return tabbing ? setTabItemFocus() : setFocus();
+ }
+
+ @Override
+ boolean setRadioSelection(boolean value) {
+ if ((style & SWT.RADIO) == 0) {
+ return false;
+ }
+ if (getSelection() != value) {
+ setSelection(value);
+ postEvent(SWT.Selection);
+ }
+ return true;
+ }
+
+ @Override
+ boolean setSavedFocus() {
+ /*
+ * Feature in Windows. When a radio button gets focus, it selects the
+ * button in WM_SETFOCUS. If the previous saved focus widget was a radio
+ * button, allowing the shell to automatically restore the focus to the
+ * previous radio button will unexpectedly check that button. The fix is
+ * to not assign focus to an unselected radio button.
+ */
+ if ((style & SWT.RADIO) != 0 && !getSelection()) {
+ return false;
+ }
+ return super.setSavedFocus();
+ }
+
+ /**
+ * 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;
+ }
+ getQButton().setChecked(selected);
+ }
+
+ /**
+ * 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 emphasized 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>
+ * Note that a Button can display an image and text simultaneously on
+ * Windows (starting with XP), GTK+ and OSX. On other platforms, a Button
+ * that has an image and text set into it will display the image or text
+ * that was set most recently.
+ * </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;
+ }
+ getQButton().setText(string);
+ }
+
+ private final class MyQCheckBox extends QCheckBox {
+
+ @Override
+ protected void mousePressEvent(QMouseEvent e) {
+ super.mousePressEvent(e);
+ e.setAccepted(false);
+ }
+
+ }
+
+ private final class MyQRadioButton extends QRadioButton {
+
+ @Override
+ protected void mousePressEvent(QMouseEvent e) {
+ super.mousePressEvent(e);
+ e.setAccepted(false);
+ }
+
+ }
+
+ private final class MyQPushButton extends QPushButton {
+
+ @Override
+ protected void mousePressEvent(QMouseEvent e) {
+ super.mousePressEvent(e);
+ e.setAccepted(false);
+ }
+
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Canvas.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Canvas.java
new file mode 100644
index 0000000000..4ae2a9a9ed
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Canvas.java
@@ -0,0 +1,355 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.core.QObject;
+import com.trolltech.qt.gui.QPaintEvent;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Rectangle;
+
+/**
+ * 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
+ * @see <a href="http://www.eclipse.org/swt/snippets/#canvas">Canvas
+ * snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ */
+
+public class Canvas extends Composite {
+ Caret caret;
+ IME ime;
+
+ /**
+ * 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);
+ }
+
+ /**
+ * 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);
+ }
+ Color gcBG = gc.getBackground();
+ gc.setBackground(getBackground());
+ gc.fillRectangle(x, y, width, height);
+ gc.setBackground(gcBG);
+ }
+
+ /**
+ * 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 for the receiver, may be 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 Caret getCaret() {
+ checkWidget();
+ return caret;
+ }
+
+ /**
+ * Returns the IME.
+ *
+ * @return the IME
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - 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.4
+ */
+ public IME getIME() {
+ checkWidget();
+ return ime;
+ }
+
+ @Override
+ void releaseChildren(boolean destroy) {
+ if (caret != null) {
+ caret.release(false);
+ caret = null;
+ }
+ if (ime != null) {
+ ime.release(false);
+ ime = null;
+ }
+ super.releaseChildren(destroy);
+ }
+
+ /**
+ * 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();
+ if (width <= 0 || height <= 0) {
+ return;
+ }
+ int deltaX = destX - x, deltaY = destY - y;
+ if (deltaX == 0 && deltaY == 0) {
+ return;
+ }
+ if (!isVisible()) {
+ return;
+ }
+
+ //getQWidget().scroll(deltaX, deltaY, new QRect(x, y, width, height));
+
+ if (all) {
+ Control[] children = _getChildren();
+ for (int i = 0; i < children.length; i++) {
+ Control child = children[i];
+ Rectangle rect = child.getBounds();
+ if (Math.min(x + width, rect.x + rect.width) >= Math.max(x, rect.x)
+ && Math.min(y + height, rect.y + rect.height) >= Math.max(y, rect.y)) {
+ child.setLocation(rect.x + deltaX, rect.y + deltaY);
+ }
+ }
+ }
+ getQMasterWidget().update();
+ }
+
+ /**
+ * 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();
+ Caret newCaret = caret;
+ Caret oldCaret = this.caret;
+ this.caret = newCaret;
+ if (hasFocus()) {
+ if (oldCaret != null) {
+ oldCaret.killFocus();
+ }
+ if (newCaret != null) {
+ if (newCaret.isDisposed()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ newCaret.setFocus();
+ }
+ }
+ }
+
+ @Override
+ public void setFont(Font font) {
+ checkWidget();
+ if (caret != null) {
+ caret.setFont(font);
+ }
+ super.setFont(font);
+ }
+
+ /**
+ * Sets the receiver's IME.
+ *
+ * @param ime
+ * the new IME for the receiver, may be null
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the IME 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.4
+ */
+ public void setIME(IME ime) {
+ checkWidget();
+ if (ime != null && ime.isDisposed()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ this.ime = ime;
+ }
+
+ @Override
+ public boolean qtPaintEvent(QObject source, QPaintEvent paintEvent) {
+ boolean ret = super.qtPaintEvent(source, paintEvent);
+ if (source == getQWidget()) {
+ if (caret != null) {
+ isOngoingPaintEvent = true;
+ try {
+ caret.draw();
+ } finally {
+ isOngoingPaintEvent = false;
+ }
+ }
+ }
+ return ret;
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Caret.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Caret.java
new file mode 100644
index 0000000000..6e7d0c24f6
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Caret.java
@@ -0,0 +1,590 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.GCData;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#caret">Caret snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample, Canvas tab</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public class Caret extends Widget {
+ private static final int DEFAULT_WIDTH = 1;
+ private Canvas parent;
+ private int x, y;
+ private int width = DEFAULT_WIDTH;
+ private int height;
+ private boolean isVisible;
+ private Image image;
+ private Font font;
+ private Color carentBG;
+
+ /**
+ * 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() {
+ isVisible = true;
+ carentBG = new Color(display, 0, 0, 0);
+ if (parent.getCaret() == null) {
+ parent.setCaret(this);
+ }
+ }
+
+ /**
+ * 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 font;
+ }
+ return parent.getFont();
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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 isVisible && parent.isVisible() && parent.hasFocus();
+ }
+
+ /**
+ * 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;
+ }
+
+ @Override
+ void releaseParent() {
+ super.releaseParent();
+ if (this == parent.getCaret()) {
+ parent.setCaret(null);
+ }
+ }
+
+ @Override
+ void releaseWidget() {
+ parent = null;
+ image = null;
+ font = null;
+ carentBG.dispose();
+ carentBG = null;
+ }
+
+ /**
+ * 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();
+ //System.out.println("Caret.setBounds(" + x + ", " + y + ", " + width + ", " + height + ")");
+ boolean moved = this.x != x || this.y != y;
+ boolean resized = this.width != width || this.height != height;
+ if (!(moved || resized)) {
+ return;
+ }
+
+ // invalidate old location
+ parent.getQWidget().update(this.x, this.y, this.width, this.height);
+
+ this.x = x;
+ this.y = y;
+ this.width = Math.max(width, DEFAULT_WIDTH);
+ this.height = height;
+
+ // invalidate new location
+ parent.getQWidget().update(this.x, this.y, this.width, this.height);
+ }
+
+ /**
+ * 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 killFocus() {
+ //focus = false;
+ }
+
+ void setFocus() {
+ //focus = true;
+ }
+
+ /**
+ * 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;
+ // resize();
+ }
+
+ /**
+ * 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;
+ }
+ setBounds(x, y, width, height);
+ }
+
+ /**
+ * 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;
+ }
+ setBounds(x, y, 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);
+ }
+
+ void draw() {
+ if (!isVisible || parent == null || parent.isDisposed()) {
+ return;
+ }
+ //System.out.println("caret paint: " + this + " @ " + getLocation());
+ GCData data = new GCData();
+ data.device = display;
+ GC gc = GC.qt_new(parent, parent.getQWidget(), data);
+ // GdkColor color = new GdkColor ();
+ // color.red = (short) 0xffff;
+ // color.green = (short) 0xffff;
+ // color.blue = (short) 0xffff;
+ // int /*long*/ colormap = OS.gdk_colormap_get_system ();
+ // OS.gdk_colormap_alloc_color (colormap, color, true, true);
+ // OS.gdk_gc_set_foreground (gc, color);
+ // OS.gdk_gc_set_function (gc, OS.GDK_XOR);
+ // if (image != null && !image.isDisposed() && image.mask == 0) {
+ // int[] width = new int[1];
+ // int[] height = new int[1];
+ // OS.gdk_drawable_get_size(image.pixmap, width, height);
+ // int nX = x;
+ // if ((parent.style & SWT.MIRRORED) != 0) {
+ // nX = parent.getClientWidth() - width[0] - nX;
+ // }
+ // OS.gdk_draw_drawable(window, gc, image.pixmap, 0, 0, nX, y, width[0], height[0]);
+ // } else {
+ int nWidth = width, nHeight = height;
+ if (nWidth <= 0) {
+ nWidth = DEFAULT_WIDTH;
+ }
+ int nX = x;
+ if ((parent.style & SWT.MIRRORED) != 0) {
+ nX = parent.getClientWidth() - nWidth - nX;
+ }
+ data.backgroundColor = carentBG;
+ gc.fillRectangle(nX, y, nWidth, nHeight);
+ gc.dispose();
+ //}
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ColorDialog.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ColorDialog.java
new file mode 100644
index 0000000000..bb98ecabfe
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ColorDialog.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.gui.QColor;
+import com.trolltech.qt.gui.QColorDialog;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.graphics.PaletteData;
+import org.eclipse.swt.graphics.RGB;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample, Dialog tab</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public class ColorDialog extends Dialog {
+ Display display;
+ int width, height;
+ RGB initialRGB;
+ QColorDialog cd;
+
+ /**
+ * 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.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.
+ * </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, checkStyle(parent, style));
+ checkSubclass();
+ cd = new QColorDialog();
+
+ }
+
+ /**
+ * 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() {
+ QColor color = cd.currentColor();
+ RGB rgb = new RGB(color.red(), color.green(), color.blue());
+ 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() {
+ cd.exec();
+ QColor color = cd.selectedColor();
+ cd.disposeLater();
+ return new RGB(color.red(), color.green(), color.blue());
+ }
+
+ /**
+ * 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) {
+ cd.setCurrentColor(new QColor(rgb.red, rgb.green, rgb.blue));
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Combo.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Combo.java
new file mode 100644
index 0000000000..bb0ab32767
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Combo.java
@@ -0,0 +1,1398 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import java.util.Arrays;
+
+import com.trolltech.qt.core.QObject;
+import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.core.Qt.LayoutDirection;
+import com.trolltech.qt.gui.QComboBox;
+import com.trolltech.qt.gui.QFrame;
+import com.trolltech.qt.gui.QLineEdit;
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.qt.gui.QComboBox.InsertPolicy;
+import com.trolltech.qt.gui.QComboBox.SizeAdjustPolicy;
+
+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;
+
+/**
+ * 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
+ * @see <a href="http://www.eclipse.org/swt/snippets/#combo">Combo snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public class Combo extends Composite {
+ /**
+ * 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 = new QLineEdit().maxLength();
+ }
+
+ /**
+ * 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));
+ }
+
+ @Override
+ protected QComboBox createQWidget(int style) {
+ QComboBox combo = new QComboBox();
+ combo.setEditable(true);
+ combo.setSizeAdjustPolicy(SizeAdjustPolicy.AdjustToMinimumContentsLength);
+ // Disable the ability to add edited text at the end
+ combo.setInsertPolicy(InsertPolicy.NoInsert);
+ if ((style & SWT.READ_ONLY) != 0) {
+ combo.lineEdit().setReadOnly(true);
+ }
+ return combo;
+ }
+
+ private QComboBox getQComboBox() {
+ return (QComboBox) getQWidget();
+ }
+
+ @Override
+ protected void connectSignals() {
+ getQComboBox().activatedIndex.connect(this, "qtActivatedIndexEvent(int)"); //$NON-NLS-1$
+ getQComboBox().lineEdit().returnPressed.connect(this, "qtReturnPressedEvent()"); //$NON-NLS-1$
+ getQComboBox().editTextChanged.connect(this, "qtEditTextChangedEvent(String)"); //$NON-NLS-1$
+ }
+
+ protected void qtActivatedIndexEvent(int index) {
+ setSelection(new Point(0, getQComboBox().lineEdit().text().length()));
+ sendEvent(SWT.Selection);
+ }
+
+ protected void qtReturnPressedEvent() {
+ sendEvent(SWT.DefaultSelection);
+ }
+
+ protected void qtEditTextChangedEvent(String text) {
+ sendEvent(SWT.Modify);
+ }
+
+ /**
+ * 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);
+ }
+ getQComboBox().addItem(string);
+ }
+
+ /**
+ * 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);
+ }
+ getQComboBox().insertItem(index, string);
+ }
+
+ /**
+ * 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 user changes the receiver's selection, by sending it one of the
+ * messages defined in the <code>SelectionListener</code> interface.
+ * <p>
+ * <code>widgetSelected</code> is called when the user changes the combo's
+ * list selection. <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);
+ }
+
+ @Override
+ 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();
+ getQComboBox().lineEdit().setCursorPosition(0);
+ }
+
+ @Override
+ public Point computeSize(int wHint, int hHint, boolean changed) {
+ checkWidget();
+ if (changed) {
+ getQWidget().updateGeometry();
+ }
+
+ // to get the maximum row length depending on the content,
+ // set size policy to QComboBox::AdjustToContents. but it has drawback
+ // that
+ // it doesn't allow resizing so we have to set back size policy after
+ // compute size
+ getQComboBox().setSizeAdjustPolicy(SizeAdjustPolicy.AdjustToContents);
+ QSize size = getQWidget().sizeHint();
+ Point sizeHint = new Point(size.width(), size.height());
+
+ int width = DEFAULT_WIDTH;
+ int height = DEFAULT_HEIGHT;
+ if (sizeHint.x >= 0) {
+ width = sizeHint.x;
+ }
+ if (sizeHint.y >= 0) {
+ height = sizeHint.y;
+ }
+ if (wHint != SWT.DEFAULT) {
+ width = wHint;
+ }
+ if (hHint != SWT.DEFAULT && hHint < sizeHint.y) {
+ height = hHint;
+ }
+
+ // sets the size policy back to default so that resizing will be allowed
+ getQComboBox().setSizeAdjustPolicy(SizeAdjustPolicy.AdjustToMinimumContentsLength);
+ 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();
+ getQComboBox().lineEdit().copy();
+ }
+
+ /**
+ * 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();
+ getQComboBox().lineEdit().cut();
+ }
+
+ /**
+ * 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();
+ if (getSelectionIndex() == index) {
+ deselectAll();
+ }
+ }
+
+ /**
+ * 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();
+ getQComboBox().setCurrentIndex(-1);
+ sendEvent(SWT.Modify);
+ }
+
+ /**
+ * 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();
+ return getQComboBox().itemText(index);
+ }
+
+ /**
+ * 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();
+ return getQComboBox().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();
+ return getQComboBox().view().sizeHintForRow(0);
+ }
+
+ /**
+ * 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.4
+ */
+ public boolean getListVisible() {
+ checkWidget();
+ java.util.List<QObject> children = getQComboBox().children();
+ for (QObject child : children) {
+ if (child.isWidgetType() && child instanceof QFrame) {
+ return ((QWidget) child).isVisible();
+ }
+ }
+ return false;
+ }
+
+ @Override
+ String getNameText() {
+ return getText();
+ }
+
+ /**
+ * 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.4
+ */
+ public void setListVisible(boolean visible) {
+ checkWidget();
+ if (visible) {
+ getQComboBox().showPopup();
+ } else {
+ getQComboBox().hidePopup();
+ }
+ }
+
+ /**
+ * 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();
+ int start = getQComboBox().lineEdit().selectionStart();
+ int end = getQComboBox().lineEdit().cursorPosition();
+ return new Point(start == -1 ? end : start, end);
+ }
+
+ /**
+ * 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 getQComboBox().currentIndex();
+ }
+
+ /**
+ * 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();
+ return getQComboBox().currentText();
+ }
+
+ /**
+ * 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();
+ return getQComboBox().lineEdit().sizeHint().height();
+ }
+
+ /**
+ * 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();
+ return getQComboBox().lineEdit().maxLength();
+ }
+
+ /**
+ * 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();
+ return getQComboBox().maxVisibleItems();
+ }
+
+ /**
+ * 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 index = getQComboBox().findText(string);
+ if (!(0 <= start && start <= index)) {
+ return -1;
+ }
+ 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();
+ getQComboBox().lineEdit().paste();
+ }
+
+ /**
+ * 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();
+ int count = getItemCount();
+ if (!(index < count && index >= 0)) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+ getQComboBox().removeItem(index);
+ }
+
+ /**
+ * 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 < count && start >= 0 && end < count)) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+ if (start > end) {
+ return;
+ }
+ for (int i = end; i >= start; --i) {
+ getQComboBox().removeItem(i);
+ }
+ }
+
+ /**
+ * 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();
+ getQComboBox().clear();
+ }
+
+ /**
+ * 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 user changes the receiver's selection.
+ *
+ * @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 count = getItemCount();
+ if (index < 0 || index >= count) {
+ return;
+ }
+ getQComboBox().setCurrentIndex(index);
+ }
+
+ /**
+ * Sets the text of the item in the receiver's list at the given
+ * zero-relative index to the string argument.
+ *
+ * @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 selection = getSelectionIndex();
+ remove(index);
+ if (isDisposed()) {
+ return;
+ }
+ add(string, index);
+ if (selection != -1) {
+ select(selection);
+ }
+ }
+
+ /**
+ * 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);
+ }
+ }
+ getQComboBox().addItems(Arrays.asList(items));
+ }
+
+ /**
+ * 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();
+ int flags = SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT;
+ if ((orientation & flags) == 0 || (orientation & flags) == flags) {
+ return;
+ }
+
+ style &= ~flags;
+ style |= orientation & flags;
+
+ getQWidget().setLayoutDirection(
+ orientation == SWT.LEFT_TO_RIGHT ? LayoutDirection.LeftToRight : LayoutDirection.RightToLeft);
+ }
+
+ /**
+ * 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 (selection == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ int start = selection.x, end = selection.y;
+ getQComboBox().lineEdit().setSelection(start, (end - 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;
+ }
+ getQComboBox().setEditText(string);
+ sendEvent(SWT.Modify);
+ }
+
+ /**
+ * 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);
+ }
+ if (limit > LIMIT) {
+ limit = LIMIT;
+ }
+ getQComboBox().lineEdit().setMaxLength(limit);
+ }
+
+ /**
+ * 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;
+ }
+ getQComboBox().setMaxVisibleItems(count);
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Composite.java
new file mode 100644
index 0000000000..374d7c9f88
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Composite.java
@@ -0,0 +1,1301 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+import com.trolltech.qt.core.QObject;
+import com.trolltech.qt.core.QPoint;
+import com.trolltech.qt.core.Qt.FocusReason;
+import com.trolltech.qt.gui.QLabel;
+import com.trolltech.qt.gui.QMouseEvent;
+import com.trolltech.qt.gui.QResizeEvent;
+import com.trolltech.qt.gui.QScrollArea;
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.qt.gui.QPalette.ColorRole;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+
+/**
+ * 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.
+ * </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
+ * @see <a href="http://www.eclipse.org/swt/snippets/#composite">Composite
+ * snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ */
+public class Composite extends Scrollable {
+ private Layout layout;
+ private Control[] tabList;
+ protected int layoutCount;
+ private int backgroundMode = SWT.INHERIT_NONE;
+
+ /**
+ * 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);
+ }
+
+ @Override
+ QWidget createQWidget(int style) {
+ QWidget widget = super.createQWidget(style);
+ state |= CANVAS;
+ if ((style & (SWT.H_SCROLL | SWT.V_SCROLL)) == 0) {
+ state |= THEME_BACKGROUND;
+ }
+ if ((style & SWT.TRANSPARENT) != 0) {
+ System.out.println("TODO: handle SWT.TRANSPARENT"); //$NON-NLS-1$
+ }
+ return widget;
+ }
+
+ protected void updateAutoFillBackground() {
+ // if ((style & SWT.NO_BACKGROUND) == 0) {
+ // getQMasterWidget().setAutoFillBackground(true);
+ // } else {
+ // getQMasterWidget().setAutoFillBackground(false);
+ // System.out.println(this + " no bg");
+ // }
+ }
+
+ protected boolean noBackground() {
+ return (style & SWT.NO_BACKGROUND) == 1;
+ }
+
+ @Override
+ protected void updateBackground() {
+ if ((state & PARENT_BACKGROUND) == 0) {
+ updateAutoFillBackground();
+ applyBackgroundColor(getDefaultBackgroundColor());
+ } else {
+ super.updateBackground();
+ }
+ }
+
+ @Override
+ protected ColorRole[] getBackgroundColorRoles() {
+ if (backgroundMode == SWT.INHERIT_FORCE) {
+ return super.getBackgroundColorRoles();
+ } else {
+ return new ColorRole[] { ColorRole.Window };
+ }
+ }
+
+ void addQChild(Control control) {
+ control.getQMasterWidget().setParent(getQWidget());
+ }
+
+ 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;
+ }
+
+ /**
+ * 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;
+ }
+ }
+ }
+
+ @Override
+ protected void checkSubclass() {
+ /* Do nothing - Subclassing is allowed */
+ }
+
+ @Override
+ 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;
+ }
+
+ @Override
+ public Point computeSize(int wHint, int hHint, boolean changed) {
+ checkWidget();
+ Point size;
+ if ((state & CANVAS) != 0) {
+ 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 && wHint > 0) {
+ size.x = wHint;
+ }
+ if (hHint != SWT.DEFAULT && hHint > 0) {
+ size.y = hHint;
+ }
+ Rectangle trim = computeTrim(0, 0, size.x, size.y);
+ return new Point(trim.width, trim.height);
+ }
+ return super.computeSize(wHint, hHint, changed);
+
+ }
+
+ @Override
+ boolean isMirrored() {
+ return (style & SWT.MIRRORED) != 0;
+ }
+
+ /**
+ * Copies a rectangular area of the receiver at the specified position using
+ * the gc.
+ *
+ * @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>
+ */
+ /* public */void copyArea(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);
+ }
+ throw new UnsupportedOperationException("not yet implemented"); //$NON-NLS-1$
+ }
+
+ protected Composite findDeferredControl() {
+ return layoutCount > 0 ? this : parent.findDeferredControl();
+ }
+
+ @Override
+ 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;
+ }
+
+ @Override
+ void fixChildren(Shell newShell, Shell oldShell, Decorations newDecorations, Decorations oldDecorations,
+ Menu[] menus) {
+ super.fixChildren(newShell, oldShell, newDecorations, oldDecorations, menus);
+ Control[] children = _getChildren();
+ for (int i = 0; i < children.length; i++) {
+ children[i].fixChildren(newShell, oldShell, newDecorations, oldDecorations, menus);
+ }
+ }
+
+ 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();
+ }
+
+ Control[] _getChildren() {
+ Collection<QObject> qtChildren = getQWidget().children();
+ int count = qtChildren.size();
+ if (count == 0) {
+ return new Control[0];
+ }
+ LinkedList<Control> children = new LinkedList<Control>();
+ for (QObject qObj : qtChildren) {
+ Widget widget = display.findControl(qObj);
+ if (widget != null && widget != this) {
+ if (widget instanceof Control && !(widget instanceof Shell)) {
+ children.addFirst((Control) widget);
+ }
+ }
+ }
+ return children.toArray(new Control[children.size()]);
+ }
+
+ int getChildrenCount() {
+ return getQWidget().children().size();
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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>
+ * <p>
+ * Note: Layout is different from painting. If a child is moved or resized
+ * such that an area in the parent is exposed, then the parent will paint.
+ * If no child is affected, the parent will not paint.
+ * </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);
+ }
+
+ @Override
+ protected void updateLayout() {
+ layout(true, 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>
+ * <p>
+ * Note: Layout is different from painting. If a child is moved or resized
+ * such that an area in the parent is exposed, then the parent will paint.
+ * If no child is affected, the parent will not paint.
+ * </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>
+ * <p>
+ * Note: Layout is different from painting. If a child is moved or resized
+ * such that an area in the parent is exposed, then the parent will paint.
+ * If no child is affected, the parent will not paint.
+ * </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(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.
+ * <p>
+ * Note: Layout is different from painting. If a child is moved or resized
+ * such that an area in the parent is exposed, then the parent will paint.
+ * If no child is affected, the parent will not paint.
+ * </p>
+ *
+ * @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(false);
+ }
+ }
+
+ @Override
+ 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);
+ }
+
+ @Override
+ void redrawChildren() {
+ Control[] children = _getChildren();
+ for (int i = 0; i < children.length; i++) {
+ children[i]._redraw();
+ }
+ }
+
+ @Override
+ 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);
+ }
+
+ @Override
+ void releaseWidget() {
+ super.releaseWidget();
+ layout = null;
+ tabList = null;
+ }
+
+ void removeControl(Control control) {
+ control.getQMasterWidget().setParent(null);
+ fixTabList(control);
+ resizeChildren();
+ }
+
+ private void resizeChildren() {
+ if (getQWidget() == null) {
+ return;
+ }
+ for (QObject child : getQWidget().children()) {
+ if (child.isWidgetType()) {
+ ((QWidget) child).updateGeometry();
+ }
+ }
+ }
+
+ /**
+ * 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();
+ if (backgroundMode == mode) {
+ return;
+ }
+ backgroundMode = mode;
+ Control[] children = _getChildren();
+ for (int i = 0; i < children.length; i++) {
+ children[i].updateBackgroundMode();
+ }
+ }
+
+ @Override
+ protected void setBounds(int x, int y, int width, int height, boolean move, boolean resize) {
+ if ((state & CANVAS) != 0) {
+ state &= ~(RESIZE_OCCURRED | MOVE_OCCURRED);
+ state |= RESIZE_DEFERRED | MOVE_DEFERRED;
+ }
+ super.setBounds(x, y, width, height, move, resize);
+ if ((state & CANVAS) != 0) {
+ boolean wasResized = (state & RESIZE_OCCURRED) != 0;
+ state &= ~(RESIZE_DEFERRED | MOVE_DEFERRED);
+ if (wasResized && layout != null) {
+ markLayout(false, false);
+ updateLayout(false);
+ }
+ }
+ }
+
+ @Override
+ public boolean setFocus() {
+ checkWidget();
+ return setFocus(FocusReason.OtherFocusReason);
+ // Control[] children = _getChildren();
+ // for (int i = 0; i < children.length; i++) {
+ // Control child = children[i];
+ // if (child.setRadioFocus(false))
+ // return true;
+ // }
+ // for (int i = 0; i < children.length; i++) {
+ // Control child = children[i];
+ // if (child.setFocus())
+ // return true;
+ // }
+ // return super.setFocus();
+ }
+
+ @Override
+ protected boolean setFocus(FocusReason focusReason) {
+ Control[] children = _getChildren();
+ for (int i = 0; i < children.length; i++) {
+ Control child = children[i];
+ if (child.getVisible() && child.setFocus(focusReason)) {
+ return true;
+ }
+ }
+ return super.setFocus(focusReason);
+ }
+
+ /**
+ * 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);
+ }
+ }
+ } 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;
+ }
+
+ @Override
+ 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(true)) {
+ return true;
+ }
+ }
+ for (int i = 0; i < children.length; i++) {
+ Control child = children[i];
+ if (child.isTabItem() && !child.isTabGroup() && child.setTabItemFocus()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ 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;
+ }
+
+ @Override
+ void updateBackgroundColor() {
+ // if (noBackground()) {
+ // return;
+ // }
+ super.updateBackgroundColor();
+ for (Control child : _getChildren()) {
+ if ((child.state & PARENT_BACKGROUND) != 0) {
+ child.updateBackgroundColor();
+ }
+ }
+ }
+
+ @Override
+ void updateBackgroundImage() {
+ // if (noBackground()) {
+ // return;
+ // }
+ super.updateBackgroundImage();
+ for (Control child : _getChildren()) {
+ if ((child.state & PARENT_BACKGROUND) != 0) {
+ child.updateBackgroundImage();
+ }
+ }
+ }
+
+ @Override
+ void updateBackgroundMode() {
+ super.updateBackgroundMode();
+ for (Control child : _getChildren()) {
+ child.updateBackgroundMode();
+ }
+ }
+
+ @Override
+ 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);
+ }
+ }
+ }
+
+ @Override
+ void updateLayout(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);
+ if (layout != null) {
+ layout.layout(this, changed);
+ }
+ resizeChildren();
+ }
+ if (all) {
+ state &= ~LAYOUT_CHILD;
+ Control[] children = _getChildren();
+ for (int i = 0; i < children.length; i++) {
+ children[i].updateLayout(all);
+ }
+ }
+ }
+
+ @Override
+ protected void _setVisible(QWidget widget, boolean visible) {
+ findChildren();
+ boolean oldVisibility = getQMasterWidget().isVisible();
+ super._setVisible(widget, visible);
+ if (getQMasterWidget().isVisible() != oldVisibility && layout != null) {
+ markLayout(true, true);
+ updateLayout(true);
+ }
+ }
+
+ // TODO sma@2010-02-08 Links contain HTML escape sequences and therefore "&".
+ // Removing it breaks the HTML. Can Links have mnemonics?
+ private void findChildren() {
+ for (Control child : getChildren()) {
+ if (!(child instanceof Link) && child.getQWidget() instanceof QLabel
+ && ((QLabel) child.getQWidget()).text().contains("&")) { //$NON-NLS-1$
+ handleMnemonic(child.getQWidget());
+ } else if (child instanceof Composite) {
+ ((Composite) child).findChildren();
+ }
+ }
+ }
+
+ private void handleMnemonic(QWidget qwidget) {
+ QLabel myLabel = (QLabel) qwidget;
+ boolean foundBuddy = false;
+ java.util.List<QObject> children = myLabel.parent().children();
+ for (int i = 0; i < children.size() - 1; i++) {
+ if (children.get(i).equals(myLabel)) {
+ // search for a suitable buddy
+ for (int k = i + 1; k < children.size(); k++) {
+ QObject neighbour = children.get(k);
+ if (neighbour != null && !(neighbour instanceof QLabel) && !(neighbour instanceof QScrollArea)) {
+ myLabel.setBuddy((QWidget) neighbour);
+ foundBuddy = true;
+ break;
+ }
+ }
+ }
+
+ }
+ /*
+ * If there is no buddy to get the mnemonic, the "&" is removed from the
+ * string. In SWT/Win32 the character will remain underlined without any
+ * function, but in SWT/Qt this is not possible.
+ */
+ if (!foundBuddy) {
+ myLabel.setText(myLabel.text().replace("&", "")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ @Override
+ public boolean qtResizeEvent(QObject source, QResizeEvent resizeEvent) {
+ if (isDisposed()) {
+ return true;
+ }
+ if (isMirrored()) {
+ int newWidth = resizeEvent.size().width();
+ int oldWidth = resizeEvent.oldSize().width();
+ final int dx = newWidth - oldWidth;
+ if (dx != 0) {
+ Control[] children = _getChildren();
+ for (int i = 0; i < children.length; ++i) {
+ Control child = children[i];
+ if (!child.isDisposed()) {
+ QWidget qtControl = child.getQMasterWidget();
+ QPoint pos = qtControl.pos();
+ qtControl.move(pos.x() + dx, pos.y());
+ }
+ }
+ }
+ }
+ super.qtResizeEvent(source, resizeEvent);
+ if (layout != null) {
+ markLayout(false, false);
+ updateLayout(false);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean qtMouseButtonPressEvent(QObject source, QMouseEvent mouseEvent) {
+ if (source == getQWidget()) {
+ boolean ret = super.qtMouseButtonPressEvent(source, mouseEvent);
+ if ((this.state & CANVAS) != 0) {
+ if ((style & SWT.NO_FOCUS) == 0 && hooksKeys()) {
+ Control[] children = getChildren();
+ if (children == null || children.length == 0) {
+ setFocus(FocusReason.OtherFocusReason);
+ }
+ }
+ }
+ return ret;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean qtMouseEnterEvent(Object source) {
+ if (source == getQMasterWidget()) {
+ sendEvent(SWT.MouseEnter);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean qtMouseLeaveEvent(Object source) {
+ if (source == getQMasterWidget()) {
+ sendEvent(SWT.MouseExit);
+ }
+ return false;
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Control.java
new file mode 100644
index 0000000000..ffff864e5b
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Control.java
@@ -0,0 +1,4225 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import java.util.List;
+
+import com.trolltech.qt.core.QCoreApplication;
+import com.trolltech.qt.core.QObject;
+import com.trolltech.qt.core.QPoint;
+import com.trolltech.qt.core.QRect;
+import com.trolltech.qt.core.QEventLoop.ProcessEventsFlag;
+import com.trolltech.qt.core.Qt.FocusPolicy;
+import com.trolltech.qt.core.Qt.FocusReason;
+import com.trolltech.qt.core.Qt.Key;
+import com.trolltech.qt.core.Qt.LayoutDirection;
+import com.trolltech.qt.core.Qt.MouseButton;
+import com.trolltech.qt.core.Qt.MouseButtons;
+import com.trolltech.qt.gui.QAbstractScrollArea;
+import com.trolltech.qt.gui.QAction;
+import com.trolltech.qt.gui.QApplication;
+import com.trolltech.qt.gui.QBrush;
+import com.trolltech.qt.gui.QColor;
+import com.trolltech.qt.gui.QContextMenuEvent;
+import com.trolltech.qt.gui.QDesktopWidget;
+import com.trolltech.qt.gui.QDragEnterEvent;
+import com.trolltech.qt.gui.QDragLeaveEvent;
+import com.trolltech.qt.gui.QDragMoveEvent;
+import com.trolltech.qt.gui.QDropEvent;
+import com.trolltech.qt.gui.QFrame;
+import com.trolltech.qt.gui.QKeyEvent;
+import com.trolltech.qt.gui.QMenu;
+import com.trolltech.qt.gui.QMouseEvent;
+import com.trolltech.qt.gui.QMoveEvent;
+import com.trolltech.qt.gui.QPaintDeviceInterface;
+import com.trolltech.qt.gui.QPaintEvent;
+import com.trolltech.qt.gui.QPainter;
+import com.trolltech.qt.gui.QPalette;
+import com.trolltech.qt.gui.QPicture;
+import com.trolltech.qt.gui.QResizeEvent;
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.qt.gui.QFrame.Shadow;
+import com.trolltech.qt.gui.QFrame.Shape;
+import com.trolltech.qt.gui.QPalette.ColorRole;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.accessibility.Accessible;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.DragDetectListener;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.HelpListener;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MenuDetectListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.MouseTrackListener;
+import org.eclipse.swt.events.MouseWheelListener;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.events.TraverseListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.Drawable;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.GCData;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.graphics.Region;
+import org.eclipse.swt.internal.qt.DragNDropListener;
+import org.eclipse.swt.internal.qt.KeyUtil;
+import org.eclipse.swt.internal.qt.QtSWTConverter;
+
+/**
+ * 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>DragDetect, FocusIn, FocusOut, Help, KeyDown, KeyUp, MenuDetect,
+ * MouseDoubleClick, MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp,
+ * MouseMove, Move, Paint, Resize, Traverse</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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#control">Control
+ * snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public abstract class Control extends Widget implements Drawable {
+ /**
+ * 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 /* long */handle;
+ Composite parent;
+ protected Cursor cursor;
+ private Menu menu;
+ private Object layoutData;
+ private Accessible accessible;
+ protected Region region;
+ private Font font;
+ protected Color foreground;
+ protected Color background;
+ protected Image backgroundImage;
+ private QPicture temporaryGC;
+ protected boolean isOngoingPaintEvent = false;
+ private boolean enabled = true;
+ private QPoint dragStartPos;
+ private DragNDropListener dndListener;
+
+ /**
+ * 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(parent, style);
+ }
+
+ protected void createWidget(Composite parent, int style) {
+ state |= DRAG_DETECT;
+ checkAndUpdateOrientation(parent);
+ QWidget qWidget = createQWidget(style);
+ if (qWidget == null) {
+ error(SWT.ERROR_UNSPECIFIED);
+ }
+ setQWidget(qWidget);
+ setParent();
+ fixZOrder();
+ checkAndUpdateBackground();
+ connectSignals();
+ registerQWidget();
+ setupQWidget();
+ updateLayoutDirection();
+ setupStyleSheet();
+ checkAndUpdateMirrored();
+ checkAndUpdateBorder();
+ updateFocusPolicy();
+ updateBackground();
+ updateSizeAndVisibility();
+ }
+
+ abstract QWidget createQWidget(int style);
+
+ protected void setParent() {
+ if (parent != null) {
+ parent.addQChild(this);
+ }
+ }
+
+ protected void fixZOrder() {
+ if (parent != null && !(parent instanceof TabFolder)) {
+ getQMasterWidget().lower();
+ }
+ }
+
+ /**
+ * Hook that guarantees that getQWidget() != null. Called immediately after
+ * {@link createQtControl()}.
+ */
+ protected void setupQWidget() {
+ //nothing
+ }
+
+ protected void updateSizeAndVisibility() {
+ if (parent != null && parent.getQWidget().isVisible() && !(parent instanceof Shell) && !(this instanceof Shell)) {
+ getQMasterWidget().setVisible(true);
+ }
+ }
+
+ protected void connectSignals() {
+ // nothing by default
+ }
+
+ boolean isQScrollArea() {
+ return getQWidget() instanceof QAbstractScrollArea;
+ }
+
+ protected void setupStyleSheet() {
+ String styleSheet = getShell() != null ? getShell().getQMasterWidget().styleSheet() : null;
+ if (styleSheet == null) {
+ styleSheet = getDisplay().getStyleSheet();
+ if (styleSheet != null) {
+ setStyleSheet(styleSheet);
+ }
+ }
+ }
+
+ protected void updateLayoutDirection() {
+ if ((style & SWT.RIGHT_TO_LEFT) != 0) {
+ getQWidget().setLayoutDirection(LayoutDirection.RightToLeft);
+ } else {
+ getQWidget().setLayoutDirection(LayoutDirection.LeftToRight);
+ }
+ }
+
+ protected void updateFocusPolicy() {
+ if ((style & SWT.NO_FOCUS) != 0) {
+ getQMasterWidget().setFocusPolicy(FocusPolicy.NoFocus);
+ }
+ }
+
+ void registerQWidget() {
+ display.addControl(getQWidget(), this);
+ if (getQMasterWidget() != null && getQMasterWidget() != getQWidget()) {
+ display.addControl(getQMasterWidget(), this);
+ }
+ }
+
+ void deregisterQWidget() {
+ display.removeControl(getQWidget());
+ if (getQMasterWidget() != null && getQMasterWidget() != getQWidget()) {
+ display.removeControl(getQMasterWidget());
+ }
+ }
+
+ @Override
+ void releaseQWidget() {
+ super.releaseQWidget();
+ parent = null;
+ }
+
+ @Override
+ void releaseParent() {
+ parent.removeControl(this);
+ }
+
+ @Override
+ void releaseWidget() {
+ super.releaseWidget();
+
+ deregisterQWidget();
+
+ if (menu != null && !menu.isDisposed()) {
+ menu.dispose();
+ }
+ temporaryGC = null;
+ backgroundImage = null;
+ menu = null;
+ cursor = null;
+ layoutData = null;
+ if (accessible != null) {
+ // TODO
+ //accessible.internal_dispose_Accessible();
+ }
+ accessible = null;
+ region = null;
+ font = null;
+ }
+
+ protected void checkAndUpdateBorder() {
+ checkAndUpdateBorder(getQMasterWidget());
+ if (getBorderWidth() == 0) {
+ style &= ~SWT.BORDER;
+ }
+ }
+
+ protected void checkAndUpdateBorder(QWidget control) {
+ if (control != null && control instanceof QFrame) {
+ QFrame frame = (QFrame) control;
+ if ((style & SWT.BORDER) != 0) {
+ frame.setFrameShape(Shape.StyledPanel);
+ frame.setFrameShadow(Shadow.Sunken);
+ frame.setLineWidth(1);
+ } else {
+ frame.setFrameShape(Shape.NoFrame);
+ frame.setLineWidth(0);
+ }
+ }
+
+ }
+
+ /* used by CoolBar */
+ boolean drawGripper(int x, int y, int width, int height, boolean vertical) {
+ return false;
+ }
+
+ /**
+ * 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 a drag gesture occurs, by sending it one of the messages defined in
+ * the <code>DragDetectListener</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 DragDetectListener
+ * @see #removeDragDetectListener
+ *
+ * @since 3.3
+ */
+ public void addDragDetectListener(DragDetectListener listener) {
+ checkWidget();
+ if (listener == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ TypedListener typedListener = new TypedListener(listener);
+ addListener(SWT.DragDetect, 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.
+ * <p>
+ * When a key listener is added to a control, the control will take part in
+ * widget traversal. By default, all traversal keys (such as the tab key and
+ * so on) are delivered to the control. In order for a control to take part
+ * in traversal, it should listen for traversal events. Otherwise, the user
+ * can traverse into a control but not out. Note that native controls such
+ * as table and tree implement key traversal in the operating system. It is
+ * not necessary to add traversal listeners for these controls, unless you
+ * want to override the default traversal.
+ * </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 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 the platform-specific context menu trigger has occurred, by sending
+ * it one of the messages defined in the <code>MenuDetectListener</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 MenuDetectListener
+ * @see #removeMenuDetectListener
+ *
+ * @since 3.3
+ */
+ public void addMenuDetectListener(MenuDetectListener listener) {
+ checkWidget();
+ if (listener == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ TypedListener typedListener = new TypedListener(listener);
+ addListener(SWT.MenuDetect, 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 mouse wheel is scrolled, by sending it one of the messages
+ * defined in the <code>MouseWheelListener</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 MouseWheelListener
+ * @see #removeMouseWheelListener
+ *
+ * @since 3.3
+ */
+ public void addMouseWheelListener(MouseWheelListener listener) {
+ checkWidget();
+ if (listener == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ TypedListener typedListener = new TypedListener(listener);
+ addListener(SWT.MouseWheel, 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);
+ }
+
+ protected void checkBuffered() {
+ style &= ~SWT.DOUBLE_BUFFERED;
+ }
+
+ protected void checkAndUpdateMirrored() {
+ if ((style & SWT.RIGHT_TO_LEFT) != 0) {
+ style |= SWT.MIRRORED;
+ }
+ }
+
+ /**
+ * 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();
+ if (changed) {
+ getQMasterWidget().updateGeometry();
+ }
+ Point res = QtSWTConverter.convert(getQMasterWidget().sizeHint());
+ if (res.x < 0) {
+ res.x = DEFAULT_WIDTH;
+ }
+ if (res.y < 0) {
+ res.y = DEFAULT_HEIGHT;
+ }
+
+ int border = getBorderWidth();
+ if (wHint != SWT.DEFAULT) {
+ res.x = wHint + 2 * border;
+ }
+ if (hHint != SWT.DEFAULT) {
+ res.y = hHint + 2 * border;
+ }
+
+ return res;
+ }
+
+ 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];
+ }
+
+ Font defaultFont() {
+ return display.getSystemFont();
+ }
+
+ /**
+ * Detects a drag and drop gesture. This method is used to detect a drag
+ * gesture when called from within a mouse down listener.
+ *
+ * <p>
+ * By default, a drag is detected when the gesture occurs anywhere within
+ * the client area of a control. Some controls, such as tables and trees,
+ * override this behavior. In addition to the operating system specific drag
+ * gesture, they require the mouse to be inside an item. Custom widget
+ * writers can use <code>setDragDetect</code> to disable the default
+ * detection, listen for mouse down, and then call <code>dragDetect()</code>
+ * from within the listener to conditionally detect a drag.
+ * </p>
+ *
+ * @param event
+ * the mouse down event
+ *
+ * @return <code>true</code> if the gesture occurred, and <code>false</code>
+ * otherwise.
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT when the event 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 DragDetectListener
+ * @see #addDragDetectListener
+ *
+ * @see #getDragDetect
+ * @see #setDragDetect
+ *
+ * @since 3.3
+ */
+ public boolean dragDetect(Event event) {
+ checkWidget();
+ if (event == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ return dragDetect(event.button, event.count, event.stateMask, event.x, event.y);
+ }
+
+ /**
+ * Detects a drag and drop gesture. This method is used to detect a drag
+ * gesture when called from within a mouse down listener.
+ *
+ * <p>
+ * By default, a drag is detected when the gesture occurs anywhere within
+ * the client area of a control. Some controls, such as tables and trees,
+ * override this behavior. In addition to the operating system specific drag
+ * gesture, they require the mouse to be inside an item. Custom widget
+ * writers can use <code>setDragDetect</code> to disable the default
+ * detection, listen for mouse down, and then call <code>dragDetect()</code>
+ * from within the listener to conditionally detect a drag.
+ * </p>
+ *
+ * @param event
+ * the mouse down event
+ *
+ * @return <code>true</code> if the gesture occurred, and <code>false</code>
+ * otherwise.
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT when the event 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 DragDetectListener
+ * @see #addDragDetectListener
+ *
+ * @see #getDragDetect
+ * @see #setDragDetect
+ *
+ * @since 3.3
+ */
+ public boolean dragDetect(MouseEvent event) {
+ checkWidget();
+ if (event == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ return dragDetect(event.button, event.count, event.stateMask, event.x, event.y);
+ }
+
+ boolean dragDetect(int button, int count, int stateMask, int x, int y) {
+ return false;
+ // TODO
+ }
+
+ Cursor findCursor() {
+ if (cursor != null) {
+ return cursor;
+ }
+ return parent.findCursor();
+ }
+
+ Control findImageControl() {
+ Control control = findBackgroundControl();
+ return control != null && control.backgroundImage != null ? control : null;
+ }
+
+ Control findThemeControl() {
+ return background == null && backgroundImage == null ? parent.findThemeControl() : null;
+ }
+
+ Menu[] findMenus(Control control) {
+ if (menu != null && this != control) {
+ return new Menu[] { menu };
+ }
+ return new Menu[0];
+ }
+
+ protected 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';
+ }
+
+ void fixChildren(Shell newShell, Shell oldShell, Decorations newDecorations, Decorations oldDecorations,
+ Menu[] menus) {
+ oldShell.fixShell(newShell, this);
+ oldDecorations.fixDecorations(newDecorations, this, menus);
+ }
+
+ private void fixFocus(Control focusControl) {
+ Shell shell = getShell();
+ Control control = this;
+ while (control != shell && (control = control.parent) != null) {
+ if (control.setFixedFocus()) {
+ return;
+ }
+ }
+
+ shell.setSavedFocus(focusControl);
+
+ QDesktopWidget desktopWidget = QApplication.desktop();
+ if (desktopWidget != null) {
+ desktopWidget.setFocus(FocusReason.OtherFocusReason);
+ }
+ }
+
+ /**
+ * 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();
+ return forceFocus(FocusReason.OtherFocusReason);
+ }
+
+ protected boolean forceFocus(FocusReason focusReason) {
+ 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);
+ getQWidget().setFocus(focusReason);
+ 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();
+ return _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;
+ }
+
+ Color _getBackgroundColor() {
+ Control control = findBackgroundControl();
+ if (control == null) {
+ control = this;
+ }
+ if (control.background != null) {
+ return control.background;
+ }
+ return getDefaultBackgroundColor();
+ }
+
+ /**
+ * 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();
+ if (getQMasterWidget() instanceof QFrame) {
+ return ((QFrame) getQMasterWidget()).frameWidth();
+ }
+ 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();
+ return QtSWTConverter.convert(getQMasterWidget().frameGeometry());
+ }
+
+ /**
+ * Returns the receiver's cursor, or null if it has not been set.
+ * <p>
+ * When the mouse pointer passes over a control its appearance is changed to
+ * match the control's cursor.
+ * </p>
+ *
+ * @return the receiver's cursor or <code>null</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>
+ *
+ * @since 3.3
+ */
+ public Cursor getCursor() {
+ checkWidget();
+ return cursor;
+ }
+
+ /**
+ * Returns <code>true</code> if the receiver is detecting drag gestures, and
+ * <code>false</code> otherwise.
+ *
+ * @return the receiver's drag detect 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 getDragDetect() {
+ checkWidget();
+ return isDragDetectEnabled();
+ }
+
+ private boolean isDragDetectEnabled() {
+ return (state & DRAG_DETECT) != 0;
+ }
+
+ /**
+ * Sets the receiver's drag detect state. If the argument is
+ * <code>true</code>, the receiver will detect drag gestures, otherwise
+ * these gestures will be ignored.
+ *
+ * @param dragDetect
+ * the new drag detect 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 setDragDetect(boolean dragDetect) {
+ checkWidget();
+ if (dragDetect) {
+ state |= DRAG_DETECT;
+ } else {
+ state &= ~DRAG_DETECT;
+ }
+ }
+
+ protected boolean isDropTargetEnabled() {
+ return getData(DND.DROP_TARGET_KEY) != null; // check if DropTarget is present
+ }
+
+ public void setAcceptDrops(boolean accept) {
+ getQMasterWidget().setAcceptDrops(accept);
+ }
+
+ public void setDragEnabled(boolean enabled) {
+ // nothing by default
+ }
+
+ public void dragEnd() {
+ dragStartPos = null;
+ }
+
+ public void setDragNDropListener(DragNDropListener listener) {
+ this.dndListener = listener;
+ }
+
+ public void unsetDragNDropListener(DragNDropListener listener) {
+ if (this.dndListener == listener) {
+ this.dndListener = null;
+ }
+ }
+
+ protected final void sendDropEvent(QDropEvent event) {
+ if (this.dndListener == null) {
+ return;
+ }
+ dndListener.drop(event);
+ }
+
+ protected final void sendDragMoveEvent(QDragMoveEvent event) {
+ if (this.dndListener == null) {
+ return;
+ }
+ dndListener.dragMove(event);
+ }
+
+ protected final void sendDragLeaveEvent(QDragLeaveEvent event) {
+ if (this.dndListener == null) {
+ return;
+ }
+ dndListener.dragLeave(event);
+ }
+
+ protected final void sendDragEnterEvent(QDragEnterEvent event) {
+ if (this.dndListener == null) {
+ return;
+ }
+ dndListener.dragEnter(event);
+ }
+
+ /**
+ * 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 font;
+ }
+ return 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 _getForegroundColor();
+ }
+
+ Color _getForegroundColor() {
+ if (foreground != null) {
+ return foreground;
+ }
+ return getDefaultForegroundColor();
+ }
+
+ protected Color getDefaultForegroundColor() {
+ return Color.qt_new(display, getColorFromPalette(ColorRole.WindowText));
+ }
+
+ protected QColor getColorFromPalette(ColorRole role) {
+ QPalette palette = getQWidget().palette();
+ return palette.color(role);
+ }
+
+ /**
+ * 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();
+ //forceResize();
+ return QtSWTConverter.convert(getQWidget().pos());
+ }
+
+ /**
+ * 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>
+ */
+ @Override
+ public Menu getMenu() {
+ checkWidget();
+ return menu;
+ }
+
+ /**
+ * Returns the receiver's monitor.
+ *
+ * @return the receiver's monitor
+ *
+ * @since 3.0
+ */
+ public Monitor getMonitor() {
+ checkWidget();
+ return Display.createMonitor(getQWidget());
+ }
+
+ /**
+ * 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 region that defines the shape of the control, or null if the
+ * control 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.4
+ */
+ public Region getRegion() {
+ checkWidget();
+ return region;
+ }
+
+ /**
+ * 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();
+ return QtSWTConverter.convert(getQMasterWidget().frameSize());
+ }
+
+ int getClientWidth() {
+ return getQMasterWidget().rect().width();
+ }
+
+ /**
+ * 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 getQWidget().toolTip();
+ }
+
+ boolean hasFocus() {
+ return getQWidget().hasFocus();
+ }
+
+ /**
+ * 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 QPaintDeviceInterface internal_new_GC(GCData data) {
+ checkWidget();
+ initGCData(data);
+ // we are in a Qt paint event
+ if (isOngoingPaintEvent) {
+ return getQWidget();
+ }
+ // if we are not in a paint event, we need to temporarily render to a
+ // temp GC and apply the changes in the next paint event
+ temporaryGC = new QPicture();
+ //System.out.println("creating tmp gc for " + this + " " + temporaryGC);
+ return temporaryGC;
+ }
+
+ void initGCData(GCData data) {
+ data.device = display;
+ data.backgroundColor = getBackground();
+ data.foregroundColor = getForeground();
+ data.font = getFont();
+ }
+
+ /**
+ * 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(QPaintDeviceInterface paintDevice, GCData data) {
+ checkWidget();
+ if (!isOngoingPaintEvent) {
+ //System.out.println("tmp gc back " + this + " " + parent + " " + Thread.currentThread());
+ //new RuntimeException().printStackTrace();
+ getQWidget().update();
+ }
+ }
+
+ boolean isActive() {
+ Dialog dialog = display.getModalDialog();
+ if (dialog != null) {
+ Shell dialogShell = dialog.parent;
+ if (dialogShell != null && !dialogShell.isDisposed()) {
+ if (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 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();
+ return _isFocusControl();
+ }
+
+ protected boolean _isFocusControl() {
+ Control focusControl = display.focusControl;
+ if (focusControl != null && !focusControl.isDisposed()) {
+ return this == focusControl;
+ }
+ return hasFocus();
+ }
+
+ boolean isFocusAncestor(Control control) {
+ while (control != null && control != this && !(control instanceof Shell)) {
+ 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 true;
+ }
+
+ boolean isShowing() {
+ 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;
+ }
+
+ boolean isTabGroup() {
+ Control[] tabList = parent._getTabList();
+ if (tabList != null) {
+ for (int i = 0; i < tabList.length; i++) {
+ if (tabList[i] == this) {
+ return true;
+ }
+ }
+ }
+ //TODO
+ return false;
+ }
+
+ boolean isTabItem() {
+ Control[] tabList = parent._getTabList();
+ if (tabList != null) {
+ for (int i = 0; i < tabList.length; i++) {
+ if (tabList[i] == this) {
+ return false;
+ }
+ }
+ }
+ return FocusPolicy.TabFocus.equals(getQWidget().focusPolicy());
+ }
+
+ /**
+ * 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 getQMasterWidget().isVisible();
+ }
+
+ /**
+ * 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();
+ // TODO hack. some layouts are distroyed if we return the visibile state instead of the real visibility
+ return getQMasterWidget().isVisible();
+ }
+
+ /**
+ * 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(final boolean visible) {
+ checkWidget();
+ _setVisible(getQMasterWidget(), visible);
+ }
+
+ protected void _setVisible(QWidget widget, final boolean visible) {
+ //this.visible = visible;
+
+ boolean oldVisibility = getQMasterWidget().isVisible();
+
+ // we always set the visibility, this is important during initialization, when all widgets are not visible, but some are explicitly hidden
+ widget.setVisible(visible);
+
+ if (oldVisibility == visible) { // bail out if state has not changed
+ return;
+ }
+
+ // TODO hack
+ if (widget.parentWidget() != null) {
+ widget.parentWidget().update();
+ }
+
+ if (getQMasterWidget().isVisible()) {
+ sendEvent(SWT.Show);
+ if (isDisposed()) {
+ return;
+ }
+ }
+ Control control = null;
+ boolean fixFocus = false;
+ if (getQMasterWidget().isHidden()) {
+ if (display.focusEvent != SWT.FocusOut) {
+ control = display.getFocusControl();
+ fixFocus = isFocusAncestor(control);
+ }
+
+ sendEvent(SWT.Hide);
+ if (isDisposed()) {
+ return;
+ }
+ }
+ if (fixFocus) {
+ fixFocus(control);
+ }
+ }
+
+ 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;
+ }
+
+ Control controlAbove = null;
+ List<QObject> children = getQWidget().children();
+ boolean next = false;
+ for (QObject child : children) {
+ Widget widget = display.findControl(child);
+ if (!next && widget == control) {
+ next = true;
+ continue;
+ }
+ if (next) {
+ if (widget != null && widget != this) {
+ if (widget instanceof Control) {
+ controlAbove = (Control) widget;
+ break;
+ }
+ }
+ }
+ }
+ if (controlAbove != null) {
+ moveBelow(controlAbove);
+ } else {
+ getQMasterWidget().raise();
+ }
+ } else {
+ getQMasterWidget().raise();
+ }
+ }
+
+ /**
+ * 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;
+ }
+ getQMasterWidget().stackUnder(control.getQWidget());
+ } else {
+ getQMasterWidget().lower();
+ }
+ }
+
+ Accessible new_Accessible(Control control) {
+ return Accessible.internal_new_Accessible(this);
+ }
+
+ @Override
+ GC new_GC(GCData data) {
+ return GC.qt_new(this, data);
+ }
+
+ /**
+ * 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));
+ }
+
+ /**
+ * Prints the receiver and all children.
+ *
+ * @param gc
+ * the gc where the drawing occurs
+ * @return <code>true</code> if the operation was successful and
+ * <code>false</code> otherwise
+ *
+ * @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.4
+ */
+ public boolean print(GC gc) {
+ checkWidget();
+ if (gc == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (gc.isDisposed()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+
+ // TODO
+ // QPixmap pix;
+ // pix.grabWidget(myMainWindowWidget);
+ // QImage im = pix.convertToImage();
+ return false;
+ }
+
+ /**
+ * 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();
+ }
+
+ void _redraw() {
+ getQMasterWidget().update();
+ if (getQMasterWidget() != getQWidget()) {
+ getQWidget().update();
+ }
+ redrawChildren();
+ }
+
+ /**
+ * 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();
+ getQMasterWidget().update(x, y, width, height);
+ if (getQMasterWidget() != getQWidget()) {
+ getQWidget().update(x, y, width, height);
+ }
+
+ if (all) {
+ redrawChildren();
+ }
+ }
+
+ void redrawChildren() {
+ }
+
+ /**
+ * 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 a drag gesture occurs.
+ *
+ * @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 DragDetectListener
+ * @see #addDragDetectListener
+ *
+ * @since 3.3
+ */
+ public void removeDragDetectListener(DragDetectListener listener) {
+ checkWidget();
+ if (listener == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (eventTable == null) {
+ return;
+ }
+ eventTable.unhook(SWT.DragDetect, 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 platform-specific context menu trigger has occurred.
+ *
+ * @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 MenuDetectListener
+ * @see #addMenuDetectListener
+ *
+ * @since 3.3
+ */
+ public void removeMenuDetectListener(MenuDetectListener listener) {
+ checkWidget();
+ if (listener == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (eventTable == null) {
+ return;
+ }
+ eventTable.unhook(SWT.MenuDetect, 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 mouse wheel is scrolled.
+ *
+ * @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 MouseWheelListener
+ * @see #addMouseWheelListener
+ *
+ * @since 3.3
+ */
+ public void removeMouseWheelListener(MouseWheelListener listener) {
+ checkWidget();
+ if (listener == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (eventTable == null) {
+ return;
+ }
+ eventTable.unhook(SWT.MouseWheel, 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);
+ }
+
+ void sendMove() {
+ sendEvent(SWT.Move);
+ }
+
+ void sendResize() {
+ sendEvent(SWT.Resize);
+ }
+
+ /**
+ * 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.
+ * <p>
+ * Note: This operation is a hint and may be overridden by the platform. For
+ * example, on Windows the background of a Button cannot be changed.
+ * </p>
+ *
+ * @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();
+ _setBackground(color);
+ }
+
+ void _setBackground(Color color) {
+ if (color != null) {
+ if (color.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ }
+ if (color == null) {
+ background = getDefaultBackgroundColor();
+ } else {
+ background = color;
+ }
+ if (backgroundImage == null) {
+ updateBackgroundColor();
+ }
+ }
+
+ protected Color getDefaultBackgroundColor() {
+ return display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
+ }
+
+ /* refactored: was checkBackground */
+ protected void checkAndUpdateBackground() {
+ Shell shell = getShell();
+ if (this == shell) {
+ return;
+ }
+ state &= ~PARENT_BACKGROUND;
+ Composite composite = parent;
+ do {
+ int mode = composite.getBackgroundMode();
+ 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);
+ }
+
+ protected void updateBackground() {
+ if ((state & PARENT_BACKGROUND) == 0) {
+ return;
+ }
+ Control control = findBackgroundImageControl();
+ if (control == null) {
+ control = this;
+ }
+ if (control.backgroundImage != null) {
+ applyBackgroundImage(control.backgroundImage);
+ return;
+ }
+
+ control = findBackgroundColorControl();
+ if (control == null) {
+ control = this;
+ }
+ applyBackgroundColor(control.background != null ? control.background : control.getDefaultBackgroundColor());
+ }
+
+ Control findBackgroundControl() {
+ if (background != null || backgroundImage != null) {
+ return this;
+ }
+ return (state & PARENT_BACKGROUND) != 0 ? parent.findBackgroundControl() : null;
+ }
+
+ protected void applyBackgroundColor(Color color) {
+ updatedPalette(color, getBackgroundColorRoles());
+ }
+
+ protected void updatedPalette(Color color, ColorRole[] colorRoles) {
+ QPalette palette = getQMasterWidget().palette();
+ for (ColorRole role : colorRoles) {
+ palette.setBrush(role, new QBrush(color.getColor()));
+ }
+ getQMasterWidget().setAutoFillBackground(true);
+ getQMasterWidget().setPalette(palette);
+ }
+
+ protected ColorRole[] getBackgroundColorRoles() {
+ return new ColorRole[] { ColorRole.Window, ColorRole.Base, ColorRole.Button };
+ }
+
+ protected ColorRole[] getBackgroundImageRoles() {
+ return new QPalette.ColorRole[] { QPalette.ColorRole.Window, QPalette.ColorRole.Base };
+ }
+
+ /**
+ * 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.
+ * <p>
+ * Note: This operation is a hint and may be overridden by the platform. For
+ * example, on Windows the background of a Button cannot be changed.
+ * </p>
+ *
+ * @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.isBitmap()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ }
+ if (image == null) {
+ backgroundImage = null;
+ updateBackgroundColor();
+ } else {
+ backgroundImage = image;
+ updateBackgroundImage();
+ }
+ }
+
+ void applyBackgroundImage(Image image) {
+ QPalette palette = getQMasterWidget().palette();
+ ColorRole[] bkRoles = getBackgroundImageRoles();
+ for (ColorRole bkRole : bkRoles) {
+ // if (bgControl != this && canInheritBackgroundImage()) {
+ // palette.setColor(bkRole, null);
+ // // If background is inherited then brush is set to null
+ // palette.setBrush(bkRole, null);
+ // } else {
+ palette.setBrush(bkRole, new QBrush(image.getQPixmap()));
+ // }
+ }
+ getQMasterWidget().setPalette(palette);
+ getQMasterWidget().setAutoFillBackground(true);
+ }
+
+ protected boolean canInheritBackgroundImage() {
+ return true;
+ }
+
+ /**
+ * 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();
+ setBounds(x, y, width, height, true, true);
+ }
+
+ protected void setBounds(int x, int y, int width, int height, boolean move, boolean resize) {
+ if (resize) {
+ Point oldSize = QtSWTConverter.convert(getQMasterWidget().size());
+ if (oldSize.x != width || oldSize.y != height) {
+ getQMasterWidget().resize(width, height);
+ state |= RESIZE_OCCURRED;
+ }
+ }
+ if (move) {
+ Point oldPos = QtSWTConverter.convert(getQMasterWidget().pos());
+ if (oldPos.x != x || oldPos.y != y) {
+ getQMasterWidget().move(x, y);
+ state |= MOVE_OCCURRED;
+ }
+ }
+ }
+
+ /**
+ * 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, true, true);
+ }
+
+ /**
+ * 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. Note that on some platforms, a mouse
+ * button must currently be down for capture to be assigned.
+ *
+ * @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) {
+ getQMasterWidget().grabMouse();
+ } else {
+ getQMasterWidget().releaseMouse();
+ }
+ }
+
+ /**
+ * 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) {
+ getQMasterWidget().setCursor(null);
+ } else {
+ getQMasterWidget().setCursor(cursor.cursor);
+ }
+ }
+
+ /**
+ * 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 getQMasterWidget().isEnabled();
+ }
+
+ /**
+ * 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 enabled;
+ }
+
+ /**
+ * 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();
+ /*
+ * 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);
+ }
+ }
+ enableWidget(enabled);
+ if (fixFocus) {
+ fixFocus(control);
+ }
+ }
+
+ void enableWidget(boolean enabled) {
+ this.enabled = enabled;
+ getQMasterWidget().setEnabled(enabled);
+ }
+
+ boolean setFixedFocus() {
+ if ((style & SWT.NO_FOCUS) != 0) {
+ return false;
+ }
+ return forceFocus(FocusReason.OtherFocusReason);
+ }
+
+ /**
+ * 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();
+ return setFocus(FocusReason.OtherFocusReason);
+ }
+
+ protected boolean setFocus(FocusReason focusReason) {
+ if ((style & SWT.NO_FOCUS) != 0) {
+ return false;
+ }
+ return forceFocus(focusReason);
+ }
+
+ /**
+ * 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 && font.isDisposed()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ this.font = font;
+ if (font == null) {
+ getQMasterWidget().setFont(null);
+ } else {
+ getQMasterWidget().setFont(font.getQFont());
+ }
+ }
+
+ /**
+ * 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.
+ * <p>
+ * Note: This operation is a hint and may be overridden by the platform.
+ * </p>
+ *
+ * @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();
+ Color oldColor = foreground;
+ if (color != null) {
+ if (color.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ }
+ if (foreground == null && color == null) {
+ return;
+ }
+ if (color == null) {
+ foreground = null;
+ } else {
+ foreground = Color.qt_new(display, color.getColor());
+ }
+ if (oldColor != null) {
+ oldColor.dispose();
+ }
+ applyForegroundColor(foreground);
+ }
+
+ protected void updateForeground() {
+ if (foreground != null) {
+ applyForegroundColor(foreground);
+ }
+ }
+
+ void applyForegroundColor(Color color) {
+ updatedPalette(color, getForegroundColorRoles());
+ }
+
+ private ColorRole[] getForegroundColorRoles() {
+ return new ColorRole[] { QPalette.ColorRole.WindowText, QPalette.ColorRole.Text, QPalette.ColorRole.ButtonText };
+ }
+
+ /**
+ * 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();
+ setBounds(x, y, 0, 0, true, false);
+ }
+
+ /**
+ * 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;
+ }
+
+ boolean setRadioFocus(boolean tabbing) {
+ 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();
+ getQMasterWidget().setUpdatesEnabled(redraw);
+ }
+
+ /**
+ * Sets the shape of the control to the region specified by the argument.
+ * When the argument is null, the default shape of the control is restored.
+ *
+ * @param region
+ * the region that defines the shape of the control (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.4
+ */
+ public void setRegion(Region region) {
+ checkWidget();
+ if (region != null && region.isDisposed()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ this.region = region;
+ getQMasterWidget().setMask(QtSWTConverter.convert(region));
+ }
+
+ 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();
+ setBounds(0, 0, Math.max(0, width), Math.max(0, height), false, true);
+ }
+
+ /**
+ * 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 the default tool tip for the control will be shown. For a
+ * control that has a default tool tip, such as the Tree control on Windows,
+ * setting the tool tip text to an empty string replaces the default,
+ * causing no tool tip text to be shown.
+ * <p>
+ * The mnemonic indicator (character '&amp;') is not displayed in a tool
+ * tip. To display a single '&amp;' in the tool tip, the character '&amp;'
+ * can be escaped by doubling it in the string.
+ * </p>
+ *
+ * @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();
+ getQMasterWidget().setToolTip(string);
+ }
+
+ /**
+ * 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();
+ Point mappedPoint = QtSWTConverter.convert(getQMasterWidget().mapFromGlobal(new QPoint(x, y)));
+ if (isMirrored()) {
+ mappedPoint.x = getClientWidth() - mappedPoint.x;
+ }
+ return mappedPoint;
+ }
+
+ boolean isMirrored() {
+ return (style & SWT.MIRRORED) != 0;
+ }
+
+ /**
+ * 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();
+ if (isMirrored()) {
+ x = getClientWidth() - x;
+ }
+ return QtSWTConverter.convert(getQMasterWidget().mapToGlobal(new QPoint(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();
+ System.out.println("toDisplay:" + point);
+ 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 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) {
+ // TODO
+ // if (mnemonicHit(key)) {
+ // OS.SendMessage(handle, OS.WM_CHANGEUISTATE, OS.UIS_INITIALIZE, 0);
+ // return true;
+ // }
+ return false;
+ }
+
+ 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. If there are no outstanding paint request,
+ * this method does nothing.
+ * <p>
+ * Note: This method does not cause a redraw.
+ * </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 #redraw()
+ * @see #redraw(int, int, int, int, boolean)
+ * @see PaintListener
+ * @see SWT#Paint
+ */
+ public void update() {
+ checkWidget();
+ _update();
+ }
+
+ void _update() {
+ QCoreApplication.processEvents(ProcessEventsFlag.ExcludeUserInputEvents);
+ }
+
+ void updateBackgroundColor() {
+ Control control = findBackgroundColorControl();
+ if (control == null) {
+ control = this;
+ }
+ applyBackgroundColor(control.background);
+ }
+
+ Control findBackgroundColorControl() {
+ if (background != null) {
+ return this;
+ }
+ if (parent == null) {
+ return null;
+ }
+ return (state & PARENT_BACKGROUND) != 0 ? parent.findBackgroundColorControl() : null;
+ }
+
+ void updateBackgroundImage() {
+ Control control = findBackgroundImageControl();
+ if (control == null) {
+ control = this;
+ }
+ applyBackgroundImage(control.backgroundImage);
+ }
+
+ Control findBackgroundImageControl() {
+ if (backgroundImage != null) {
+ return this;
+ }
+ if (parent == null) {
+ return null;
+ }
+ return (state & PARENT_BACKGROUND) != 0 ? parent.findBackgroundImageControl() : null;
+ }
+
+ void updateBackgroundMode() {
+ int oldState = state & PARENT_BACKGROUND;
+ checkAndUpdateBackground();
+ if (oldState != (state & PARENT_BACKGROUND)) {
+ updateBackground();
+ }
+ }
+
+ void updateFont(Font oldFont, Font newFont) {
+ if (getFont().equals(oldFont)) {
+ setFont(newFont);
+ }
+ }
+
+ void updateImages() {
+ /* Do nothing */
+ }
+
+ void updateLayout(boolean all) {
+ /* Do nothing */
+ }
+
+ /**
+ * 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;
+ }
+ releaseParent();
+ Shell newShell = parent.getShell(), oldShell = getShell();
+ Decorations newDecorations = parent.menuShell(), oldDecorations = menuShell();
+ if (oldShell != newShell || oldDecorations != newDecorations) {
+ Menu[] menus = oldShell.findMenus(this);
+ fixChildren(newShell, oldShell, newDecorations, oldDecorations, menus);
+ }
+ getQMasterWidget().setParent(parent.getQWidget());
+ return true;
+ }
+
+ @Override
+ public boolean qtPaintEvent(QObject source, QPaintEvent paintEvent) {
+ if (source == getQWidget()) {
+ try {
+ isOngoingPaintEvent = true;
+ renderTemporaryGC(paintEvent.rect());
+ sendPaintEvent(paintEvent);
+ } finally {
+ isOngoingPaintEvent = false;
+ }
+ }
+ return false;
+ }
+
+ private void renderTemporaryGC(QRect rect) {
+ // Render the buffer created outside the paint event, if any
+ if (temporaryGC != null) {
+ //System.out.println("render tmp gc for " + this + " " + rect + " " + temporaryGC);
+ QPainter painter = new QPainter(getQWidget());
+ //painter.setClipRect(rect);
+ painter.drawPicture(0, 0, temporaryGC);
+ painter.end();
+ temporaryGC = null;
+ }
+ }
+
+ private void sendPaintEvent(QPaintEvent paintEvent) {
+ if (!hooks(SWT.Paint) && !filters(SWT.Paint)) {
+ return;
+ }
+
+ QRect rect = paintEvent.rect();
+ int x = rect.x();
+ int y = rect.y();
+ int width = rect.width();
+ int height = rect.height();
+ GCData data = new GCData();
+ initGCData(data);
+ GC gc = GC.qt_new(this, getQWidget(), data);
+ Event event = new Event();
+ event.count = 0;
+ if (isMirrored()) {
+ event.x = getClientWidth() - x - width;
+ } else {
+ event.x = x;
+ }
+ event.y = y;
+ event.width = width;
+ event.height = height;
+ event.gc = gc;
+ try {
+ gc.setClipping(x, y, width, height);
+ sendEvent(SWT.Paint, event);
+ } finally {
+ if (!gc.isDisposed()) {
+ gc.dispose();
+ }
+ }
+ }
+
+ @Override
+ public boolean qtResizeEvent(QObject source, QResizeEvent resizeEvent) {
+ if (source == getQWidget()) {
+ sendResize();
+ }
+ return super.qtResizeEvent(source, resizeEvent);
+ }
+
+ @Override
+ public boolean qtMoveEvent(QObject source, QMoveEvent moveEvent) {
+ // if (source == getQMasterWidget()) {
+ // sendMove();
+ // }
+ return true;
+ }
+
+ @Override
+ public boolean qtKeyPressEvent(QObject source, QKeyEvent qEvent) {
+ // if ( ( ( state & NO_KEY_PROPAGATE ) != 0 ) ) {
+ // return true;
+ // }
+ if (source == getQWidget()) {
+ return sendKeyEvent(SWT.KeyDown, qEvent);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean qtKeyReleaseEvent(QObject source, QKeyEvent qEvent) {
+ if (source == getQWidget()) {
+ return sendKeyEvent(SWT.KeyUp, qEvent);
+ }
+ // if ( ( ( state & NO_KEY_PROPAGATE ) != 0 ) ) {
+ // return true;
+ // }
+ return false;
+ }
+
+ boolean sendKeyEvent(int type, QKeyEvent qEvent) {
+ Event event = translateKeyEvent(qEvent);
+ sendEvent(type, event);
+ if (isDisposed()) {
+ return true;
+ }
+ return !event.doit;
+ }
+
+ private final Event translateKeyEvent(QKeyEvent qEvent) {
+ Event event = new Event();
+ switch (Key.resolve(qEvent.key())) {
+ case Key_Enter:
+ case Key_Return:
+ event.character = SWT.CR;
+ break;
+ case Key_Backspace:
+ event.character = SWT.BS;
+ break;
+ case Key_Delete:
+ event.character = SWT.DEL;
+ break;
+ case Key_Escape:
+ event.character = SWT.ESC;
+ break;
+ case Key_Tab:
+ event.character = SWT.TAB;
+ break;
+ default:
+ String text = qEvent.text();
+ if (text != null && text.length() > 0) {
+ event.character = qEvent.text().charAt(0);
+ }
+ break;
+ }
+ event.keyCode = KeyUtil.translateKey(qEvent);
+ if (event.keyCode == 0) {// keyCode defaults to unicode value
+ String text = qEvent.text();
+ if (text != null && text.length() > 0) {
+ event.keyCode = qEvent.text().charAt(0);
+ }
+ }
+ event.stateMask = KeyUtil.translateModifiers(qEvent.modifiers());
+ return event;
+ }
+
+ protected boolean sendMouseEvent(int type, QMouseEvent mouseEvent) {
+ return sendMouseEvent(type, mouseEvent, 0);
+ }
+
+ protected boolean sendMouseEvent(int type, QMouseEvent mouseEvent, int count) {
+ Event event = translateMouseEvent(mouseEvent, count);
+ sendEvent(type, event);
+ if (isDisposed()) {
+ return true;
+ }
+ return !event.doit;
+ }
+
+ private Event translateMouseEvent(QMouseEvent mouseEvent, int count) {
+ Event event = new Event();
+ QPoint pos = mouseEvent.pos();
+ event.x = pos.x();
+ event.y = pos.y();
+ event.count = count;
+ event.button = translateMouseButton(mouseEvent.button());
+ event.stateMask = KeyUtil.translateModifiers(mouseEvent.modifiers())
+ | translateMouseButtons(mouseEvent.buttons());
+ event.stateMask &= ~event.button;
+
+ return event;
+ }
+
+ protected int translateMouseButton(MouseButton button) {
+ switch (button) {
+ case LeftButton:
+ return SWT.BUTTON1;
+ case MidButton:
+ return SWT.BUTTON2;
+ case RightButton:
+ return SWT.BUTTON1;
+ }
+ return 0;
+ }
+
+ private int translateMouseButtons(MouseButtons buttons) {
+ int mask = 0;
+ if (buttons.isSet(MouseButton.LeftButton)) {
+ mask |= SWT.BUTTON1;
+ }
+ if (buttons.isSet(MouseButton.MidButton)) {
+ mask |= SWT.BUTTON2;
+ }
+ if (buttons.isSet(MouseButton.RightButton)) {
+ mask |= SWT.BUTTON3;
+ }
+ return mask;
+ }
+
+ @Override
+ public boolean qtMouseMoveEvent(QObject source, QMouseEvent mouseEvent) {
+ if (source == getQWidget()) {
+ if (checkForDragging(mouseEvent)) {
+ System.out.println("dragging...");
+ sendDragEvent(SWT.BUTTON1, mouseEvent.pos().x(), mouseEvent.pos().y());
+ return true;
+ } else {
+ return sendMouseEvent(SWT.MouseMove, mouseEvent);
+ }
+ }
+ return false;
+ }
+
+ private boolean checkForDragging(QMouseEvent event) {
+ return dragStartPos != null && isDragDetectEnabled()
+ && event.pos().subtract(dragStartPos).manhattanLength() >= QApplication.startDragDistance();
+ }
+
+ @Override
+ public boolean qtMouseButtonPressEvent(QObject source, QMouseEvent mouseEvent) {
+ if (source == getQWidget()) {
+ checkForDragStart(mouseEvent);
+ return sendMouseEvent(SWT.MouseDown, mouseEvent, 1);
+ }
+ return false;
+ }
+
+ private void checkForDragStart(QMouseEvent mouseEvent) {
+ if (isDragDetectEnabled() && mouseEvent.buttons().isSet(MouseButton.LeftButton)) {
+ dragStartPos = mouseEvent.pos();
+ }
+ }
+
+ @Override
+ public boolean qtMouseButtonReleaseEvent(QObject source, QMouseEvent mouseEvent) {
+ if (source == getQWidget()) {
+ dragStartPos = null;
+ return sendMouseEvent(SWT.MouseUp, mouseEvent, 1);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean qtMouseButtonDblClickEvent(QObject source, QMouseEvent mouseEvent) {
+ if (source == getQWidget()) {
+ //System.out.println("mouse dbl click on: " + this);
+ boolean doit = sendMouseEvent(SWT.MouseDown, mouseEvent, 2);
+ if (doit) {
+ return sendMouseEvent(SWT.MouseDoubleClick, mouseEvent, 2);
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void qtFocusInEvent(QObject source) {
+ if (source != getQMasterWidget()) {
+ return;
+ }
+ try {
+ display.focusEvent = SWT.FocusIn;
+ sendEvent(SWT.FocusIn);
+ } finally {
+ display.focusEvent = SWT.None;
+ }
+ }
+
+ @Override
+ public void qtFocusOutEvent(QObject source) {
+ if (source != getQMasterWidget()) {
+ return;
+ }
+ try {
+ display.focusEvent = SWT.FocusOut;
+ sendEvent(SWT.FocusOut);
+ } finally {
+ display.focusEvent = SWT.None;
+ }
+ }
+
+ protected boolean handleContextMenuEvent(QContextMenuEvent menuEvent) {
+ if (isDisposed()) {
+ return false;
+ }
+ Event event = new Event();
+ event.x = menuEvent.globalX();
+ event.y = menuEvent.globalY();
+ sendEvent(SWT.MenuDetect, event);
+
+ if (this.menu == null || menu.isDisposed()) {
+ return event.doit;
+ }
+ List<QAction> actions = getQWidget().actions();
+ if ((actions == null || actions.size() == 0) && menu == null) {
+ return false;
+ }
+
+ QMenu popUpMenu = menu.getQMenu();
+ popUpMenu.exec(menuEvent.globalPos());
+ return true;
+ }
+
+ @Override
+ public boolean qtContextMenuEvent(Object source, QContextMenuEvent event) {
+ if (source == getQWidget()) {
+ return handleContextMenuEvent(event);
+ }
+ return super.qtContextMenuEvent(source, event);
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/DateTime.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/DateTime.java
new file mode 100644
index 0000000000..be8ea748c2
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/DateTime.java
@@ -0,0 +1,806 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.core.QDate;
+import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.core.QTime;
+import com.trolltech.qt.gui.QCalendarWidget;
+import com.trolltech.qt.gui.QDateTimeEdit;
+import com.trolltech.qt.gui.QWidget;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Instances of this class are selectable user interface objects that allow the
+ * user to enter and modify date or time values.
+ * <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>DATE, TIME, CALENDAR, SHORT, MEDIUM, LONG, DROP_DOWN</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>DefaultSelection, Selection</dd>
+ * </dl>
+ * <p>
+ * Note: Only one of the styles DATE, TIME, or CALENDAR may be specified, and
+ * only one of the styles SHORT, MEDIUM, or LONG may be specified. The DROP_DOWN
+ * style is only valid with the DATE style.
+ * </p>
+ * <p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#datetime">DateTime
+ * snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ *
+ * @since 3.3
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public class DateTime extends Composite {
+ boolean doubleClick, ignoreSelection;
+ private QTime calendarTime;
+
+ /**
+ * @return the time
+ */
+ private QTime getCalendarTime() {
+ return calendarTime;
+ }
+
+ /**
+ * @param time
+ * the time to set
+ */
+ private void setCalendarTime(QTime time) {
+ this.calendarTime = time;
+ }
+
+ static final char SINGLE_QUOTE = '\'';// short date format may include quoted text
+ static final char DAY_FORMAT_CONSTANT = 'd';// 1-4 lowercase 'd's represent day
+ static final char MONTH_FORMAT_CONSTANT = 'M';// 1-4 uppercase 'M's represent month
+ static final char YEAR_FORMAT_CONSTANT = 'y';// 1-5 lowercase 'y's represent year
+ static final char HOURS_FORMAT_CONSTANT = 'h';// 1-2 upper or lowercase 'h's represent hours
+ static final char MINUTES_FORMAT_CONSTANT = 'm';// 1-2 lowercase 'm's represent minutes
+ static final char SECONDS_FORMAT_CONSTANT = 's';// 1-2 lowercase 's's represent seconds
+ static final char AMPM_FORMAT_CONSTANT = 't';// 1-2 lowercase 't's represent am/pm
+
+ /**
+ * 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#DATE
+ * @see SWT#TIME
+ * @see SWT#CALENDAR
+ * @see SWT#SHORT
+ * @see SWT#MEDIUM
+ * @see SWT#LONG
+ * @see SWT#DROP_DOWN
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+
+ public DateTime(Composite parent, int style) {
+ super(parent, checkStyle(style));
+ setDateToToday();
+ setTimeToNow();
+ }
+
+ @Override
+ protected QWidget createQWidget(int style) {
+ state &= ~(CANVAS | THEME_BACKGROUND);
+ QWidget calendar = new QWidget();
+ boolean isCalendarWidget = false;
+ boolean isTimeEdit = false;
+ if ((style & SWT.CALENDAR) != 0) {
+ calendar = new QCalendarWidget();
+ isCalendarWidget = true;
+ ((QCalendarWidget) calendar).setSelectedDate(QDate.currentDate());
+ connectSignals(calendar, isCalendarWidget);
+ } else if ((style & SWT.TIME) != 0) {
+ isTimeEdit = true;
+ /* Need to set time twice to get the right widget *with* time. */
+ calendar = new QDateTimeEdit(QTime.currentTime());
+ ((QDateTimeEdit) calendar).setDate(QDate.currentDate());
+ ((QDateTimeEdit) calendar).setTime(QTime.currentTime());
+ } else if ((style & SWT.ARROW) != 0 || (style & SWT.DROP_DOWN) != 0) {
+ calendar = new QDateTimeEdit(QDate.currentDate());
+ ((QDateTimeEdit) calendar).setCalendarPopup(true);
+ ((QDateTimeEdit) calendar).setDate(QDate.currentDate());
+ ((QDateTimeEdit) calendar).setTime(QTime.currentTime());
+ } else /* default is a QDateEdit */{
+ calendar = new QDateTimeEdit(QDate.currentDate());
+ ((QDateTimeEdit) calendar).setTime(QTime.currentTime());
+ ((QDateTimeEdit) calendar).setDate(QDate.currentDate());
+ }
+ if (!isCalendarWidget) {
+ connectSignals(calendar, isCalendarWidget);
+ if ((style & SWT.SHORT) != 0) {
+ if (isTimeEdit) {
+ ((QDateTimeEdit) calendar).setDisplayFormat(getShortTimeFormat());
+ } else {
+ ((QDateTimeEdit) calendar).setDisplayFormat(getShortDateFormat());
+ }
+ /*
+ * when DisplayFormat is set I need to set the time *again* for
+ * some strange reasons
+ */
+ ((QDateTimeEdit) calendar).setTime(QTime.currentTime());
+ } else if ((style & SWT.LONG) != 0) {
+ ((QDateTimeEdit) calendar).setDisplayFormat(getLongDateFormat());
+ ((QDateTimeEdit) calendar).setTime(QTime.currentTime());
+ }
+ }
+
+ return calendar;
+ }
+
+ private void connectSignals(QWidget calendar, boolean isCalendarWidget) {
+ if (isCalendarWidget) {
+ ((QCalendarWidget) calendar).clicked.connect(this, "clicked()"); //$NON-NLS-1$
+ ((QCalendarWidget) calendar).selectionChanged.connect(this, "clicked()"); //$NON-NLS-1$
+ } else {
+ /* some missing events */
+ //((QDateTimeEdit) calendar).dateChanged.connect(this, "dateChanged()"); //$NON-NLS-1$
+ // ((QDateTimeEdit) calendar).dateTimeChanged.connect(this, "dateTimeChanged()"); //$NON-NLS-1$
+ // ((QDateTimeEdit) calendar).timeChanged.connect(this, "timeChanged()"); //$NON-NLS-1$
+ // ((QDateTimeEdit) calendar).editingFinished.connect(this, "editingFinished"); //$NON-NLS-1$
+
+ }
+ }
+
+ protected void clicked() {
+ Event event = new Event();
+ sendEvent(SWT.Selection, event);
+ }
+
+ /**
+ * sets the date to now
+ */
+ private void setDateToToday() {
+ QDate date = QDate.currentDate();
+ setQtDate(date);
+ }
+
+ /**
+ * sets the date to now
+ */
+ private void setTimeToNow() {
+ setQtTime(QTime.currentTime());
+ setCalendarTime(new QTime(0, 0, 0));
+ }
+
+ /**
+ * Adds the listener to the collection of listeners who will be notified
+ * when the control is selected by the user, by sending it one of the
+ * messages defined in the <code>SelectionListener</code> interface.
+ * <p>
+ * <code>widgetSelected</code> is called when the user changes the control's
+ * value. <code>widgetDefaultSelected</code> is typically called when ENTER
+ * is pressed.
+ * </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) {
+ /*
+ * 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.DATE, SWT.TIME, SWT.CALENDAR, 0, 0, 0);
+ style = checkBits(style, SWT.MEDIUM, SWT.SHORT, SWT.LONG, 0, 0, 0);
+ if ((style & SWT.DATE) == 0) {
+ style &= ~SWT.DROP_DOWN;
+ }
+ return style;
+ }
+
+ @Override
+ protected void checkSubclass() {
+ if (!isValidSubclass()) {
+ error(SWT.ERROR_INVALID_SUBCLASS);
+ }
+ }
+
+ @Override
+ public Point computeSize(int wHint, int hHint, boolean changed) {
+ QWidget calendar = getQWidget();
+ QSize size = calendar.sizeHint();
+ return new Point(size.width(), size.height());
+ }
+
+ String getComputeSizeString() {
+ // TODO: Not currently used but might need for WinCE
+ if ((style & SWT.DATE) != 0) {
+ if ((style & SWT.SHORT) != 0) {
+ return getCustomShortDateFormat();
+ }
+ if ((style & SWT.MEDIUM) != 0) {
+ return getShortDateFormat();
+ }
+ if ((style & SWT.LONG) != 0) {
+ return getLongDateFormat();
+ }
+ }
+ if ((style & SWT.TIME) != 0) {
+ if ((style & SWT.SHORT) != 0) {
+ return getCustomShortTimeFormat();
+ }
+ return getTimeFormat();
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ String getCustomShortDateFormat() {
+ // TODO
+ return "M/yyyy"; //$NON-NLS-1$
+
+ }
+
+ String getCustomShortTimeFormat() {
+ StringBuffer buffer = new StringBuffer(getTimeFormat());
+ int length = buffer.length();
+ boolean inQuotes = false;
+ int start = 0, end = 0;
+ while (start < length) {
+ char ch = buffer.charAt(start);
+ if (ch == SINGLE_QUOTE) {
+ inQuotes = !inQuotes;
+ } else if (ch == SECONDS_FORMAT_CONSTANT && !inQuotes) {
+ end = start + 1;
+ while (end < length && buffer.charAt(end) == SECONDS_FORMAT_CONSTANT) {
+ end++;
+ }
+ // skip the preceding separator
+ while (start > 0 && buffer.charAt(start) != MINUTES_FORMAT_CONSTANT) {
+ start--;
+ }
+ start++;
+ break;
+ }
+ start++;
+ }
+ if (start < end) {
+ buffer.delete(start, end);
+ }
+ return buffer.toString();
+ }
+
+ String getLongDateFormat() {
+ return "dddd, d. MMMM yyyy"; //$NON-NLS-1$
+ }
+
+ String getShortDateFormat() {
+ return "MMMM yyyy"; //$NON-NLS-1$
+ }
+
+ String getShortTimeFormat() {
+ return "hh:mm"; //$NON-NLS-1$
+ }
+
+ int getShortDateFormatOrdering() {
+ // TODO
+ return 0;
+ }
+
+ String getTimeFormat() {
+ // TODO
+ return "h:mm:ss tt"; //$NON-NLS-1$
+ }
+
+ boolean is24HourTime() {
+ // TODO
+ return true;
+ }
+
+ /**
+ * Returns the receiver's date, or day of the month.
+ * <p>
+ * The first day of the month is 1, and the last day depends on the month
+ * and year.
+ * </p>
+ *
+ * @return a positive integer beginning with 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 getDay() {
+ checkWidget();
+ if (getQWidget() instanceof QCalendarWidget) {
+ return ((QCalendarWidget) getQWidget()).selectedDate().day();
+ }
+ return ((QDateTimeEdit) getQWidget()).date().day();
+
+ }
+
+ /**
+ * Returns the receiver's hours.
+ * <p>
+ * Hours is an integer between 0 and 23.
+ * </p>
+ *
+ * @return an integer between 0 and 23
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if 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 getHours() {
+ checkWidget();
+ if (getQWidget() instanceof QCalendarWidget) {
+ return getCalendarTime().hour();
+ }
+ return ((QDateTimeEdit) getQWidget()).time().hour();
+
+ }
+
+ /**
+ * Returns the receiver's minutes.
+ * <p>
+ * Minutes is an integer between 0 and 59.
+ * </p>
+ *
+ * @return an integer between 0 and 59
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if 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 getMinutes() {
+ checkWidget();
+ if (getQWidget() instanceof QCalendarWidget) {
+ return getCalendarTime().minute();
+ }
+ return ((QDateTimeEdit) getQWidget()).time().minute();
+
+ }
+
+ /**
+ * Returns the receiver's month.
+ * <p>
+ * The first month of the year is 0, and the last month is 11.
+ * </p>
+ *
+ * @return an integer between 0 and 11
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if 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 getMonth() {
+ checkWidget();
+
+ QDate date = getQtDate();
+ return date.month() - 1;
+ }
+
+ @Override
+ String getNameText() {
+ return (style & SWT.TIME) != 0 ? getHours() + ":" + getMinutes() + ":" + getSeconds() : getMonth() + "/" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ + getDay() + "/" + getYear(); //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the receiver's seconds.
+ * <p>
+ * Seconds is an integer between 0 and 59.
+ * </p>
+ *
+ * @return an integer between 0 and 59
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if 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 getSeconds() {
+ checkWidget();
+ if (getQWidget() instanceof QCalendarWidget) {
+ return getCalendarTime().second();
+ }
+ return ((QDateTimeEdit) getQWidget()).time().second();
+ }
+
+ /**
+ * Returns the receiver's year.
+ * <p>
+ * The first year is 1752 and the last year is 9999.
+ * </p>
+ *
+ * @return an integer between 1752 and 9999
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if 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 getYear() {
+ checkWidget();
+ if (getQWidget() instanceof QCalendarWidget) {
+ return ((QCalendarWidget) getQWidget()).selectedDate().year();
+ }
+ return ((QDateTimeEdit) getQWidget()).date().year();
+ }
+
+ @Override
+ void releaseWidget() {
+ super.releaseWidget();
+ // lastSystemTime = null;
+ }
+
+ /**
+ * Removes the listener from the collection of listeners who will be
+ * notified when the control is selected by the user.
+ *
+ * @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 receiver's year, month, and day in a single operation.
+ * <p>
+ * This is the recommended way to set the date, because setting the year,
+ * month, and day separately may result in invalid intermediate dates.
+ * </p>
+ *
+ * @param year
+ * an integer between 1752 and 9999
+ * @param month
+ * an integer between 0 and 11
+ * @param day
+ * a positive integer beginning with 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>
+ *
+ * @since 3.4
+ */
+ public void setDate(int year, int month, int day) {
+ checkWidget();
+ QDate date = new QDate(year, month + 1, day);
+ if (getQWidget() instanceof QCalendarWidget) {
+ ((QCalendarWidget) getQWidget()).setSelectedDate(date);
+ } else {
+ ((QDateTimeEdit) getQWidget()).setDate(date);
+ }
+ }
+
+ /**
+ * Sets the receiver's date, or day of the month, to the specified day.
+ * <p>
+ * The first day of the month is 1, and the last day depends on the month
+ * and year. If the specified day is not valid for the receiver's month and
+ * year, then it is ignored.
+ * </p>
+ *
+ * @param day
+ * a positive integer beginning with 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>
+ *
+ * @see #setDate
+ */
+ public void setDay(int day) {
+ checkWidget();
+ QDate date = getQtDate();
+ date.setDate(date.year(), date.month(), day);
+ setQtDate(date);
+ }
+
+ private QDate getQtDate() {
+ if (getQWidget() instanceof QCalendarWidget) {
+ return ((QCalendarWidget) getQWidget()).selectedDate();
+ }
+ return ((QDateTimeEdit) getQWidget()).date();
+ }
+
+ private QTime getQtTime() {
+ if (getQWidget() instanceof QCalendarWidget) {
+ return getCalendarTime();
+ }
+ return ((QDateTimeEdit) getQWidget()).time();
+ }
+
+ private void setQtDate(final QDate date) {
+ if (getQWidget() instanceof QCalendarWidget) {
+ ((QCalendarWidget) getQWidget()).setSelectedDate(date);
+ } else {
+ ((QDateTimeEdit) getQWidget()).setDate(date);
+ }
+ }
+
+ private void setQtTime(final QTime time) {
+ if (getQWidget() instanceof QCalendarWidget) {
+ setCalendarTime(time);
+ } else {
+ ((QDateTimeEdit) getQWidget()).setTime(time);
+ }
+ }
+
+ /**
+ * Sets the receiver's hours.
+ * <p>
+ * Hours is an integer between 0 and 23.
+ * </p>
+ *
+ * @param hours
+ * an integer between 0 and 23
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if 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 setHours(int hours) {
+ checkWidget();
+ QTime time = new QTime(hours, getQtTime().minute(), getQtTime().second());
+ setQtTime(time);
+ }
+
+ /**
+ * Sets the receiver's minutes.
+ * <p>
+ * Minutes is an integer between 0 and 59.
+ * </p>
+ *
+ * @param minutes
+ * an integer between 0 and 59
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if 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 setMinutes(int minutes) {
+ checkWidget();
+ QTime time = new QTime(getQtTime().hour(), minutes, getQtTime().second());
+ setQtTime(time);
+ }
+
+ /**
+ * Sets the receiver's month.
+ * <p>
+ * The first month of the year is 0, and the last month is 11. If the
+ * specified month is not valid for the receiver's day and year, then it is
+ * ignored.
+ * </p>
+ *
+ * @param month
+ * an integer between 0 and 11
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - 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 #setDate
+ */
+ public void setMonth(final int month) {
+ checkWidget();
+
+ QDate date = getQtDate();
+ date.setDate(date.year(), month + 1, date.day());
+ setQtDate(date);
+ }
+
+ /**
+ * Sets the receiver's seconds.
+ * <p>
+ * Seconds is an integer between 0 and 59.
+ * </p>
+ *
+ * @param seconds
+ * an integer between 0 and 59
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if 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 setSeconds(int seconds) {
+ checkWidget();
+ QTime time = new QTime(getQtTime().hour(), getQtTime().minute(), seconds);
+ setQtTime(time);
+
+ }
+
+ /**
+ * Sets the receiver's hours, minutes, and seconds in a single operation.
+ *
+ * @param hours
+ * an integer between 0 and 23
+ * @param minutes
+ * an integer between 0 and 59
+ * @param seconds
+ * an integer between 0 and 59
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - 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.4
+ */
+ public void setTime(int hours, int minutes, int seconds) {
+ checkWidget();
+ setQtTime(new QTime(hours, minutes, seconds));
+ }
+
+ /**
+ * Sets the receiver's year.
+ * <p>
+ * The first year is 1752 and the last year is 9999. If the specified year
+ * is not valid for the receiver's day and month, then it is ignored.
+ * </p>
+ *
+ * @param year
+ * an integer between 1752 and 9999
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - 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 #setDate
+ */
+ public void setYear(int year) {
+ checkWidget();
+ QDate date = new QDate(year, getQtDate().month(), getQtDate().day());
+ setQtDate(date);
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Decorations.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Decorations.java
new file mode 100644
index 0000000000..ecc78ea4da
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Decorations.java
@@ -0,0 +1,1218 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.core.QObject;
+import com.trolltech.qt.core.QRect;
+import com.trolltech.qt.core.Qt.WindowState;
+import com.trolltech.qt.core.Qt.WindowStates;
+import com.trolltech.qt.gui.QLayout;
+import com.trolltech.qt.gui.QMainWindow;
+import com.trolltech.qt.gui.QWidget;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.internal.qt.QtSWTConverter;
+
+/**
+ * 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
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public class Decorations extends Canvas {
+ private static final int WIDGETSIZE_MAX = 16777215;
+ Image image, smallImage, largeImage;
+ Image[] images;
+ Menu menuBar;
+ Menu[] menus;
+ Control savedFocus;
+ Button defaultButton, saveDefault;
+ int swFlags, nAccel;
+ boolean moved, resized, opened;
+ private int restoreState;
+ private Point fixedSize;
+ static int topTitleFrame = -1;
+ static int leftTitleFrame = -1;
+ static int rightTitleFrame = -1;
+ static int bottomTitleFrame = -1;
+ static int topThinFrame = -1;
+ static int leftThinFrame = -1;
+ static int rightThinFrame = -1;
+ static int bottomThinFrame = -1;
+
+ /**
+ * 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));
+ }
+
+ protected QWidget getWindowControl() {
+ return getQWidget();
+ }
+
+ QWidget getMenuContainer() {
+ return getWindowControl();
+ }
+
+ 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() {
+ if (isDisposed()) {
+ return;
+ }
+ getWindowControl().activateWindow();
+ getWindowControl().raise();
+ }
+
+ 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;
+ }
+
+ @Override
+ protected void checkAndUpdateBorder() {
+ /* Do nothing */
+ }
+
+ @Override
+ void checkOpened() {
+ if (!opened) {
+ resized = false;
+ }
+ }
+
+ @Override
+ protected void checkSubclass() {
+ if (!isValidSubclass()) {
+ error(SWT.ERROR_INVALID_SUBCLASS);
+ }
+ }
+
+ boolean closeWidget() {
+ Event event = new Event();
+ event.doit = true;
+ sendEvent(SWT.Close, event);
+ if (event.doit && !isDisposed()) {
+ dispose();
+ }
+ if (isDisposed()) {
+ return false;
+ }
+ return !event.doit;
+ }
+
+ 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 (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;
+ }
+
+ @Override
+ Control computeTabGroup() {
+ return this;
+ }
+
+ @Override
+ Control computeTabRoot() {
+ return this;
+ }
+
+ @Override
+ public Rectangle computeTrim(int x, int y, int width, int height) {
+ checkWidget();
+
+ Rectangle trim = new Rectangle(x, y, width, height);
+
+ QRect outer = getQWidget().frameGeometry();
+ QRect inner = getQWidget().geometry();
+
+ int leftTrim, rightTrim;
+ leftTrim = rightTrim = outer.x() - inner.x();
+ int topTrim = inner.y() - outer.y();
+ int bottomTrim = outer.y() - inner.y();
+
+ trim.x -= leftTrim;
+ trim.width += leftTrim + rightTrim;
+ trim.y -= topTrim;
+ trim.height += topTrim + bottomTrim;
+
+ return trim;
+ }
+
+ @Override
+ public void dispose() {
+ if (isDisposed()) {
+ return;
+ }
+ if (!isValidThread()) {
+ error(SWT.ERROR_THREAD_INVALID_ACCESS);
+ }
+ if (!(this instanceof Shell)) {
+ if (!traverseDecorations(true)) {
+ Shell shell = getShell();
+ shell.setFocus();
+ }
+ setVisible(false);
+ }
+ super.dispose();
+ }
+
+ 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.getMenu();
+ if (menu != null) {
+ int index = 0;
+ while (index < menus.length) {
+ if (menus[index] == menu) {
+ control.setMenu(null);
+ return;
+ }
+ index++;
+ }
+ menu.fixMenus(newDecorations);
+ }
+ }
+
+ /**
+ * 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(Button)
+ */
+ 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 getWindowControl().isMaximized();
+ }
+
+ /**
+ * 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 getWindowControl().isMinimized();
+ }
+
+ @Override
+ 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();
+ return getWindowControl().windowTitle();
+ }
+
+ @Override
+ public boolean qtCloseEvent() {
+ if (isEnabled()) {
+ closeWidget();
+ }
+ return true;
+ }
+
+ @Override
+ 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;
+ }
+
+ @Override
+ boolean isTabGroup() {
+ /*
+ * Can't test WS_TAB bits because they are the same as WS_MAXIMIZEBOX.
+ */
+ return true;
+ }
+
+ @Override
+ boolean isTabItem() {
+ /*
+ * Can't test WS_TAB bits because they are the same as WS_MAXIMIZEBOX.
+ */
+ return false;
+ }
+
+ @Override
+ Decorations menuShell() {
+ return this;
+ }
+
+ @Override
+ 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;
+ }
+ }
+
+ @Override
+ void releaseWidget() {
+ super.releaseWidget();
+ if (smallImage != null) {
+ smallImage.dispose();
+ }
+ if (largeImage != null) {
+ largeImage.dispose();
+ }
+ smallImage = largeImage = 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 (savedFocus != null && savedFocus.isDisposed()) {
+ savedFocus = null;
+ }
+ return savedFocus != null && savedFocus.setSavedFocus();
+ }
+
+ void saveFocus() {
+ Control control = display.getFocusControl();
+ if (control != null && control != this && this == control.menuShell()) {
+ setSavedFocus(control);
+ }
+ }
+
+ protected void unlockSize() {
+ getWindowControl().setMaximumSize(WIDGETSIZE_MAX, WIDGETSIZE_MAX);
+ getWindowControl().setMinimumSize(0, 0);
+ }
+
+ protected boolean sizeFixed() {
+ return getWindowControl().minimumSize().equals(getQWidget().maximumSize());
+ }
+
+ protected void setRestoreState(int state, boolean restore) {
+ int oldState = getWindowControl().windowState().value();
+ if (restore) {
+ if ((oldState & state) == 0) {
+ return;
+ }
+ restoreState();
+ } else {
+ setState(state);
+ }
+ }
+
+ protected void restoreState() {
+ // This might not restore it from minimized if wm doesn't allow it.
+ // It might e.g. blink in the task bar to indicate to the user
+ // that the window wants to become active.
+ if (restoreState == WindowState.WindowMinimized.value()) {
+ setState(WindowState.WindowMinimized.value());
+ } else if (restoreState == WindowState.WindowMaximized.value()) {
+ setState(WindowState.WindowMaximized.value());
+ } else {
+ setState(WindowState.WindowNoState.value());
+ }
+ bringToTop();
+ restoreState = 0;
+ }
+
+ protected void storeState(int state) {
+ if ((state & WindowState.WindowMinimized.value()) != 0) {
+ restoreState = WindowState.WindowMinimized.value();
+ } else if ((state & WindowState.WindowMaximized.value()) != 0) {
+ restoreState = WindowState.WindowMaximized.value();
+ } else {
+ restoreState = 0;
+ }
+ }
+
+ protected void setState(final int state) {
+ final int oldState = getWindowControl().windowState().value();
+ if ((oldState & state) != 0) {
+ return;
+ }
+ storeState(oldState);
+ int newState = oldState;
+ int statesToRemove = (WindowState.WindowFullScreen.value() | WindowState.WindowMaximized.value() | WindowState.WindowMinimized
+ .value())
+ & ~state;
+ newState &= ~statesToRemove;
+ newState |= state;
+
+ // Full screen and maximize won't work if size is fixed. The fixed size
+ // needs to be stored and then restored when going back to normal state.
+ if ((newState & (WindowState.WindowFullScreen.value() | WindowState.WindowMaximized.value())) != 0
+ && (oldState & (WindowState.WindowFullScreen.value() | WindowState.WindowMaximized.value())) == 0) {
+ if (sizeFixed()) {
+ fixedSize = QtSWTConverter.convert(getWindowControl().minimumSize());
+ style |= SWT.Resize;
+ unlockSize();
+ }
+ }
+
+ // Going directly from full screen to maximized doesn't work. Need to go
+ // normal first.
+ if ((newState & WindowState.WindowMaximized.value()) != 0
+ && (oldState & WindowState.WindowFullScreen.value()) != 0) {
+ getWindowControl().setWindowState(WindowState.WindowNoState);
+ }
+
+ getWindowControl().setWindowState(new WindowStates(newState));
+
+ // Restore the fixed size if back to normal
+ if ((newState & (WindowState.WindowFullScreen.value() | WindowState.WindowMaximized.value())) == 0) {
+ if (fixedSize != null) {
+ getWindowControl().setFixedSize(fixedSize.x, fixedSize.y);
+ style &= ~SWT.Resize;
+ fixedSize = null;
+ }
+ }
+ }
+
+ /**
+ * 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;
+ if (image != null) {
+ getWindowControl().setWindowIcon(image.getQIcon());
+ }
+ }
+
+ /**
+ * 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;
+ this.images = images;
+ if (parent != null) {
+ return;
+ }
+ if (images != null && images.length > 1) {
+ Image[] bestImages = new Image[images.length];
+ System.arraycopy(images, 0, bestImages, 0, images.length);
+ sort(bestImages);
+ images = bestImages;
+ }
+ if (images.length > 0) {
+ getWindowControl().setWindowIcon(images[0].getQIcon());
+ } else {
+ getWindowControl().setWindowIcon(null);
+ }
+ }
+
+ /**
+ * 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();
+ if (maximized) {
+ getWindowControl().showMaximized();
+
+ } else {
+ getWindowControl().showNormal();
+ }
+ }
+
+ /**
+ * 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);
+ }
+ }
+ if (menuBar != null) {
+ menuBar.dispose();
+ }
+ menuBar = menu;
+ if (parent == null) { // window
+ ((QMainWindow) getMenuContainer()).setMenuBar(menu.getQMenuBar());
+ } else {
+ QLayout layout = getWindowControl().layout();
+ layout.setMenuBar(menu.getQWidget());
+ }
+
+ }
+
+ /**
+ * 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();
+ if (minimized) {
+ getWindowControl().showMinimized();
+
+ } else {
+ getWindowControl().showNormal();
+ }
+ }
+
+ 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 title
+ * 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 title) {
+ checkWidget();
+ if (title == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ // fix for emtpy title
+ if (title.length() == 0) {
+ title = " "; //$NON-NLS-1$
+ }
+ getWindowControl().setWindowTitle(title);
+ getWindowControl().setWindowIconText(title);
+ }
+
+ void sort(Image[] images) {
+ /* Shell Sort from K&R, pg 108 */
+ int length = images.length;
+ if (length <= 1) {
+ return;
+ }
+ ImageData[] datas = new ImageData[length];
+ for (int i = 0; i < length; i++) {
+ datas[i] = images[i].getImageData();
+ }
+ 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]) >= 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;
+ }
+ }
+ }
+ }
+ }
+
+ int compare(ImageData data1, ImageData data2) {
+ if (data1.width == data2.width && data1.height == data2.height) {
+ int transparent1 = data1.getTransparencyType();
+ int transparent2 = data2.getTransparencyType();
+ 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 data1.width > data2.width || data1.height > data2.height ? -1 : 1;
+ }
+
+ 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;
+ }
+
+ @Override
+ boolean traverseItem(boolean next) {
+ return false;
+ }
+
+ @Override
+ boolean traverseReturn() {
+ if (defaultButton == null || defaultButton.isDisposed()) {
+ return false;
+ }
+ if (!defaultButton.isVisible() || !defaultButton.isEnabled()) {
+ return false;
+ }
+ defaultButton.click();
+ return true;
+ }
+
+ @Override
+ public void qtFocusInEvent(QObject source) {
+ if (source != getQMasterWidget()) {
+ return;
+ }
+ super.qtFocusInEvent(source);
+ if (savedFocus != this) {
+ restoreFocus();
+ }
+ }
+
+ @Override
+ public void qtFocusOutEvent(QObject source) {
+ if (source != getQMasterWidget()) {
+ return;
+ }
+ super.qtFocusInEvent(source);
+ if (savedFocus != this) {
+ saveFocus();
+ }
+ }
+
+ @Override
+ public boolean qtWindowActivateEvent(QObject source) {
+ if (source == getWindowControl()) {
+ sendEvent(SWT.Activate);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean qtWindowDeactivateEvent(QObject source) {
+ if (source == getWindowControl()) {
+ sendEvent(SWT.Deactivate);
+ saveFocus();
+ }
+ return false;
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/DirectoryDialog.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/DirectoryDialog.java
new file mode 100644
index 0000000000..697a3c1e76
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/DirectoryDialog.java
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.core.QDir;
+import com.trolltech.qt.gui.QFileDialog;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+
+/**
+ * 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>
+ *
+ * @see <a
+ * href="http://www.eclipse.org/swt/snippets/#directorydialog">DirectoryDialog
+ * snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample, Dialog tab</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public class DirectoryDialog extends Dialog {
+ String message = "", filterPath = ""; //$NON-NLS-1$//$NON-NLS-2$
+ String directoryPath = ""; //$NON-NLS-1$
+ String[] dirNames = new String[0];
+ QFileDialog fd;
+
+ /**
+ * 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.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.
+ * </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, checkStyle(parent, style));
+ checkSubclass();
+ fd = new QFileDialog();
+ fd.setFileMode(QFileDialog.FileMode.DirectoryOnly);
+ }
+
+ /**
+ * Returns the path which the dialog will use to filter the directories it
+ * shows.
+ *
+ * @return the filter path
+ *
+ * @see #setFilterPath
+ */
+ public String getFilterPath() {
+ QDir dir = fd.directory();
+ return dir.absolutePath();
+ }
+
+ /**
+ * 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() {
+
+ java.util.List<String> dirs = null;
+ if (fd.exec() != 0) {
+ dirs = fd.selectedFiles();
+ }
+ directoryPath = dirs.get(0); //
+ fd.disposeLater();
+
+ return directoryPath;
+ }
+
+ /**
+ * 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) {
+ fd.setDirectory(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) {
+ /*
+ * QFileDialog has nothing like this message. There's a caption which
+ * will be shown in the title of the dialog window. But this has to be
+ * set when the dialog is initialized. There are also some labelTexts
+ * which can be set like setLabelText(DialogLabel.FileName, "Choose:")
+ * but these are only for describing buttons and textfields
+ */
+ if (string == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+
+ message = string;
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Display.java
new file mode 100644
index 0000000000..5d0bdf4a25
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Display.java
@@ -0,0 +1,3200 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.trolltech.qt.core.QEvent;
+import com.trolltech.qt.core.QEventLoop;
+import com.trolltech.qt.core.QMessageHandler;
+import com.trolltech.qt.core.QObject;
+import com.trolltech.qt.core.QPoint;
+import com.trolltech.qt.core.QRect;
+import com.trolltech.qt.core.QTime;
+import com.trolltech.qt.core.QTimer;
+import com.trolltech.qt.core.QTimerEvent;
+import com.trolltech.qt.core.QEvent.Type;
+import com.trolltech.qt.core.QEventLoop.ProcessEventsFlags;
+import com.trolltech.qt.core.Qt.Key;
+import com.trolltech.qt.core.Qt.KeyboardModifier;
+import com.trolltech.qt.core.Qt.KeyboardModifiers;
+import com.trolltech.qt.core.Qt.MouseButton;
+import com.trolltech.qt.gui.QApplication;
+import com.trolltech.qt.gui.QCloseEvent;
+import com.trolltech.qt.gui.QContextMenuEvent;
+import com.trolltech.qt.gui.QCursor;
+import com.trolltech.qt.gui.QFont;
+import com.trolltech.qt.gui.QIcon;
+import com.trolltech.qt.gui.QKeyEvent;
+import com.trolltech.qt.gui.QMouseEvent;
+import com.trolltech.qt.gui.QMoveEvent;
+import com.trolltech.qt.gui.QPaintDeviceInterface;
+import com.trolltech.qt.gui.QPaintEvent;
+import com.trolltech.qt.gui.QPicture;
+import com.trolltech.qt.gui.QPixmap;
+import com.trolltech.qt.gui.QResizeEvent;
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.qt.gui.QWindowStateChangeEvent;
+import com.trolltech.qt.gui.QStyle.StandardPixmap;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTError;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.Device;
+import org.eclipse.swt.graphics.DeviceData;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GCData;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.internal.qt.KeyUtil;
+import org.eclipse.swt.internal.qt.QtSWTConverter;
+import org.eclipse.swt.internal.qt.SWQT;
+
+/**
+ * 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, Settings</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
+ * @see <a href="http://www.eclipse.org/swt/snippets/#display">Display
+ * snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public class Display extends Device {
+
+ Thread thread;
+ int threadId;
+ /* Windows and Events */
+ private Event[] eventQueue;
+ private EventTable eventTable, filterTable;
+
+ /* Focus */
+ int focusEvent;
+ Control focusControl;
+
+ /* Menus */
+ private Menu[] bars;
+ Menu[] popups;
+ private MenuItem[] items;
+
+ /* Settings */
+ private static final int /* long */SETTINGS_ID = 100;
+
+ /*
+ * The start value for WM_COMMAND id's. Windows reserves the values 0..100.
+ *
+ * The SmartPhone SWT resource file reserves the values 101..107.
+ */
+ private static final int ID_START = 108;
+
+ /* Sync/Async Widget Communication */
+ private Synchronizer synchronizer = new Synchronizer(this);
+
+ /* Display Shutdown */
+ private Runnable[] disposeList;
+
+ /* System Tray */
+ private Tray tray;
+
+ /* Timers */
+ private int /* long */[] timerIds;
+ private Runnable[] timerList;
+ private int /* long */nextTimerId = SETTINGS_ID + 1;
+
+ /* Keyboard and Mouse */
+ int lastKey;
+ int lastAscii;
+ boolean lastVirtual;
+ boolean lastNull;
+ boolean xMouse;
+
+ /* System Resources */
+ private Font systemFont;
+ private Image errorImage, infoImage, questionImage, warningIcon;
+ private Cursor[] cursors = new Cursor[SWT.CURSOR_HAND + 1];
+
+ /* Display Data */
+ private Object data;
+ private String[] keys;
+ private Object[] values;
+
+ /* Multiple Displays */
+ private static Display Default;
+ private static Display[] Displays = new Display[4];
+
+ /* Modality */
+ Shell[] modalShells;
+ private Dialog modalDialog;
+
+ /* Qt specific fields */
+ private String styleSheet;
+ private Map<Object, Widget> qt2swtControlMap;
+ private MasterEventFilter masterEventFilter;
+ private int lastEventTime;
+ private static final ProcessEventsFlags PROCESS_EVENTS_FLAGS = new ProcessEventsFlags(
+ QEventLoop.ProcessEventsFlag.AllEvents);
+ private QTimer timer;
+ private final boolean ignorePaintEvents = false;
+ private QMessageHandler messageHandler;
+
+ /* Package Name */
+ private static final String PACKAGE_PREFIX = "org.eclipse.swt.widgets."; //$NON-NLS-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);
+ }
+
+ public String getStyleSheet() {
+ return styleSheet;
+ }
+
+ protected void setStyleSheet(String style) {
+ this.styleSheet = style;
+ for (Shell shell : getShells()) {
+ shell.setStyleSheet(style);
+ }
+ Event event = new Event();
+ event.text = style;
+ sendEvent(SWQT.StyleSheetChange, event);
+ }
+
+ private Control _getFocusControl() {
+ Widget widget = findControl(QApplication.focusWidget());
+ if (widget instanceof Control) {
+ return (Control) widget;
+ }
+ return null;
+ }
+
+ void addControl(Object qtControl, Widget swtControl) {
+ if (qtControl == null || swtControl == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ qt2swtControlMap.put(qtControl, swtControl);
+ }
+
+ Widget findControl(Object qtControl) {
+ if (qtControl == null) {
+ return null;
+ }
+ return qt2swtControlMap.get(qtControl);
+ }
+
+ Widget removeControl(Object qtControl) {
+ return qt2swtControlMap.remove(qtControl);
+ }
+
+ void addBar(Menu menu) {
+ if (bars == null) {
+ bars = new Menu[4];
+ }
+ int length = bars.length;
+ for (int i = 0; i < length; i++) {
+ if (bars[i] == menu) {
+ return;
+ }
+ }
+ int index = 0;
+ while (index < length) {
+ if (bars[index] == null) {
+ break;
+ }
+ index++;
+ }
+ if (index == length) {
+ Menu[] newBars = new Menu[length + 4];
+ System.arraycopy(bars, 0, newBars, 0, length);
+ bars = newBars;
+ }
+ bars[index] = menu;
+ }
+
+ void releaseTray(Tray tray) {
+ if (this.tray == tray) {
+ this.tray = null;
+ }
+ }
+
+ /**
+ * 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 addMenuItem(MenuItem item) {
+ if (items == null) {
+ items = new MenuItem[64];
+ }
+ for (int i = 0; i < items.length; i++) {
+ if (items[i] == null) {
+ item.id = i + ID_START;
+ items[i] = item;
+ return;
+ }
+ }
+ item.id = items.length + ID_START;
+ MenuItem[] newItems = new MenuItem[items.length + 64];
+ newItems[items.length] = item;
+ System.arraycopy(items, 0, newItems, 0, items.length);
+ items = newItems;
+ }
+
+ 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) {
+ synchronized (Device.class) {
+ 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();
+ QApplication.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);
+ }
+ }
+
+ @Override
+ protected void checkDevice() {
+ if (thread == null) {
+ error(SWT.ERROR_WIDGET_DISPOSED);
+ }
+ if (thread != Thread.currentThread()) {
+ /*
+ * Bug in IBM JVM 1.6. For some reason, under conditions that are
+ * yet to be full understood, Thread.currentThread() is either
+ * returning null or a different instance from the one that was
+ * saved when the Display was created. This is possibly a JIT
+ * problem because modifying this method to print logging
+ * information when the error happens seems to fix the problem. The
+ * fix is to use operating system calls to verify that the current
+ * thread is not the Display thread.
+ *
+ * NOTE: Despite the fact that Thread.currentThread() is used in
+ * other places, the failure has not been observed in all places
+ * where it is called.
+ */
+
+ if (threadId != (int) Thread.currentThread().getId()) {
+ error(SWT.ERROR_THREAD_INVALID_ACCESS);
+ }
+ }
+ if (isDisposed()) {
+ error(SWT.ERROR_DEVICE_DISPOSED);
+ }
+ }
+
+ private static void checkDisplay(Thread thread, boolean multiple) {
+ synchronized (Device.class) {
+ for (int i = 0; i < Displays.length; i++) {
+ if (Displays[i] != null) {
+ if (!multiple) {
+ SWT.error(SWT.ERROR_NOT_IMPLEMENTED, null, " [multiple displays]"); //$NON-NLS-1$
+ }
+ if (Displays[i].thread == thread) {
+ SWT.error(SWT.ERROR_THREAD_INVALID_ACCESS);
+ }
+ }
+ }
+ }
+ }
+
+ 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
+ */
+ @Override
+ protected void create(DeviceData data) {
+ checkSubclass();
+ checkDisplay(thread = Thread.currentThread(), true);
+ createDisplay(data);
+ register(this);
+ if (Default == null) {
+ Default = this;
+ }
+ }
+
+ private void createDisplay(DeviceData data) {
+ qt2swtControlMap = Collections.synchronizedMap(new HashMap<Object, Widget>());
+ QApplication.initialize(new String[0]);
+ QApplication.setQuitOnLastWindowClosed(false);
+ masterEventFilter = new MasterEventFilter(this);
+ QApplication.instance().installEventFilter(masterEventFilter);
+ setPaintDevice(QApplication.desktop());
+ messageHandler = new SwtMessageHandler();
+ QMessageHandler.installMessageHandler(messageHandler);
+ }
+
+ static void deregister(Display display) {
+ synchronized (Device.class) {
+ 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
+ */
+ @Override
+ protected void destroy() {
+ if (this == Default) {
+ Default = null;
+ }
+ deregister(this);
+ destroyDisplay();
+ }
+
+ void destroyDisplay() {
+ QMessageHandler.removeMessageHandler(messageHandler);
+ QApplication.instance().removeEventFilter(masterEventFilter);
+ QApplication.instance().dispose();
+ }
+
+ /**
+ * 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 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 /* long */id) {
+ checkDevice();
+ // TODO howto to it with qt ? use qObj.nativeId() ?
+ throw new UnsupportedOperationException("not yet implemented for qt"); //$NON-NLS-1$
+ }
+
+ // linux 64bit
+ public Widget findWidget(/* int */long id) {
+ checkDevice();
+ // TODO howto to it with qt ? use qObj.nativeId() ?
+ throw new UnsupportedOperationException("not yet implemented for qt"); //$NON-NLS-1$
+ }
+
+ // win32
+ public Widget findWidget(int /* long */hwnd, int /* long */id) {
+ checkDevice();
+ // TODO howto to it with qt ? use qObj.nativeId() ?
+ throw new UnsupportedOperationException("not yet implemented for qt"); //$NON-NLS-1$
+ }
+
+ /**
+ * 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 Display findDisplay(Thread thread) {
+ synchronized (Device.class) {
+ 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();
+ QWidget activeWindow = QApplication.activeWindow();
+ Widget control = findControl(activeWindow);
+ if (!(control instanceof Control)) {
+ return null;
+ }
+ return control != null ? ((Control) control).getShell() : null;
+ }
+
+ /**
+ * Returns a rectangle describing the receiver's size and location. Note
+ * that on multi-monitor systems the origin can be negative.
+ *
+ * @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>
+ */
+ @Override
+ public Rectangle getBounds() {
+ checkDevice();
+ return QtSWTConverter.convert(QApplication.desktop().screenGeometry());
+ }
+
+ /**
+ * 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 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
+ */
+ @Override
+ public Rectangle getClientArea() {
+ checkDevice();
+ return QtSWTConverter.convert(QApplication.desktop().childrenRect());
+ }
+
+ /**
+ * 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();
+ Widget widget = findControl(QApplication.widgetAt(QCursor.pos()));
+ if (widget instanceof Control) {
+ return (Control) widget;
+ }
+ 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();
+ return QtSWTConverter.convert(QCursor.pos());
+ }
+
+ /**
+ * 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(32, 32) };
+ }
+
+ /**
+ * 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 Display getDefault() {
+ synchronized (Device.class) {
+ if (Default == null) {
+ Default = new Display();
+ // Hack: This is necessary to prevent a JVM crash when leaving the Eclipse IDE with Qt!
+ // http://eclipse.compeople.eu/wiki/index.php/Compeople:SWTQtImplementierungsdetails#ACCESS_VIOLATION_beim_Beenden_der_IDE_mit_Qt
+ Display.deregister(Default);
+ Default.destroyDisplay();
+ }
+ 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 (SWQT.STYLESHEET_KEY.equals(key)) {
+ return styleSheet;
+ }
+
+ 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();
+ return QApplication.doubleClickInterval();
+ }
+
+ /**
+ * 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();
+ if (focusControl != null && !focusControl.isDisposed()) {
+ return focusControl;
+ }
+ 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 false;
+ }
+
+ /**
+ * 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();
+ return QPixmap.defaultDepth();
+ }
+
+ /**
+ * 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 defaults ok?
+ return new Point[] { new Point(16, 16), new Point(32, 32) };
+ }
+
+ public int getLastEventTime() {
+ return lastEventTime;
+ }
+
+ private 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;
+ }
+
+ Dialog getModalDialog() {
+ return modalDialog;
+ }
+
+ /**
+ * Returns an array of monitors attached to the device.
+ *
+ * @return the array of monitors
+ *
+ * @since 3.0
+ */
+ public Monitor[] getMonitors() {
+ checkDevice();
+ Monitor[] monitors = new Monitor[QApplication.desktop().numScreens()];
+ for (int i = 0; i < monitors.length; i++) {
+ monitors[i] = createMonitor(i);
+ }
+ return monitors;
+ }
+
+ static Monitor createMonitor(QWidget widget) {
+ return createMonitor(QApplication.desktop().screenNumber(widget));
+ }
+
+ static Monitor createMonitor(int index) {
+ QRect screen = QApplication.desktop().screenGeometry(index);
+ Monitor monitor = new Monitor();
+ monitor.handle = index;
+ monitor.width = screen.width();
+ monitor.height = screen.height();
+
+ QRect rect = QApplication.desktop().availableGeometry(index);
+ monitor.clientX = rect.left();
+ monitor.clientY = rect.top();
+ monitor.clientWidth = rect.width();
+ monitor.clientHeight = rect.height();
+ return monitor;
+ }
+
+ /**
+ * Returns the primary monitor for that device.
+ *
+ * @return the primary monitor
+ *
+ * @since 3.0
+ */
+ public Monitor getPrimaryMonitor() {
+ checkDevice();
+ return createMonitor(QApplication.desktop().primaryScreen());
+ }
+
+ /**
+ * 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;
+ Shell[] result = new Shell[16];
+ for (Widget control : qt2swtControlMap.values()) {
+ if (control != null && control instanceof Shell) {
+ int j = 0;
+ while (j < index) {
+ if (result[j] == control) {
+ break;
+ }
+ j++;
+ }
+ if (j == index) {
+ if (index == result.length) {
+ Shell[] newResult = new Shell[index + 16];
+ System.arraycopy(result, 0, newResult, 0, index);
+ result = newResult;
+ }
+ result[index++] = (Shell) control;
+ }
+ }
+ }
+ if (index == result.length) {
+ return result;
+ }
+ Shell[] newResult = new Shell[index];
+ System.arraycopy(result, 0, newResult, 0, index);
+ return newResult;
+ }
+
+ /**
+ * Gets the synchronizer used by the display.
+ *
+ * @return the receiver's synchronizer
+ *
+ * @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.4
+ */
+ public Synchronizer getSynchronizer() {
+ checkDevice();
+ return synchronizer;
+ }
+
+ /**
+ * 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() {
+ synchronized (Device.class) {
+ if (isDisposed()) {
+ error(SWT.ERROR_DEVICE_DISPOSED);
+ }
+ return synchronizer.syncThread;
+ }
+ }
+
+ /**
+ * 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 a reasonable font for applications to use. On some platforms,
+ * this will match the "default font" or "system font" if such can be found.
+ * This font should not be free'd because it was allocated by the system,
+ * not the application.
+ * <p>
+ * Typically, applications which want the default look should simply not set
+ * the font on the widgets they create. Widgets are always created with the
+ * correct default font for the class of user-interface component they
+ * represent.
+ * </p>
+ *
+ * @return a font
+ *
+ * @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>
+ */
+ @Override
+ public Font getSystemFont() {
+ checkDevice();
+ return systemFont = Font.qt_new(this, new QFont());
+ }
+
+ /**
+ * 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;
+ }
+ QIcon icon = QApplication.style().standardIcon(StandardPixmap.SP_MessageBoxCritical);
+ return errorImage = Image.qt_new(this, SWT.ICON, icon);
+ }
+ case SWT.ICON_WORKING:
+ case SWT.ICON_INFORMATION: {
+ if (infoImage != null) {
+ return infoImage;
+ }
+ QIcon icon = QApplication.style().standardIcon(StandardPixmap.SP_MessageBoxInformation);
+ return errorImage = Image.qt_new(this, SWT.ICON, icon);
+ }
+ case SWT.ICON_QUESTION: {
+ if (questionImage != null) {
+ return questionImage;
+ }
+ QIcon icon = QApplication.style().standardIcon(StandardPixmap.SP_MessageBoxQuestion);
+ return errorImage = Image.qt_new(this, SWT.ICON, icon);
+ }
+ case SWT.ICON_WARNING: {
+ if (warningIcon != null) {
+ return warningIcon;
+ }
+ QIcon icon = QApplication.style().standardIcon(StandardPixmap.SP_MessageBoxWarning);
+ return errorImage = Image.qt_new(this, SWT.ICON, icon);
+ }
+ }
+ 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() {
+ synchronized (Device.class) {
+ 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>
+ */
+ @Override
+ public QPaintDeviceInterface internal_new_GC(GCData data) {
+ if (isDisposed()) {
+ SWT.error(SWT.ERROR_DEVICE_DISPOSED);
+ }
+ return new QPicture();
+ }
+
+ /**
+ * 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
+ */
+ @Override
+ public void internal_dispose_GC(QPaintDeviceInterface paintDevice, GCData data) {
+ // nothing
+ }
+
+ 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);
+ }
+ if (from == to) {
+ return new Point(x, y);
+ }
+
+ Point point = null;
+ if (to != null && from != null) {
+ point = from.toDisplay(x, y);
+ point = to.toControl(x, y);
+ } else if (to != null) {
+ point = to.toControl(x, y);
+ } else if (from != null) {
+ point = from.toDisplay(x, y);
+ } else {
+ point = new Point(x, y);
+ }
+ return point;
+ }
+
+ /**
+ * 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);
+ }
+ if (from == to) {
+ return new Rectangle(x, y, width, height);
+ }
+
+ Rectangle rectangle = new Rectangle(x, y, width, height);
+ if (to != null && from != null) {
+ Point topLeft = from.toDisplay(x, y);
+ topLeft = to.toControl(topLeft);
+ rectangle.x = topLeft.x;
+ rectangle.y = topLeft.y;
+ } else if (to != null) {
+ Point topLeft = to.toControl(x, y);
+ rectangle.x = topLeft.x;
+ rectangle.y = topLeft.y;
+ } else if (from != null) {
+ Point topLeft = from.toDisplay(x, y);
+ rectangle.x = topLeft.x;
+ rectangle.y = topLeft.y;
+ }
+ return rectangle;
+ }
+
+ /**
+ * 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>
+ * <p>
+ * MouseWheel
+ * </p>
+ * <p>
+ * The following fields in the <code>Event</code> apply:
+ * <ul>
+ * <li>(in) type MouseWheel
+ * <li>(in) detail either SWT.SCROLL_LINE or SWT.SCROLL_PAGE
+ * <li>(in) count the number of lines or pages to scroll
+ * </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);
+ }
+
+ QWidget control = getControlForEvent(event);
+ if (control == null) {
+ return false;
+ }
+
+ QEvent qtEvent = createQEvent(event, control);
+ if (event == null) {
+ return false;
+ }
+
+ QApplication.postEvent(control, qtEvent);
+ return true;
+
+ }
+
+ private QWidget getControlForEvent(Event event) {
+ if (event.widget != null) {
+ return event.widget.getQWidget();
+ }
+ return QApplication.focusWidget();
+ }
+
+ private QEvent createQEvent(Event event, QWidget focusWidget) {
+ KeyboardModifiers modifiers = mapSWTModifier2Qt(event.stateMask);
+ Type type = mapSWTEventType2Qt(event.type);
+
+ switch (type) {
+ case KeyPress:
+ case KeyRelease:
+ return createQKeyEvent(event, type, modifiers);
+ case MouseButtonPress:
+ case MouseMove:
+ case MouseButtonRelease:
+ case MouseButtonDblClick:
+ return createQMouseEvent(event, type, modifiers, focusWidget);
+ }
+ return null;
+ }
+
+ private QEvent createQMouseEvent(Event event, Type type, KeyboardModifiers modifiers, QWidget focusWidget) {
+ Control widget = (Control) findControl(focusWidget);
+ if ((widget.getStyle() & SWT.MIRRORED) != 0) {
+ event.x = widget.getClientWidth() - event.x;
+ }
+
+ QPoint eventPoint = new QPoint(event.x, event.y);
+ QPoint global = focusWidget.mapToGlobal(eventPoint);
+ MouseButton button = mapSWTButton2Qt(event.button);
+ if (!type.equals(Type.MouseMove) && button.equals(MouseButton.NoButton)) {
+ return null;
+ }
+ return new QMouseEvent(type, eventPoint, global, button, MouseButton.createQFlags(button), modifiers);
+ }
+
+ private QEvent createQKeyEvent(Event event, Type type, KeyboardModifiers modifiers) {
+ // If neither keyCode nor character is given then abort
+ if (event.keyCode == 0 && event.character == 0) {
+ return null;
+ }
+
+ // Primarily try to map the keyCode to Qt:Key
+ int key = KeyUtil.untranslateKey(event.keyCode);
+ // If keyCode was given in the Event
+ if (event.keyCode != 0) {
+ // Given keyCode couldn't be translated, use it directly
+ if (key == 0) {
+ key = event.keyCode;
+ }
+ }
+
+ // Secondarily if keyCode couldn't be mapped try the character
+ if (key == 0) {
+ switch (event.character) {
+ case SWT.BS:
+ key = Key.Key_Backspace.value();
+ break;
+ case SWT.CR:
+ key = Key.Key_Return.value();
+ break;
+ case SWT.DEL:
+ key = Key.Key_Delete.value();
+ break;
+ case SWT.ESC:
+ key = Key.Key_Escape.value();
+ break;
+ case SWT.TAB:
+ key = Key.Key_Tab.value();
+ 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:
+ return null;
+ default:
+ key = Character.toUpperCase(event.character);
+ break;
+ }
+ }
+ return new QKeyEvent(type, key, modifiers, String.valueOf(event.character));
+ }
+
+ private static KeyboardModifiers mapSWTModifier2Qt(int modifiers) {
+ int nativeModifiers = 0;
+ if ((modifiers & SWT.ALT) != 0) {
+ nativeModifiers |= KeyboardModifier.AltModifier.value();
+ }
+ if ((modifiers & SWT.SHIFT) != 0) {
+ nativeModifiers |= KeyboardModifier.ShiftModifier.value();
+ }
+ if ((modifiers & SWT.CONTROL) != 0) {
+ nativeModifiers |= KeyboardModifier.ControlModifier.value();
+ }
+ return new KeyboardModifiers(nativeModifiers);
+ }
+
+ private static QEvent.Type mapSWTEventType2Qt(int type) {
+ switch (type) {
+ case SWT.KeyDown:
+ return Type.KeyPress;
+ case SWT.KeyUp:
+ return Type.KeyRelease;
+ case SWT.MouseDown:
+ return Type.MouseButtonPress;
+ case SWT.MouseMove:
+ return Type.MouseMove;
+ case SWT.MouseUp:
+ return Type.MouseButtonRelease;
+ case SWT.MouseDoubleClick:
+ return Type.MouseButtonDblClick;
+ default:
+ return Type.None;
+ }
+ }
+
+ private static MouseButton mapSWTButton2Qt(int button) {
+ switch (button) {
+ case 1:
+ return MouseButton.LeftButton;
+ case 2:
+ return MouseButton.MidButton;
+ case 3:
+ return MouseButton.RightButton;
+ default:
+ return MouseButton.NoButton;
+ }
+ }
+
+ 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;
+ }
+
+ /**
+ * 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();
+ // runPopups();
+ // boolean canSleep = runAsyncMessages(false);
+ // if (!canSleep) {
+ // QApplication.processEvents();
+ // }
+ // return canSleep;
+
+ if (QApplication.hasPendingEvents()) {
+ QApplication.processEvents();//ProcessEventsFlag.AllEvents
+ if (isDisposed()) {
+ return false;
+ }
+ QApplication.sendPostedEvents();
+ }
+ if (isDisposed()) {
+ return false;
+ }
+
+ runDeferredEvents();
+
+ if (isDisposed()) {
+ return false;
+ }
+
+ runPopups();
+
+ if (isDisposed()) {
+ return false;
+ }
+
+ return runAsyncMessages(false);
+ }
+
+ private static void register(Display display) {
+ synchronized (Device.class) {
+ 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
+ */
+ @Override
+ 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;
+ 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();
+ }
+
+ private void releaseDisplay() {
+ /* Release the System fonts */
+ if (systemFont != null) {
+ systemFont.dispose();
+ }
+ systemFont = 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 references */
+ thread = null;
+ modalDialog = null;
+ modalShells = null;
+ data = null;
+ keys = null;
+ values = null;
+ bars = popups = null;
+ timerIds = null;
+ timerList = null;
+ eventTable = filterTable = null;
+ items = null;
+
+ /* Release handles */
+ threadId = 0;
+ QApplication.quit();
+ }
+
+ /**
+ * 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
+ *
+ * @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);
+ }
+
+ void removeBar(Menu menu) {
+ if (bars == null) {
+ return;
+ }
+ for (int i = 0; i < bars.length; i++) {
+ if (bars[i] == menu) {
+ bars[i] = null;
+ return;
+ }
+ }
+ }
+
+ void removeMenuItem(MenuItem item) {
+ if (items == null) {
+ return;
+ }
+ items[item.id - ID_START] = null;
+ }
+
+ void removePopup(Menu menu) {
+ if (popups == null) {
+ return;
+ }
+ for (int i = 0; i < popups.length; i++) {
+ if (popups[i] == menu) {
+ popups[i] = null;
+ return;
+ }
+ }
+ }
+
+ private boolean runAsyncMessages(boolean all) {
+ return synchronizer.runAsyncMessages(all);
+ }
+
+ private boolean runDeferredEvents() {
+ boolean run = false;
+ /*
+ * 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()) {
+ run = true;
+ widget.sendEvent(event);
+ }
+ }
+
+ /*
+ * At this point, the event queue could be null due to a recursive
+ * invocation when running the event.
+ */
+ }
+
+ /* Clear the queue */
+ eventQueue = null;
+ return run;
+ }
+
+ private 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;
+ if (!menu.isDisposed()) {
+ menu._setVisible(true);
+ }
+ result = true;
+ }
+ popups = null;
+ return result;
+ }
+
+ private boolean runTimer(int /* long */id) {
+ if (timerList != null && timerIds != null) {
+ int index = 0;
+ while (index < timerIds.length) {
+ if (timerIds[index] == id && timerIds[index] != -1) {
+ timer.killTimer(timerIds[index]);
+ timerIds[index] = 0;
+ Runnable runnable = timerList[index];
+ timerList[index] = null;
+ if (runnable != null) {
+ runnable.run();
+ }
+ return true;
+ }
+ index++;
+ }
+ }
+ return false;
+ }
+
+ private 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();
+ QCursor.setPos(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 (SWQT.STYLESHEET_KEY.equals(key)) {
+ setStyleSheet((String) value);
+ }
+
+ /* 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) {
+ QApplication.setApplicationName(name);
+ }
+
+ void setModalDialog(Dialog modalDailog) {
+ this.modalDialog = 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 (synchronizer == this.synchronizer) {
+ return;
+ }
+ Synchronizer oldSynchronizer;
+ synchronized (Device.class) {
+ oldSynchronizer = this.synchronizer;
+ this.synchronizer = synchronizer;
+ }
+ if (oldSynchronizer != null) {
+ oldSynchronizer.runAsyncMessages(true);
+ }
+ }
+
+ /**
+ * 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();
+ if (getMessageCount() != 0) {
+ return true;
+ }
+
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ // awake
+ }
+ QApplication.processEvents(PROCESS_EVENTS_FLAGS, 1000);
+
+ if (isDisposed()) {
+ destroy();
+ }
+ return true;
+ }
+
+ /**
+ * 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 occurred when
+ * executing the runnable</li>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been
+ * disposed</li>
+ * </ul>
+ *
+ * @see #asyncExec
+ */
+ public void syncExec(Runnable runnable) {
+ Synchronizer synchronizer;
+ synchronized (Device.class) {
+ if (isDisposed()) {
+ error(SWT.ERROR_DEVICE_DISPOSED);
+ }
+ synchronizer = this.synchronizer;
+ }
+ 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();
+ timer = new QTimer();
+
+ if (runnable == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (timerList == null) {
+ timerList = new Runnable[4];
+ }
+ if (timerIds == null) {
+ timerIds = new int /* long */[4];
+ }
+ int index = 0;
+ while (index < timerList.length) {
+ if (timerList[index] == runnable) {
+ break;
+ }
+ index++;
+ }
+ int /* long */timerId = 0;
+ if (index != timerList.length) {
+ timerId = timerIds[index];
+ if (milliseconds < 0) {
+ timer.killTimer(timerId);
+ timerList[index] = null;
+ timerIds[index] = 0;
+ return;
+ }
+ } else {
+ if (milliseconds < 0) {
+ return;
+ }
+ index = 0;
+ while (index < timerList.length) {
+ if (timerList[index] == null) {
+ break;
+ }
+ index++;
+ }
+ timerId = nextTimerId++;
+ if (index == timerList.length) {
+ Runnable[] newTimerList = new Runnable[timerList.length + 4];
+ System.arraycopy(timerList, 0, newTimerList, 0, timerList.length);
+ timerList = newTimerList;
+ int /* long */[] newTimerIds = new int /* long */[timerIds.length + 4];
+ System.arraycopy(timerIds, 0, newTimerIds, 0, timerIds.length);
+ timerIds = newTimerIds;
+ }
+ }
+
+ timer.setSingleShot(false);
+ timer.start(milliseconds);
+ final QTimerEvent qte = new QTimerEvent(timer.timerId());
+ timer.timeout.connect(new QObject() {
+ private int id = qte.timerId();
+
+ @SuppressWarnings("unused")
+ protected void idTransfer() {
+ runTimer(id);
+ }
+ }, "idTransfer()"); //$NON-NLS-1$
+ timerList[index] = runnable;
+ timerIds[index] = timer.timerId();
+ }
+
+ /**
+ * 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();
+ if (QApplication.hasPendingEvents()) {
+ QApplication.processEvents(QEventLoop.ProcessEventsFlag.ExcludeUserInputEvents);
+ }
+ }
+
+ /**
+ * 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() {
+ synchronized (Device.class) {
+ if (isDisposed()) {
+ error(SWT.ERROR_DEVICE_DISPOSED);
+ }
+ if (thread == Thread.currentThread()) {
+ return;
+ }
+ wakeThread();
+ }
+ }
+
+ void wakeThread() {
+ try {
+ thread.notify();
+ } catch (Exception e) {
+ // ok
+ }
+ }
+
+ static String withCrLf(String string) {
+
+ /* If the string is empty, return the string. */
+ int length = string.length();
+ if (length == 0) {
+ return string;
+ }
+
+ /*
+ * Check for an LF or CR/LF and assume the rest of the string is
+ * formated that way. This will not work if the string contains mixed
+ * delimiters.
+ */
+ int i = string.indexOf('\n', 0);
+ if (i == -1) {
+ return string;
+ }
+ if (i > 0 && string.charAt(i - 1) == '\r') {
+ return string;
+ }
+
+ /*
+ * The string is formatted with LF. Compute the number of lines and the
+ * size of the buffer needed to hold the result
+ */
+ i++;
+ int count = 1;
+ while (i < length) {
+ if ((i = string.indexOf('\n', i)) == -1) {
+ break;
+ }
+ count++;
+ i++;
+ }
+ count += length;
+
+ /* Create a new string with the CR/LF line terminator. */
+ i = 0;
+ StringBuffer result = new StringBuffer(count);
+ while (i < length) {
+ int j = string.indexOf('\n', i);
+ if (j == -1) {
+ j = length;
+ }
+ result.append(string.substring(i, j));
+ if ((i = j) < length) {
+ result.append("\r\n"); //$NON-NLS-1$
+ i++;
+ }
+ }
+ return result.toString();
+ }
+
+ private final class MasterEventFilter extends QObject {
+ private final Display display;
+ private final boolean printEvents = Boolean.getBoolean("swtqt.printEvents"); //$NON-NLS-1$
+
+ public MasterEventFilter(Display display) {
+ this.display = display;
+ }
+
+ @Override
+ public boolean eventFilter(QObject obj, QEvent event) {
+ try {
+ if (printEvents) {
+ System.out.println("QObject: " + (obj == null ? "null" : obj.toString()) + ": " + event.toString()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ lastEventTime = QTime.currentTime().elapsed();
+ Widget eventSource = display.findControl(obj);
+ if (eventSource == null) {
+ // if (event.type() == Type.Paint) {
+ // System.out.println("paint event for qObj: " + obj + " unknown swt source"); //$NON-NLS-1$ //$NON-NLS-2$
+ // }
+ if (printEvents) {
+ System.err.println("unknown event source: " + obj + " parent: " //$NON-NLS-1$ //$NON-NLS-2$
+ + (obj == null ? "null" : obj.parent())); //$NON-NLS-1$
+ }
+ return false;
+ }
+ switch (event.type()) {
+ case Paint:
+ if (printEvents) {
+ System.out.println("paint event for qObj: " + obj + " swt: " + eventSource); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ if (ignorePaintEvents) {
+ return false;
+ }
+ return eventSource.qtPaintEvent(obj, (QPaintEvent) event);
+ case Resize:
+ return eventSource.qtResizeEvent(obj, (QResizeEvent) event);
+ case Move:
+ return eventSource.qtMoveEvent(obj, (QMoveEvent) event);
+ case FocusIn:
+ eventSource.qtFocusInEvent(obj);
+ return false;
+ case FocusOut:
+ eventSource.qtFocusOutEvent(obj);
+ return false;
+ case ContextMenu: {
+ QContextMenuEvent contextEvent = (QContextMenuEvent) event;
+ boolean accepted = eventSource.qtContextMenuEvent(obj, contextEvent);
+ if (accepted) {
+ contextEvent.setAccepted(true);
+ }
+ return accepted;
+ }
+ case Close:
+ QCloseEvent closeEvent = (QCloseEvent) event;
+ boolean accepted = eventSource.qtCloseEvent();
+ if (accepted) {
+ closeEvent.ignore();
+ }
+ return accepted;
+ case Enter:
+ return eventSource.qtMouseEnterEvent(obj);
+ case Leave:
+ return eventSource.qtMouseLeaveEvent(obj);
+ case Show:
+ return eventSource.qtShowEvent(obj);
+ case Hide:
+ return eventSource.qtHideEvent(obj);
+ case MouseMove:
+ return eventSource.qtMouseMoveEvent(obj, (QMouseEvent) event);
+ case MouseButtonPress:
+ QMouseEvent mouseEvent = (QMouseEvent) event;
+ // for debug
+ // QWidget widget = QApplication.widgetAt(mouseEvent.globalX(), mouseEvent.globalY());
+ // System.out.println("mouse click on: " + widget);
+ // System.out.println("mouse click on swt widget: " + display.findControl(widget));
+ return eventSource.qtMouseButtonPressEvent(obj, mouseEvent);
+ case MouseButtonRelease:
+ return eventSource.qtMouseButtonReleaseEvent(obj, (QMouseEvent) event);
+ case MouseButtonDblClick:
+ return eventSource.qtMouseButtonDblClickEvent(obj, (QMouseEvent) event);
+ case KeyPress:
+ return eventSource.qtKeyPressEvent(obj, (QKeyEvent) event);
+ case KeyRelease:
+ return eventSource.qtKeyReleaseEvent(obj, (QKeyEvent) event);
+ case WindowActivate:
+ return eventSource.qtWindowActivateEvent(obj);
+ case WindowDeactivate:
+ return eventSource.qtWindowDeactivateEvent(obj);
+ case WindowStateChange:
+ return eventSource.qtWindowStateChangeEvent(obj, (QWindowStateChangeEvent) event);
+ case WinEventAct:
+ return false;
+ case Timer:
+ return false;
+ default:
+ if (printEvents) {
+ System.err.println("unhandled event: " + event); //$NON-NLS-1$
+ }
+ }
+ } catch (Exception e) {
+ System.err.println("error during event processing:"); //$NON-NLS-1$
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ }
+
+ private final static class SwtMessageHandler extends QMessageHandler {
+
+ @Override
+ public void warning(String msg) {
+ System.err.println("Qt-Warning: " + msg); //$NON-NLS-1$
+ }
+
+ @Override
+ public void fatal(String msg) {
+ System.err.println("Qt-Fatal: " + msg); //$NON-NLS-1$
+ }
+
+ @Override
+ public void debug(String msg) {
+ System.err.println("Qt-Debug: " + msg); //$NON-NLS-1$
+ }
+
+ @Override
+ public void critical(String msg) {
+ System.err.println("Qt-Critical: " + msg); //$NON-NLS-1$
+ }
+ };
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/FileDialog.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/FileDialog.java
new file mode 100644
index 0000000000..f199d3626e
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/FileDialog.java
@@ -0,0 +1,443 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.trolltech.qt.gui.QFileDialog;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#filedialog">FileDialog
+ * snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample, Dialog tab</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class FileDialog extends Dialog {
+ String[] filterNames = new String[0];
+ String[] filterExtensions = new String[0];
+ String[] fileNames = new String[0];
+ String filterPath = "", fileName = "";//$NON-NLS-1$ //$NON-NLS-2$
+ int filterIndex = 0;
+ boolean overwrite = false;
+ static final String FILTER = "*.*";//$NON-NLS-1$
+ QFileDialog fd;
+
+ /**
+ * 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.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.
+ * </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, checkStyle(parent, style));
+ checkSubclass();
+ fd = new QFileDialog();
+ if ((style & SWT.SAVE) != 0) {
+ fd.setFileMode(QFileDialog.FileMode.AnyFile);
+ } else if ((style & SWT.MULTI) != 0) {
+ fd.setFileMode(QFileDialog.FileMode.ExistingFiles);
+ } else {
+ fd.setFileMode(QFileDialog.FileMode.ExistingFile);
+ }
+ }
+
+ /**
+ * 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() {
+ String[] files = getSplittedFileNames();
+ if (files.length == 1) {
+ return files[0];
+ } else {
+ return ""; //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * 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 getSplittedFileNames();
+ }
+
+ private String[] getSplittedFileNames() {
+ String[] split = { null, null };
+ List<String> files = fd.selectedFiles();
+
+ if (!files.isEmpty()) {
+ for (int i = 0; i < files.size(); i++) {
+ String file = files.get(i);
+ split = file.split("/"); //$NON-NLS-1$
+
+ if (split != null) {
+ files.set(i, split[split.length - 1]);
+ }
+ }
+ }
+ return files.toArray(new String[] {});
+ }
+
+ /**
+ * Returns the file extensions which the dialog will use to filter the files
+ * it shows.
+ *
+ * @return the file extensions filter
+ */
+ @SuppressWarnings("nls")
+ public String[] getFilterExtensions() {
+ List<String> filters = fd.nameFilters();
+ ArrayList<String> result = new ArrayList<String>();
+ String[] split1 = null;
+ String[] split2 = null;
+ /*
+ * just get the extensions out of the nameFilters, not the names (split
+ * between "(" and ")"
+ */
+ for (String filter : filters) {
+ split1 = filter.split("\\(");
+ split2 = split1[1].split("\\)");
+ result.add(split2[0]);
+ }
+
+ /*
+ * replace all " " by ";" because that's the way swt returns the
+ * extensions
+ */
+ for (String r : result) {
+ r = r.replaceAll(" ", ";");
+ }
+
+ return result.toArray(new String[] {});
+ }
+
+ /**
+ * Get the 0-based index of the file extension filter which was selected by
+ * the user, or -1 if no filter was selected.
+ * <p>
+ * This is an index into the FilterExtensions array and the FilterNames
+ * array.
+ * </p>
+ *
+ * @return index the file extension filter index
+ *
+ * @see #getFilterExtensions
+ * @see #getFilterNames
+ *
+ * @since 3.4
+ */
+ public int getFilterIndex() {
+ //TODO see Bug 166
+ return filterIndex;
+ }
+
+ /**
+ * 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
+ */
+ @SuppressWarnings("nls")
+ public String[] getFilterNames() {
+ List<String> filters = fd.nameFilters();
+ ArrayList<String> result = new ArrayList<String>();
+ String[] name = null;
+
+ /*
+ * just get the names out of the nameFilters, not the extensions(split
+ * between "("
+ */
+ for (String filter : filters) {
+ name = filter.split("\\(");
+ result.add(name[0]);
+ }
+
+ return result.toArray(new String[] {});
+ }
+
+ /**
+ * 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 fd.directory().path();
+ }
+
+ /**
+ * Returns the flag that the dialog will use to determine whether to prompt
+ * the user for file overwrite if the selected file already exists.
+ *
+ * @return true if the dialog will prompt for file overwrite, false
+ * otherwise
+ *
+ * @since 3.4
+ */
+ public boolean getOverwrite() {
+ return fd.confirmOverwrite();
+ }
+
+ /**
+ * 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() {
+ fd.exec();
+ java.util.List<String> files = fd.selectedFiles();
+ fileName = null;
+ fileNames = new String[files.size()];
+ if (files.size() > 0) {
+ fileNames[0] = fileName = files.get(0);
+ }
+ for (int i = 1; i < files.size(); i++) {
+ fileNames[i] = files.get(i);
+ }
+ fd.disposeLater();
+ return fileName;
+ }
+
+ /**
+ * 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) {
+ fd.selectFile(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 some platforms, an
+ * extension filter string is typically of the form "*.extension", where
+ * "*.*" matches all files. For filters with multiple extensions, use
+ * semicolon as a separator, e.g. "*.jpg;*.png".
+ * </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;
+ makeFilter();
+
+ }
+
+ /**
+ * Set the 0-based index of the file extension filter which the dialog will
+ * use initially to filter the files it shows to the argument.
+ * <p>
+ * This is an index into the FilterExtensions array and the FilterNames
+ * array.
+ * </p>
+ *
+ * @param index
+ * the file extension filter index
+ *
+ * @see #setFilterExtensions
+ * @see #setFilterNames
+ *
+ * @since 3.4
+ */
+ public void setFilterIndex(int index) {
+ //TODO see Bug 166
+ filterIndex = index;
+ }
+
+ /**
+ * Sets 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;
+ makeFilter();
+ }
+
+ /**
+ * constructs a filter for the fileDialog like this:
+ * "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"
+ *
+ * @param names
+ * @return
+ */
+ private void makeFilter() {
+ java.util.ArrayList<String> filters = new java.util.ArrayList<String>();
+
+ if (filterNames.length == 0 && filterExtensions.length == 0) {
+ // nothing to do
+ } else {
+ /*
+ * If there are more filterNames than filterExtensions, just use as
+ * much filterNames as FilterExtensions.length. Ignore the rest.
+ */
+ for (int i = 0; i < filterExtensions.length; i++) {
+ if (filterNames.length >= i + 1) {
+ /*
+ * If there's a matching filterName for the
+ * filterExtension-Field, the filterExtension-Field has to
+ * get rid of the ";". The ";" are only allowed, when the
+ * filterExtension hasn't a matching name.
+ */
+ String ex = filterExtensions[i].replace(";", " "); //$NON-NLS-1$ //$NON-NLS-2$
+ filters.add(filterNames[i] + "(" + ex + ")"); //$NON-NLS-1$//$NON-NLS-2$
+
+ } else {
+ /*
+ * just a filterExtension without a name
+ */
+ filters.add(filterExtensions[i]);
+ }
+ }
+
+ fd.setNameFilters(filters);
+ }
+ }
+
+ /**
+ * 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) {
+ fd.setDirectory(string);
+ }
+
+ /**
+ * Sets the flag that the dialog will use to determine whether to prompt the
+ * user for file overwrite if the selected file already exists.
+ *
+ * @param overwrite
+ * true if the dialog will prompt for file overwrite, false
+ * otherwise
+ *
+ * @since 3.4
+ */
+ public void setOverwrite(boolean overwrite) {
+ fd.setConfirmOverwrite(overwrite);
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/FontDialog.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/FontDialog.java
new file mode 100644
index 0000000000..43563ebb4f
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/FontDialog.java
@@ -0,0 +1,246 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.gui.QDialog;
+import com.trolltech.qt.gui.QFont;
+import com.trolltech.qt.gui.QFontDialog;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.PaletteData;
+import org.eclipse.swt.graphics.RGB;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample, Dialog tab</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class FontDialog extends Dialog {
+ FontData fontData;
+ RGB rgb;
+ QFontDialog fd;
+
+ /**
+ * 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.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.
+ * </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, checkStyle(parent, style));
+ checkSubclass();
+ }
+
+ protected QFontDialog createFontDialog(Shell parent, int style) {
+ return new QFontDialog();
+ }
+
+ /**
+ * 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 ()
+ */
+ @Deprecated
+ public FontData getFontData() {
+ return getFontList()[0];
+ }
+
+ /**
+ * 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() {
+ QFont font = fd.selectedFont();
+ if (font == null) {
+ return null;
+ }
+ FontData[] result = new FontData[1];
+ result[0] = qFontToFontData(font);
+ return result;
+ }
+
+ private FontData qFontToFontData(QFont qFont) {
+ int style = SWT.NORMAL;
+ if (qFont.italic()) {
+ style += SWT.ITALIC;
+ }
+ if (qFont.bold()) {
+ style += SWT.BOLD;
+ }
+ FontData fontData = new FontData(qFont.rawName(), qFont.pointSize(), style);
+ return fontData;
+ }
+
+ /**
+ * 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() {
+ // QFontDialog doesn't support setting a font color, see Bug 167
+ return null;
+ }
+
+ /**
+ * 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() {
+ fd = new QFontDialog();
+ if (fd.exec() == QDialog.DialogCode.Rejected.value()) {
+ return null;
+ }
+ QFont font = fd.selectedFont();
+
+ FontData fontData = qFontToFontData(font);
+ font.dispose();
+ fd.disposeLater();
+ return fontData;
+ }
+
+ /**
+ * 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 [])
+ */
+ @Deprecated
+ public void setFontData(FontData fontData) {
+ // QFontDialog doesn't support setting the default font
+ 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) {
+ // QFontDialog doesn't support setting the default font, see Bug 168
+ 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) {
+ // QFontDialog doesn't support setting a font color, see Bug 167
+ this.rgb = rgb;
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Group.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Group.java
new file mode 100644
index 0000000000..9af907e13e
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Group.java
@@ -0,0 +1,293 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.gui.QContentsMargins;
+import com.trolltech.qt.gui.QGroupBox;
+import com.trolltech.qt.gui.QWidget;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.internal.qt.QtSWTConverter;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public class Group extends 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 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));
+ }
+
+ @Override
+ protected QWidget createQWidget(int style) {
+ state |= DRAW_BACKGROUND;
+ state |= CANVAS;
+ //TODO apply SWT.SHADOW_* styles
+ return new QGroupBox();
+ }
+
+ QGroupBox getQGroupBox() {
+ return (QGroupBox) getQWidget();
+ }
+
+ 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);
+ }
+
+ @Override
+ protected void checkSubclass() {
+ if (!isValidSubclass()) {
+ error(SWT.ERROR_INVALID_SUBCLASS);
+ }
+ }
+
+ @Override
+ public Rectangle getClientArea() {
+ checkWidget();
+ if (!isVisible()) {
+ updateQLayouts();
+ }
+
+ Rectangle clientArea = QtSWTConverter.convert(getQWidget().contentsRect());
+ if (clientArea.width < 0) {
+ clientArea.width = 0;
+ }
+ if (clientArea.height < 0) {
+ clientArea.height = 0;
+ }
+
+ return clientArea;
+ }
+
+ @Override
+ public Rectangle computeTrim(int x, int y, int width, int height) {
+ QContentsMargins margins = getQGroupBox().getContentsMargins();
+ return new Rectangle(x - margins.left, y - margins.top, width + margins.left + margins.right, height
+ + margins.top + margins.bottom);
+ }
+
+ @Override
+ 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 getQGroupBox().title();
+ }
+
+ @Override
+ boolean mnemonicHit(char key) {
+ return setFocus();
+ }
+
+ @Override
+ boolean mnemonicMatch(char key) {
+ char mnemonic = findMnemonic(getText());
+ if (mnemonic == '\0') {
+ return false;
+ }
+ return Character.toUpperCase(key) == Character.toUpperCase(mnemonic);
+ }
+
+ void printWidget(int /* long */hwnd, int /* long */hdc, GC gc) {
+ // TODO
+ throw new UnsupportedOperationException("not yet implemented");//$NON-NLS-1$
+ // /*
+ // * Bug in Windows. For some reason, PrintWindow() returns success but
+ // * does nothing when it is called on a printer. The fix is to just go
+ // * directly to WM_PRINT in this case.
+ // */
+ // boolean success = false;
+ // if ( !( OS.GetDeviceCaps( gc.handle, OS.TECHNOLOGY ) ==
+ // OS.DT_RASPRINTER ) ) {
+ // success = OS.PrintWindow( hwnd, hdc, 0 );
+ // }
+ //
+ // /*
+ // * Bug in Windows. For some reason, PrintWindow() fails when it is
+ // * called on a push button. The fix is to detect the failure and use
+ // * WM_PRINT instead. Note that WM_PRINT cannot be used all the time
+ // * because it fails for browser controls when the browser has focus.
+ // */
+ // if ( !success ) {
+ // /*
+ // * Bug in Windows. For some reason, WM_PRINT when called with
+ // * PRF_CHILDREN will not draw the tool bar divider for tool bar
+ // * children that do not have CCS_NODIVIDER. The fix is to draw the
+ // * group box and iterate through the children, drawing each one.
+ // */
+ // int flags = OS.PRF_CLIENT | OS.PRF_NONCLIENT | OS.PRF_ERASEBKGND;
+ // OS.SendMessage( hwnd, OS.WM_PRINT, hdc, flags );
+ // int nSavedDC = OS.SaveDC( hdc );
+ // Control[] children = _getChildren();
+ // Rectangle rect = getBounds();
+ // OS.IntersectClipRect( hdc, 0, 0, rect.width, rect.height );
+ // for ( int i = children.length - 1; i >= 0; --i ) {
+ // Point location = children[i].getLocation();
+ // int graphicsMode = OS.GetGraphicsMode( hdc );
+ // if ( graphicsMode == OS.GM_ADVANCED ) {
+ // float[] lpXform = { 1, 0, 0, 1, location.x, location.y };
+ // OS.ModifyWorldTransform( hdc, lpXform, OS.MWT_LEFTMULTIPLY );
+ // } else {
+ // OS.SetWindowOrgEx( hdc, -location.x, -location.y, null );
+ // }
+ // int /* long */topHandle = children[i].topHandle();
+ // int bits = OS.GetWindowLong( topHandle, OS.GWL_STYLE );
+ // if ( ( bits & OS.WS_VISIBLE ) == 0 ) {
+ // OS.DefWindowProc( topHandle, OS.WM_SETREDRAW, 1, 0 );
+ // }
+ // children[i].printWidget( topHandle, hdc, gc );
+ // if ( ( bits & OS.WS_VISIBLE ) == 0 ) {
+ // OS.DefWindowProc( topHandle, OS.WM_SETREDRAW, 0, 0 );
+ // }
+ // if ( graphicsMode == OS.GM_ADVANCED ) {
+ // float[] lpXform = { 1, 0, 0, 1, -location.x, -location.y };
+ // OS.ModifyWorldTransform( hdc, lpXform, OS.MWT_LEFTMULTIPLY );
+ // }
+ // }
+ // OS.RestoreDC( hdc, nSavedDC );
+ // }
+ }
+
+ @Override
+ public void setFont(Font font) {
+ checkWidget();
+ Rectangle oldRect = getClientArea();
+ super.setFont(font);
+ Rectangle newRect = getClientArea();
+ if (!oldRect.equals(newRect)) {
+ sendResize();
+ }
+ }
+
+ /**
+ * 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);
+ }
+ getQGroupBox().setTitle(string);
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Label.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Label.java
new file mode 100644
index 0000000000..1274dabea4
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Label.java
@@ -0,0 +1,456 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.core.Qt.AlignmentFlag;
+import com.trolltech.qt.gui.QDragEnterEvent;
+import com.trolltech.qt.gui.QDragLeaveEvent;
+import com.trolltech.qt.gui.QDragMoveEvent;
+import com.trolltech.qt.gui.QDropEvent;
+import com.trolltech.qt.gui.QFrame;
+import com.trolltech.qt.gui.QLabel;
+import com.trolltech.qt.gui.QMouseEvent;
+import com.trolltech.qt.gui.QWidget;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * 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.
+ * <p>
+ * Shadow styles are hints and may not be honored by the platform. To create a
+ * separator label with the default shadow style for the platform, do not
+ * specify a shadow style.
+ * </p>
+ * <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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#label">Label snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class Label extends Control {
+ private String text = ""; //$NON-NLS-1$
+ private 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));
+ }
+
+ @Override
+ protected QWidget createQWidget(int style) {
+ state |= THEME_BACKGROUND;
+ QLabel label = new MyQLabel();
+ if ((style & SWT.SEPARATOR) != 0) {
+ setSeparatorType(label, style);
+ }
+ label.setContentsMargins(0, 0, 0, 0);
+ setAlignment(label, style);
+ label.setMargin(0);
+ // TODO make this work with the right size.
+ //label.setWordWrap((style & SWT.WRAP) != 0);
+ return label;
+ }
+
+ @Override
+ protected void checkAndUpdateBorder() {
+ // nothing on purpose
+ }
+
+ private void setSeparatorType(QLabel label, int style) {
+ int frameStyle = 0;
+ if ((style & SWT.VERTICAL) != 0) {
+ frameStyle |= QFrame.Shape.VLine.value();
+ label.setFixedWidth(2);
+ } else {
+ frameStyle |= QFrame.Shape.HLine.value();
+ label.setMaximumHeight(2);
+ }
+ if ((style & SWT.SHADOW_IN) != 0) {
+ frameStyle |= QFrame.Shadow.Raised.value();
+ } else if ((style & SWT.SHADOW_OUT) != 0) {
+ frameStyle |= QFrame.Shadow.Sunken.value();
+ } else if ((style & SWT.SHADOW_NONE) != 0) {
+ frameStyle |= QFrame.Shadow.Plain.value();
+ }
+ label.setFrameStyle(frameStyle);
+ }
+
+ private QLabel getQLabel() {
+ return (QLabel) getQWidget();
+ }
+
+ 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);
+ }
+
+ @Override
+ public boolean qtMouseEnterEvent(Object source) {
+ if (source == getQWidget()) {
+ sendEvent(SWT.MouseEnter);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean qtMouseLeaveEvent(Object source) {
+ if (source == getQWidget()) {
+ sendEvent(SWT.MouseExit);
+ }
+ return false;
+ }
+
+ @Override
+ public Point computeSize(int wHint, int hHint, boolean changed) {
+ Point p = super.computeSize(wHint, hHint, changed);
+ if ((style & SWT.SEPARATOR) != 0) {
+ int width = p.x;
+ int height = p.y;
+ if ((style & SWT.VERTICAL) != 0) {
+ width = 2;
+ } else {
+ height = Math.min(height, 3);
+ }
+ p.x = width;
+ p.y = height;
+ }
+ return p;
+ }
+
+ @Override
+ 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 "";//$NON-NLS-1$
+ }
+ return text;
+ }
+
+ /**
+ * 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;
+ string = Display.withCrLf(string);
+ getQLabel().setText(string);
+ }
+
+ @Override
+ boolean mnemonicHit(char key) {
+ Composite control = this.parent;
+ while (control != null) {
+ Control[] children = control._getChildren();
+ int index = 0;
+ while (index < children.length) {
+ if (children[index] == this) {
+ break;
+ }
+ index++;
+ }
+ index++;
+ if (index < children.length) {
+ if (children[index].setFocus()) {
+ return true;
+ }
+ }
+ control = control.parent;
+ }
+ return false;
+ }
+
+ @Override
+ boolean mnemonicMatch(char key) {
+ char mnemonic = findMnemonic(getText());
+ if (mnemonic == '\0') {
+ return false;
+ }
+ return Character.toUpperCase(key) == Character.toUpperCase(mnemonic);
+ }
+
+ @Override
+ void releaseWidget() {
+ super.releaseWidget();
+ text = null;
+ image = null;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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();
+ setAlignment(getQLabel(), alignment);
+ }
+
+ void setAlignment(QLabel label, int alignment) {
+ if ((getStyle() & SWT.SEPARATOR) != 0) {
+ return;
+ }
+ if ((alignment & SWT.RIGHT) != 0) {
+ label.setAlignment(AlignmentFlag.AlignRight);
+ } else if ((alignment & SWT.CENTER) != 0) {
+ label.setAlignment(AlignmentFlag.AlignCenter);
+ }
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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();
+ // dont crash if the image is null
+ if (image == null) {
+ return;
+ }
+ this.image = image;
+ getQLabel().setPixmap(image.getQPixmap());
+ }
+
+ private final class MyQLabel extends QLabel {
+ @Override
+ protected void mousePressEvent(QMouseEvent e) {
+ super.mousePressEvent(e);
+ e.setAccepted(false);
+ }
+
+ @Override
+ protected void dropEvent(QDropEvent event) {
+ sendDropEvent(event);
+ }
+
+ @Override
+ protected void dragMoveEvent(QDragMoveEvent event) {
+ sendDragMoveEvent(event);
+ }
+
+ @Override
+ protected void dragEnterEvent(QDragEnterEvent event) {
+ sendDragEnterEvent(event);
+ }
+
+ @Override
+ protected void dragLeaveEvent(QDragLeaveEvent event) {
+ sendDragLeaveEvent(event);
+ }
+
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Link.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Link.java
new file mode 100644
index 0000000000..844a4371f5
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Link.java
@@ -0,0 +1,552 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.core.Qt.TextInteractionFlag;
+import com.trolltech.qt.gui.QLabel;
+import com.trolltech.qt.gui.QWidget;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.accessibility.ACC;
+import org.eclipse.swt.accessibility.Accessible;
+import org.eclipse.swt.accessibility.AccessibleAdapter;
+import org.eclipse.swt.accessibility.AccessibleControlAdapter;
+import org.eclipse.swt.accessibility.AccessibleControlEvent;
+import org.eclipse.swt.accessibility.AccessibleEvent;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#link">Link snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ *
+ * @since 3.1
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class Link extends Control {
+ private Point[] offsets;
+ private String[] ids;
+ private int[] mnemonics;
+
+ private static final String LINK_START = "<a>";//$NON-NLS-1$
+ private static final String LINK_END = "</a>";//$NON-NLS-1$
+
+ /**
+ * 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, checkBits(style, SWT.LEFT, SWT.CENTER, SWT.RIGHT, 0, 0, 0));
+ }
+
+ @Override
+ protected QWidget createQWidget(int style) {
+ state |= THEME_BACKGROUND;
+ QLabel link = new QLabel();
+ link.setTextInteractionFlags(TextInteractionFlag.TextBrowserInteraction);
+ link.setOpenExternalLinks(false);
+ return link;
+ }
+
+ protected QLabel getQLabel() {
+ return (QLabel) getQWidget();
+ }
+
+ @Override
+ protected void connectSignals() {
+ getQLabel().linkActivated.connect(this, "linkActivated(java.lang.String)");//$NON-NLS-1$
+ }
+
+ protected void linkActivated(String link) {
+ Event event = new Event();
+ event.text = link;
+ sendEvent(SWT.Selection, event);
+ }
+
+ /**
+ * Adds the listener to the collection of listeners who will be notified
+ * when the control is selected by the user, 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 by the
+ * user. <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);
+ }
+
+ void initAccessible() {
+ Accessible accessible = getAccessible();
+ accessible.addAccessibleListener(new AccessibleAdapter() {
+ @Override
+ public void getName(AccessibleEvent e) {
+ e.result = parse(_getText());
+ }
+ });
+
+ accessible.addAccessibleControlListener(new AccessibleControlAdapter() {
+ @Override
+ public void getChildAtPoint(AccessibleControlEvent e) {
+ e.childID = ACC.CHILDID_SELF;
+ }
+
+ @Override
+ public void getLocation(AccessibleControlEvent e) {
+ Rectangle rect = display.map(getParent(), null, getBounds());
+ e.x = rect.x;
+ e.y = rect.y;
+ e.width = rect.width;
+ e.height = rect.height;
+ }
+
+ @Override
+ public void getChildCount(AccessibleControlEvent e) {
+ e.detail = 0;
+ }
+
+ @Override
+ public void getRole(AccessibleControlEvent e) {
+ e.detail = ACC.ROLE_LINK;
+ }
+
+ @Override
+ public void getState(AccessibleControlEvent e) {
+ e.detail = ACC.STATE_FOCUSABLE;
+ if (hasFocus()) {
+ e.detail |= ACC.STATE_FOCUSED;
+ }
+ }
+
+ @Override
+ public void getDefaultAction(AccessibleControlEvent e) {
+ e.result = SWT.getMessage("SWT_Press"); //$NON-NLS-1$
+ }
+
+ @Override
+ public void getSelection(AccessibleControlEvent e) {
+ if (hasFocus()) {
+ e.childID = ACC.CHILDID_SELF;
+ }
+ }
+
+ @Override
+ public void getFocus(AccessibleControlEvent e) {
+ if (hasFocus()) {
+ e.childID = ACC.CHILDID_SELF;
+ }
+ }
+ });
+ }
+
+ @Override
+ 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 _getText();
+ }
+
+ private String _getText() {
+ return getQLabel().text();
+ }
+
+ private 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;
+ }
+ 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, Math.max(tagStart, linkStart), length, 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();
+ }
+
+ private 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;
+ }
+
+ @Override
+ void releaseWidget() {
+ super.releaseWidget();
+ offsets = null;
+ ids = null;
+ mnemonics = null;
+ }
+
+ /**
+ * Removes the listener from the collection of listeners who will be
+ * notified when the control is selected by the user.
+ *
+ * @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 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(_getText())) {
+ return;
+ }
+ String text = string.replace("<A>", "<a>");//$NON-NLS-1$ //$NON-NLS-2$
+ text = text.replace("</A>", "</a>");//$NON-NLS-1$ //$NON-NLS-2$
+ getQLabel().setText(adjustTags(text));
+ }
+
+ /*
+ * QLabel does not render a link as a link if it is created like this: Text
+ * and <a>link</a> and another <a>link</a> QLabel requires the href part to
+ * be there also. This function changes the string above to this: Text and
+ * <a href="link">link</a> and another <a href="link">link</a>
+ */
+ static String adjustTags(String str) {
+ int pos = str.indexOf(LINK_START);
+
+ if (pos == -1) {
+ return str;
+ }
+
+ int start = 0;
+ int endPos = pos;
+ StringBuffer sb = new StringBuffer();
+ String clean = "";//$NON-NLS-1$
+
+ while (pos != -1) {
+ sb.append(str.substring(start, pos)).append("<a href=\"");//$NON-NLS-1$
+ start = pos + LINK_START.length();
+ endPos = str.indexOf(LINK_END, start);
+ if (endPos != -1) {
+ clean = clean(str.substring(start, endPos));
+ sb.append(clean);
+ } else {
+ // If the link format is invalid in any way, just use
+ // original string and try not to be too clever.
+ return str;
+ }
+
+ sb.append("\">" + clean + LINK_END);//$NON-NLS-1$
+ start = endPos + LINK_END.length();
+ pos = str.indexOf(LINK_START, start);
+ }
+
+ return sb.toString();
+ }
+
+ static String clean(String strToClean) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < strToClean.length(); i++) {
+ char charAt = strToClean.charAt(i);
+ if (charAt == '"') {
+ sb.append("&quot;"); //$NON-NLS-1$
+ } else {
+ if (charAt == '<') {
+ sb.append("&lt;"); //$NON-NLS-1$
+ } else {
+ if (charAt == '>') {
+ sb.append("&gt;"); //$NON-NLS-1$
+ } else {
+ sb.append(charAt);
+ }
+ }
+ }
+ }
+ return sb.toString();
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/List.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/List.java
new file mode 100644
index 0000000000..db2dfc0a7b
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/List.java
@@ -0,0 +1,1380 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import java.util.Arrays;
+
+import com.trolltech.qt.core.QModelIndex;
+import com.trolltech.qt.core.QPoint;
+import com.trolltech.qt.core.Qt.DropActions;
+import com.trolltech.qt.gui.QDragEnterEvent;
+import com.trolltech.qt.gui.QDragLeaveEvent;
+import com.trolltech.qt.gui.QDragMoveEvent;
+import com.trolltech.qt.gui.QDropEvent;
+import com.trolltech.qt.gui.QItemSelection;
+import com.trolltech.qt.gui.QListWidget;
+import com.trolltech.qt.gui.QListWidgetItem;
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.qt.gui.QAbstractItemView.DragDropMode;
+import com.trolltech.qt.gui.QAbstractItemView.ScrollHint;
+import com.trolltech.qt.gui.QAbstractItemView.SelectionMode;
+import com.trolltech.qt.gui.QItemSelectionModel.SelectionFlag;
+import com.trolltech.qt.gui.QItemSelectionModel.SelectionFlags;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#list">List snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public class List extends 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#SINGLE
+ * @see SWT#MULTI
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+ public List(Composite parent, int style) {
+ super(parent, checkStyle(style));
+ }
+
+ @Override
+ protected QWidget createQWidget(int style) {
+ QListWidget listWidget = new MyListWidget();
+ if ((style & SWT.MULTI) != 0) {
+ listWidget.setSelectionMode(SelectionMode.MultiSelection);
+ } else {
+ listWidget.setSelectionMode(SelectionMode.SingleSelection);
+ }
+ return listWidget;
+ }
+
+ @Override
+ protected void connectSignals() {
+ getQListWidget().selectionModel().selectionChanged.connect(this, "selectionEvent()");//$NON-NLS-1$
+ getQListWidget().itemActivated.connect(this, "itemActivationEvent(QListWidgetItem)");//$NON-NLS-1$
+ }
+
+ private QListWidget getQListWidget() {
+ return (QListWidget) getQWidget();
+ }
+
+ protected void selectionEvent() {
+ sendEvent(SWT.Selection);
+ }
+
+ protected void itemActivationEvent(QListWidgetItem item) {
+ sendEvent(SWT.DefaultSelection);
+ }
+
+ @Override
+ public void setDragEnabled(boolean enabled) {
+ getQListWidget().setDragEnabled(enabled);
+ }
+
+ @Override
+ public void setAcceptDrops(boolean accept) {
+ super.setAcceptDrops(accept);
+ getQListWidget().setDragDropMode(DragDropMode.DragDrop);
+ getQListWidget().setDropIndicatorShown(true);
+ }
+
+ /**
+ * 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);
+ }
+ getQListWidget().addItem(string);
+ }
+
+ /**
+ * 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);
+ }
+ validateIndex(index);
+ getQListWidget().insertItem(index, string);
+ }
+
+ /**
+ * Adds the listener to the collection of listeners who will be notified
+ * when the user changes the receiver's selection, 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 when the user changes
+ * the receiver's selection
+ *
+ * @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);
+ }
+
+ /**
+ * 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);
+ }
+
+ updateSelection(indices, new SelectionFlags(SelectionFlag.Deselect));
+ }
+
+ private void updateSelection(int[] indices, SelectionFlags selectionFlags) {
+ int count = getQListWidget().count();
+ for (int i = 0; i < indices.length; i++) {
+ if (indices[i] >= 0 && indices[i] < count) {
+ updateSelectionRange(indices[i], indices[i], selectionFlags);
+ }
+ }
+ }
+
+ /**
+ * 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();
+ validateIndex(index);
+ updateSelectionRange(index, index, new SelectionFlags(SelectionFlag.Deselect));
+ }
+
+ void validateIndex(int index) {
+ if (index < 0 || index > getQListWidget().count()) {
+ SWT.error(SWT.ERROR_INVALID_RANGE);
+ }
+ }
+
+ /**
+ * 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 || end < 0) {
+ return;
+ }
+ int count = getQListWidget().count();
+ if (start > count - 1) {
+ return;
+ }
+ start = Math.max(0, start);
+ end = Math.min(end, count - 1);
+ updateSelectionRange(start, end, new SelectionFlags(SelectionFlag.Deselect));
+ }
+
+ void updateSelectionRange(int start, int end, SelectionFlags flags) {
+ QModelIndex startIndex = getQListWidget().model().index(start, 0);
+ QModelIndex endIndex = getQListWidget().model().index(end, 0);
+ QItemSelection itemSelection = new QItemSelection(startIndex, endIndex);
+ getQListWidget().selectionModel().select(itemSelection, flags);
+ }
+
+ /**
+ * 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();
+ getQListWidget().clearSelection();
+ }
+
+ /**
+ * 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();
+ return getQListWidget().currentRow();
+ }
+
+ /**
+ * 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();
+ validateIndex(index);
+ return getQListWidget().item(index).text();
+ }
+
+ /**
+ * 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 getQListWidget().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();
+ int itemHeight = 0;
+ if (getQListWidget().count() > 0) {
+ itemHeight = getQListWidget().sizeHintForRow(0);
+ } else {
+ // we add a dummy item to get the height
+ getQListWidget().addItem("");//$NON-NLS-1$
+ itemHeight = getQListWidget().sizeHintForRow(0);
+ _remove(0);
+ }
+ return itemHeight;
+ }
+
+ /**
+ * 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();
+ QListWidget listWidget = getQListWidget();
+ java.util.List<QModelIndex> selectedIndices = listWidget.selectionModel().selectedRows();
+ String[] sel = new String[selectedIndices.size()];
+ int i = 0;
+ for (QModelIndex index : selectedIndices) {
+ sel[i] = listWidget.item(index.row()).text();
+ i++;
+ }
+ return sel;
+ }
+
+ /**
+ * 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();
+ return getQListWidget().selectionModel().selectedRows().size();
+ }
+
+ /**
+ * 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();
+ java.util.List<QModelIndex> selectedIndices = getQListWidget().selectionModel().selectedRows();
+ if (selectedIndices != null && selectedIndices.size() > 0) {
+ return selectedIndices.get(0).row();
+ }
+ return 0;
+ }
+
+ /**
+ * 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();
+ java.util.List<QModelIndex> selection = getQListWidget().selectionModel().selectedRows();
+ int[] selIndex = new int[selection.size()];
+ int i = 0;
+ for (QModelIndex index : selection) {
+ selIndex[i] = index.row();
+ i++;
+ }
+ return selIndex;
+ }
+
+ /**
+ * 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();
+ QModelIndex modellIndex = getQListWidget().indexAt(new QPoint(1, 1));
+ return modellIndex == null ? -1 : modellIndex.row();
+ }
+
+ /**
+ * 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) {
+ checkWidget();
+ if (string == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+
+ 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) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ QListWidget listWidget = getQListWidget();
+ int count = listWidget.count();
+ if (start < 0 || start > count - 1) {
+ return -1;
+ }
+ for (int i = start; i < count; i++) {
+ if (listWidget.item(i).equals(string)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * 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 selection 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();
+ validateIndex(index);
+ QListWidgetItem item = getQListWidget().item(index);
+ if (item != null) {
+ return item.isSelected();
+ }
+ return false;
+ }
+
+ /**
+ * 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);
+ }
+ for (int index : indices) {
+ _remove(index);
+ }
+ }
+
+ /**
+ * 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();
+ _remove(index);
+ }
+
+ void _remove(int index) {
+ validateIndex(index);
+ getQListWidget().takeItem(index).dispose();
+ }
+
+ /**
+ * 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 (end < 0 || start > end || (style & SWT.SINGLE) != 0 && start != end) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+ QListWidget listWidget = getQListWidget();
+ int count = listWidget.count();
+ if (count == 0 || start >= count) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+ start = Math.max(0, start);
+ end = Math.min(end, count - 1);
+ for (int i = end; i >= start; --i) {
+ listWidget.takeItem(i).dispose();
+ }
+ }
+
+ /**
+ * 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();
+ getQListWidget().clear();
+ }
+
+ /**
+ * Removes the listener from the collection of listeners who will be
+ * notified when the user changes the receiver's selection.
+ *
+ * @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) {
+ updateSelection(indices, new SelectionFlags(SelectionFlag.Select));
+ }
+
+ /**
+ * 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 = getQListWidget().count();
+ if (index >= count) {
+ return;
+ }
+ updateSelectionRange(index, index, new SelectionFlags(SelectionFlag.Select));
+ }
+
+ /**
+ * 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 = getQListWidget().count();
+ if (count == 0 || start >= count) {
+ return;
+ }
+ start = Math.max(0, start);
+ end = Math.min(end, count - 1);
+ if ((style & SWT.SINGLE) != 0) {
+ select(start, false);
+ } else {
+ select(start, end, false);
+ }
+ }
+
+ void select(int start, int end, boolean scroll) {
+ updateSelectionRange(start, end, new SelectionFlags(SelectionFlag.Select));
+ }
+
+ /**
+ * 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();
+ int count = getQListWidget().count();
+ if ((style & SWT.MULTI) != 0 && count > 0) {
+ updateSelectionRange(0, count - 1, new SelectionFlags(SelectionFlag.Select));
+ }
+ }
+
+ void setFocusIndex(int index) {
+ QModelIndex modelIndex = getQListWidget().model().index(index, 0);
+ getQListWidget().selectionModel().setCurrentIndex(modelIndex, SelectionFlag.Current);
+ }
+
+ /**
+ * Sets the text of the item in the receiver's list at the given
+ * zero-relative index to the string argument.
+ *
+ * @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);
+ }
+ validateIndex(index);
+ 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 (String item : items) {
+ if (item == null) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ }
+ getQListWidget().clear();
+ getQListWidget().addItems(Arrays.asList(items));
+ }
+
+ /**
+ * 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);
+ if ((style & SWT.MULTI) != 0) {
+ int focusIndex = indices[0];
+ if (focusIndex >= 0) {
+ setFocusIndex(focusIndex);
+ }
+ }
+ }
+
+ /**
+ * 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;
+ }
+ int focusIndex = -1;
+ for (int i = length - 1; i >= 0; --i) {
+ String string = items[i];
+ int index = 0;
+ if (string != null) {
+ int localFocus = -1;
+ while ((index = indexOf(string, index)) != -1) {
+ if (localFocus == -1) {
+ localFocus = index;
+ }
+ select(index, false);
+ if ((style & SWT.SINGLE) != 0 && isSelected(index)) {
+ showSelection();
+ return;
+ }
+ index++;
+ }
+ if (localFocus != -1) {
+ focusIndex = localFocus;
+ }
+ }
+ }
+ if ((style & SWT.MULTI) != 0) {
+ if (focusIndex >= 0) {
+ setFocusIndex(focusIndex);
+ }
+ }
+ }
+
+ /**
+ * 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);
+ if ((style & SWT.MULTI) != 0) {
+ if (index >= 0 && index < getQListWidget().count()) {
+ setFocusIndex(index);
+ }
+ }
+ }
+
+ /**
+ * 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 = getQListWidget().count();
+ if (count == 0 || start >= count) {
+ return;
+ }
+ start = Math.max(0, start);
+ end = Math.min(end, count - 1);
+ updateSelectionRange(start, end, new SelectionFlags(SelectionFlag.Select));
+ }
+
+ /**
+ * 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();
+ validateIndex(index);
+ getQListWidget().scrollToItem(getQListWidget().item(index), ScrollHint.PositionAtTop);
+ }
+
+ /**
+ * 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() {
+ checkWidget();
+ getQListWidget().scrollToItem(getQListWidget().currentItem(), ScrollHint.PositionAtTop);
+ }
+
+ private final class MyListWidget extends QListWidget {
+
+ @Override
+ protected void startDrag(DropActions supportedActions) {
+ // System.out.println("MyQTreeWidget.startDrag: " + supportedActions);
+ }
+
+ @Override
+ protected void dropEvent(QDropEvent event) {
+ sendDropEvent(event);
+ }
+
+ @Override
+ protected void dragMoveEvent(QDragMoveEvent event) {
+ sendDragMoveEvent(event);
+ }
+
+ @Override
+ protected void dragEnterEvent(QDragEnterEvent event) {
+ sendDragEnterEvent(event);
+ }
+
+ @Override
+ protected void dragLeaveEvent(QDragLeaveEvent event) {
+ sendDragLeaveEvent(event);
+ }
+
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Menu.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Menu.java
new file mode 100644
index 0000000000..14e057d36c
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Menu.java
@@ -0,0 +1,1423 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import java.util.List;
+
+import com.trolltech.qt.core.QObject;
+import com.trolltech.qt.core.Qt.LayoutDirection;
+import com.trolltech.qt.gui.QAction;
+import com.trolltech.qt.gui.QActionGroup;
+import com.trolltech.qt.gui.QApplication;
+import com.trolltech.qt.gui.QBrush;
+import com.trolltech.qt.gui.QColor;
+import com.trolltech.qt.gui.QMenu;
+import com.trolltech.qt.gui.QMenuBar;
+import com.trolltech.qt.gui.QPalette;
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.qt.gui.QPalette.ColorRole;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.HelpListener;
+import org.eclipse.swt.events.MenuListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.internal.qt.QtSWTConverter;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#menu">Menu snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public class Menu extends Widget {
+ private int x, y;
+ private boolean hasLocation;
+ private Color foreground = null;
+ private Color background = null;
+ private Image backgroundImage;
+ MenuItem cascade;
+ Decorations parent;
+ private QActionGroup actionGroup;
+
+ /**
+ * 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.
+ * <p>
+ * After constructing a menu, it can be set into its parent using
+ * <code>parent.setMenu(menu)</code>. In this case, the parent may be any
+ * control in the same widget tree as the parent.
+ * </p>
+ *
+ * @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(), null, 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>
+ * <p>
+ * After constructing a menu or menuBar, it can be set into its parent using
+ * <code>parent.setMenu(menu)</code> or
+ * <code>parent.setMenuBar(menuBar)</code>.
+ * </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, null, checkStyle(style));
+ }
+
+ /**
+ * 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.
+ * <p>
+ * After constructing a drop-down menu, it can be set into its parentMenu
+ * using <code>parentMenu.setMenu(menu)</code>.
+ * </p>
+ *
+ * @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, parentMenu.getQWidget(), 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.
+ * <p>
+ * After constructing a drop-down menu, it can be set into its parentItem
+ * using <code>parentItem.setMenu(menu)</code>.
+ * </p>
+ *
+ * @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, QWidget qParent, int style) {
+ super(parent, checkStyle(style));
+ display = parent.display;
+ createWidget(parent, qParent, style);
+ }
+
+ protected void createWidget(Decorations parent, QWidget qParent, int style) {
+ state |= DRAG_DETECT;
+ this.parent = parent;
+ checkAndUpdateOrientation(parent);
+ QWidget qtControl = createQtControl(qParent != null ? qParent : parent.getQWidget());
+ if (qtControl == null) {
+ error(SWT.ERROR_UNSPECIFIED);
+ }
+ setQWidget(qtControl);
+ if ((style & SWT.RIGHT_TO_LEFT) != 0) {
+ qtControl.setLayoutDirection(LayoutDirection.RightToLeft);
+ }
+ register();
+ if ((state & PARENT_BACKGROUND) != 0) {
+ updateBackground();
+ }
+ parent.addMenu(this);
+ }
+
+ protected QWidget createQtControl(QWidget parent) {
+ state &= ~CANVAS;
+ if (isMenuBar()) {
+ return new QMenuBar(parent);
+ }
+ return new QMenu(parent);
+ }
+
+ QMenuBar getQMenuBar() {
+ return (QMenuBar) getQWidget();
+ }
+
+ QMenu getQMenu() {
+ return (QMenu) getQWidget();
+ }
+
+ void addToActionGroup(QAction action) {
+ initActionGroup();
+ actionGroup.addAction(action);
+ }
+
+ void removeFromActionGroup(QAction action) {
+ if (hasActionGroup()) {
+ actionGroup.removeAction(action);
+ }
+ }
+
+ private boolean hasActionGroup() {
+ return actionGroup != null;
+ }
+
+ private void initActionGroup() {
+ if (actionGroup == null) {
+ actionGroup = new QActionGroup(getQWidget());
+ if ((parent.style & SWT.NO_RADIO_GROUP) != 0) {
+ actionGroup.setExclusive(false);
+ }
+ }
+ }
+
+ void register() {
+ display.addControl(getQWidget(), this);
+ }
+
+ void deregister() {
+ display.removeControl(getQWidget());
+ }
+
+ void _setVisible(boolean visible) {
+ if ((style & (SWT.BAR | SWT.DROP_DOWN)) != 0) {
+ return;
+ }
+ getQWidget().setHidden(!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 addAction(QAction action, int index) {
+ QWidget menu = getQWidget();
+ int itemCount = _getItemCount();
+ if (index >= 0 && index < itemCount) {
+ MenuItem[] items = getItems();
+ QAction before = items[index].getQAction();
+ menu.insertAction(before, action);
+ } else {
+ menu.addAction(action);
+ }
+ }
+
+ void removeAction(QAction action) {
+ if (isMenuBar()) {
+ getQMenuBar().removeAction(action);
+ } else {
+ getQMenu().removeAction(action);
+ }
+ }
+
+ boolean isMenuBar() {
+ return (style & SWT.BAR) != 0;
+ }
+
+ Color defaultBackground() {
+ return display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
+ }
+
+ Color defaultForeground() {
+ return display.getSystemColor(SWT.COLOR_WIDGET_FOREGROUND);
+ }
+
+ 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 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 3.3
+ */
+ /* public */Color getBackground() {
+ checkWidget();
+ return background != null ? Color.qt_new(display, background.getColor()) : defaultBackground();
+ }
+
+ /**
+ * 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.3
+ */
+ /* public */Image getBackgroundImage() {
+ checkWidget();
+ return backgroundImage;
+ }
+
+ /**
+ * 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();
+ return QtSWTConverter.convert(getQWidget().frameGeometry());
+ }
+
+ /**
+ * 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();
+ // if ( OS.IsWinCE )
+ // return null;
+ // int id = OS.GetMenuDefaultItem( handle, OS.MF_BYCOMMAND,
+ // OS.GMDI_USEDISABLED );
+ // if ( id == -1 )
+ // return null;
+ // MENUITEMINFO info = new MENUITEMINFO();
+ // info.cbSize = MENUITEMINFO.sizeof;
+ // info.fMask = OS.MIIM_ID;
+ // if ( OS.GetMenuItemInfo( handle, id, false, info ) ) {
+ // return display.getMenuItem( info.wID );
+ // }
+ 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 getQMenuBar().isEnabled();
+ }
+
+ /**
+ * 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 foreground != null ? Color.qt_new(display, foreground.getColor()) : defaultForeground();
+ }
+
+ /**
+ * 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();
+ List<QAction> list = getQWidget().actions();
+ int count = list.size();
+ if (!(0 <= index && index < count)) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+ Widget widget = display.findControl(list.get(index));
+ if (widget == null || !MenuItem.class.isInstance(widget)) {
+ error(SWT.ERROR_CANNOT_GET_ITEM);
+ }
+ return (MenuItem) 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 _getItemCount();
+ }
+
+ /**
+ * 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();
+ List<QAction> list = getQWidget().actions();
+ int count = list.size();
+ if (count == 0) {
+ return new MenuItem[0];
+ }
+ MenuItem[] children = new MenuItem[count];
+ int items = 0;
+ for (QAction action : list) {
+ if (action != null) {
+ Widget widget = display.findControl(action);
+ if (widget != null && widget != this) {
+ if (widget instanceof MenuItem) {
+ children[items++] = (MenuItem) widget;
+ }
+ }
+ }
+ }
+ if (items == count) {
+ return children;
+ }
+ MenuItem[] newChildren = new MenuItem[items];
+ System.arraycopy(children, 0, newChildren, 0, items);
+ return newChildren;
+ }
+
+ int _getItemCount() {
+ return getQWidget().actions().size();
+ }
+
+ @Override
+ String getNameText() {
+ String result = "";//$NON-NLS-1$
+ MenuItem[] items = getItems();
+ int length = items.length;
+ if (length > 0) {
+ for (int i = 0; i < length - 1; i++) {
+ result = result + items[i].getNameText() + ", ";//$NON-NLS-1$
+ }
+ 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;
+ }
+
+ /**
+ * 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>
+ * </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();
+ if (item == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (item.isDisposed()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ if (item.parent != this) {
+ return -1;
+ }
+ List<QAction> actions = getQWidget().actions();
+ for (int i = 0; i < actions.size(); i++) {
+ if (actions.get(i) == item.getQAction()) {
+ 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() && parent.isEnabled();
+ }
+ 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 redraw() {
+ if (!isVisible()) {
+ return;
+ }
+ if ((style & SWT.BAR) != 0) {
+ display.addBar(this);
+ }
+ }
+
+ @Override
+ void releaseQWidget() {
+ super.releaseQWidget();
+ cascade = null;
+ }
+
+ @Override
+ 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);
+ }
+
+ @Override
+ void releaseParent() {
+ super.releaseParent();
+ 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);
+ }
+ }
+ }
+
+ @Override
+ void releaseWidget() {
+ super.releaseWidget();
+ backgroundImage = null;
+ if (parent != null) {
+ parent.removeMenu(this);
+ }
+ parent = 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 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>
+ *
+ * @since 3.3
+ */
+ /* public */void setBackground(Color color) {
+ checkWidget();
+ if (color != null) {
+ if (color.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ }
+ Color oldColor = background;
+ if (color == null) {
+ background = null;
+ } else {
+ if (color.equals(background)) {
+ return;
+ }
+ background = color;
+ }
+ if (oldColor != null) {
+ oldColor.dispose();
+ }
+ updateBackground();
+ }
+
+ /**
+ * 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.3
+ */
+ /* public */void setBackgroundImage(Image image) {
+ checkWidget();
+ if (image != null) {
+ if (image.isDisposed()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ if (!image.isBitmap()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ }
+ if (backgroundImage == image) {
+ return;
+ }
+ backgroundImage = image;
+ updateBackground();
+ }
+
+ /**
+ * 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>
+ *
+ * @since 3.3
+ */
+ /* public */void setForeground(Color color) {
+ checkWidget();
+ if (color != null) {
+ if (color.isDisposed()) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ }
+ Color oldColor = foreground;
+ if (color == null) {
+ foreground = null;
+ } else {
+ if (color.equals(foreground)) {
+ return;
+ }
+ foreground = color;
+ }
+ if (oldColor != null) {
+ oldColor.dispose();
+ }
+ applyForegroundColor(foreground);
+ }
+
+ /**
+ * 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();
+ if (item != null) {
+ if (item.isDisposed()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ if (item.parent != this) {
+ return;
+ }
+ if (!isMenuBar()) {
+ getQMenu().setDefaultAction(item.getQAction());
+ }
+ } else {
+ if (!isMenuBar()) {
+ getQMenu().setDefaultAction(null);
+ }
+ }
+ }
+
+ /**
+ * 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();
+ getQWidget().setEnabled(enabled);
+ getQWidget().update();
+ }
+
+ /**
+ * 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;
+ }
+ this.x = x;
+ this.y = y;
+ hasLocation = true;
+ }
+
+ /**
+ * 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);
+ if (hasLocation) {
+ getQMenu().move(x, y);
+ }
+ getQMenu().setVisible(true);
+ } else {
+ display.removePopup(this);
+ _setVisible(false);
+ }
+ }
+
+ @Override
+ public boolean qtHideEvent(QObject source) {
+ if (source == getQWidget()) {
+ if (!isDisposed()) {
+ sendEvent(SWT.Hide);
+ }
+ }
+ return super.qtHideEvent(source);
+ }
+
+ @Override
+ public boolean qtShowEvent(QObject source) {
+ if (source == getQWidget()) {
+ if (!isDisposed()) {
+ sendEvent(SWT.Show);
+ }
+ }
+ return super.qtShowEvent(source);
+ }
+
+ void updateBackground() {
+ if (backgroundImage != null) {
+ applyBackgroundImage(backgroundImage);
+ return;
+ }
+ if (background != null) {
+ applyBackgroundColor(background);
+ return;
+ }
+ }
+
+ private void applyBackgroundColor(Color color) {
+ updatedPalette(color, getBackgroundColorRoles());
+ updateAutoFillBackground();
+ }
+
+ private void updatedPalette(Color color, ColorRole[] colorRoles) {
+ QPalette palette = getQWidget().palette();
+ if (color != null) {
+ QColor qColor = new QColor(color.getColor());
+ for (ColorRole role : colorRoles) {
+ palette.setColor(role, qColor);
+ }
+ } else {
+ QPalette defaultPalette = QApplication.palette();
+ for (ColorRole role : colorRoles) {
+ QBrush brush = defaultPalette.brush(role);
+ palette.setBrush(role, brush);
+ }
+ }
+ getQWidget().setPalette(palette);
+ }
+
+ private QPalette.ColorRole[] getBackgroundColorRoles() {
+ return new QPalette.ColorRole[] { QPalette.ColorRole.Window, QPalette.ColorRole.Base, QPalette.ColorRole.Button };
+ }
+
+ private void updateAutoFillBackground() {
+ if (background != null || backgroundImage != null) {
+ getQWidget().setAutoFillBackground(true);
+ }
+ }
+
+ private void applyBackgroundImage(Image image) {
+ QPalette palette = getQWidget().palette().clone();
+ try {
+ setPaletteBgImage(palette, image);
+ getQWidget().setPalette(palette);
+ } finally {
+ palette.dispose();
+ }
+ updateAutoFillBackground();
+ }
+
+ private void setPaletteBgImage(QPalette palette, Image image) {
+ ColorRole[] bkRoles = getBackgroundImageRoles();
+ if (image != null) {
+ for (ColorRole bkRole : bkRoles) {
+ palette.setBrush(bkRole, new QBrush(image.getQPixmap()));
+ }
+ } else {
+ QPalette defaultPalette = QApplication.palette();
+ for (ColorRole role : bkRoles) {
+ QBrush brush = defaultPalette.brush(role);
+ palette.setBrush(role, brush.clone());
+ }
+ }
+ }
+
+ private ColorRole[] getBackgroundImageRoles() {
+ return new QPalette.ColorRole[] { QPalette.ColorRole.Window, QPalette.ColorRole.Base };
+ }
+
+ private void applyForegroundColor(Color color) {
+ updatedPalette(color, getForegroundColorRoles());
+ }
+
+ private ColorRole[] getForegroundColorRoles() {
+ return new ColorRole[] { QPalette.ColorRole.WindowText, QPalette.ColorRole.Text, QPalette.ColorRole.ButtonText };
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/MenuItem.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/MenuItem.java
new file mode 100644
index 0000000000..479993bdec
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/MenuItem.java
@@ -0,0 +1,1011 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import java.util.HashMap;
+
+import com.trolltech.qt.core.Qt;
+import com.trolltech.qt.gui.QAction;
+import com.trolltech.qt.gui.QIcon;
+import com.trolltech.qt.gui.QKeySequence;
+import com.trolltech.qt.gui.QMenu;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.ArmListener;
+import org.eclipse.swt.events.HelpListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.internal.qt.QtSWTConverter;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public class MenuItem extends Item {
+ private QAction action;
+ Menu parent, menu;
+ int id, accelerator;
+
+ private HashMap<Integer, Integer> modifiers = new HashMap<Integer, Integer>();
+ private HashMap<Integer, Integer> accelerators = new HashMap<Integer, Integer>();
+
+ /**
+ * 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;
+ createAction(parent, style, -1);
+ initializeKeys();
+ }
+
+ /**
+ * 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;
+ createAction(parent, style, index);
+ initializeKeys();
+ }
+
+ MenuItem(Menu parent, Menu menu, int style, int index) {
+ super(parent, checkStyle(style));
+ this.parent = parent;
+ this.menu = menu;
+ if (menu != null) {
+ menu.cascade = this;
+ }
+ display.addMenuItem(this);
+ initializeKeys();
+ }
+
+ protected void createAction(Menu parent, int style, int index) {
+ action = new QAction(parent.getQWidget());
+
+ parent.addAction(action, index);
+ int bits = SWT.CHECK | SWT.RADIO | SWT.PUSH | SWT.SEPARATOR;
+ switch (style & bits) {
+ case SWT.SEPARATOR:
+ action.setSeparator(true);
+ break;
+ case SWT.RADIO:
+ action.setCheckable(true);
+ parent.addToActionGroup(action);
+ break;
+ case SWT.CHECK:
+ action.setCheckable(true);
+ break;
+ case SWT.PUSH:
+ default:
+ break;
+ }
+ connectSignals();
+ display.addControl(action, this);
+ }
+
+ QAction getQAction() {
+ return action;
+ }
+
+ protected void connectSignals() {
+ if ((style & SWT.CASCADE) == 0) {
+ getQAction().triggered.connect(this, "triggerEvent(boolean)");//$NON-NLS-1$
+ }
+ getQAction().hovered.connect(this, "hoverEvent()");//$NON-NLS-1$
+ }
+
+ protected void triggerEvent(boolean triggered) {
+ Event event = new Event();
+ sendEvent(SWT.Selection, event);
+ }
+
+ protected void hoverEvent() {
+ sendEvent(SWT.Arm);
+ }
+
+ /**
+ * Initialize the hashmaps with the SWT keys mapping to QT keys. This is
+ * needed for the accelerator.
+ */
+ private void initializeKeys() {
+
+ modifiers.put(SWT.CTRL, Qt.Modifier.CTRL.value()); // 262144, 67108864
+ modifiers.put(SWT.MOD1, Qt.Modifier.CTRL.value()); // 262144, 67108864
+ modifiers.put(SWT.SHIFT, Qt.Modifier.SHIFT.value());
+ modifiers.put(SWT.MOD2, Qt.Modifier.SHIFT.value());
+ modifiers.put(SWT.ALT, Qt.Modifier.ALT.value());
+
+ accelerators.put(SWT.ARROW_DOWN, Qt.Key.Key_Down.value()); // 16777218
+ accelerators.put(SWT.ARROW_LEFT, Qt.Key.Key_Left.value()); // 16777219
+ accelerators.put(SWT.ARROW_RIGHT, Qt.Key.Key_Right.value()); // 16777220
+ accelerators.put(SWT.ARROW_UP, Qt.Key.Key_Up.value()); // 16777217
+ accelerators.put(SWT.F1, Qt.Key.Key_F1.value()); // 16777226
+ accelerators.put(SWT.F2, Qt.Key.Key_F2.value());
+ accelerators.put(SWT.F3, Qt.Key.Key_F3.value());
+ accelerators.put(SWT.F4, Qt.Key.Key_F4.value());
+ accelerators.put(SWT.F5, Qt.Key.Key_F5.value());
+ accelerators.put(SWT.F6, Qt.Key.Key_F6.value());
+ accelerators.put(SWT.F7, Qt.Key.Key_F7.value());
+ accelerators.put(SWT.F8, Qt.Key.Key_F8.value());
+ accelerators.put(SWT.F9, Qt.Key.Key_F9.value());
+ accelerators.put(SWT.F10, Qt.Key.Key_F10.value());
+ accelerators.put(SWT.F11, Qt.Key.Key_F11.value());
+ accelerators.put(SWT.F12, Qt.Key.Key_F12.value());
+ accelerators.put(SWT.F13, Qt.Key.Key_F13.value());
+ accelerators.put(SWT.F14, Qt.Key.Key_F14.value());
+ accelerators.put(SWT.F15, Qt.Key.Key_F15.value());
+ accelerators.put(SWT.PAGE_UP, Qt.Key.Key_PageUp.value());
+ accelerators.put(SWT.PAGE_DOWN, Qt.Key.Key_PageDown.value());
+ accelerators.put(SWT.HOME, Qt.Key.Key_Home.value());
+ accelerators.put(SWT.END, Qt.Key.Key_End.value());
+ accelerators.put(SWT.INSERT, Qt.Key.Key_Insert.value());
+ }
+
+ /**
+ * 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 the user, 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 when the menu item is
+ * selected by the user
+ *
+ * @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);
+ }
+
+ @Override
+ 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);
+ }
+
+ @Override
+ void destroyWidget() {
+ parent.removeAction(getQAction());
+ 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();
+ return accelerator;
+ }
+
+ /**
+ * 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();
+ return QtSWTConverter.convert(getQWidget().frameGeometry());
+ }
+
+ /**
+ * 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 getQAction().isEnabled();
+ }
+
+ /**
+ * 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>
+ */
+ @Override
+ public Menu getMenu() {
+ checkWidget();
+ return menu;
+ }
+
+ @Override
+ String getNameText() {
+ if ((style & SWT.SEPARATOR) != 0) {
+ return "|";//$NON-NLS-1$
+ }
+ 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();
+ return getQAction().isChecked();
+ }
+
+ /**
+ * 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();
+ }
+
+ @Override
+ void releaseChildren(boolean destroy) {
+ if (menu != null) {
+ menu.release(false);
+ menu = null;
+ }
+ super.releaseChildren(destroy);
+ }
+
+ @Override
+ void releaseQWidget() {
+ if ((style & SWT.RADIO) != 0) {
+ parent.removeFromActionGroup(action);
+ }
+ parent.removeAction(action);
+ display.removeControl(action);
+ parent = null;
+ action = null;
+ id = -1;
+ super.releaseQWidget();
+ }
+
+ @Override
+ void releaseParent() {
+ super.releaseParent();
+ if (menu != null) {
+ menu.dispose();
+ }
+ menu = null;
+ }
+
+ @Override
+ void releaseWidget() {
+ super.releaseWidget();
+ accelerator = 0;
+ display.removeMenuItem(this);
+ }
+
+ /**
+ * 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 by the user.
+ *
+ * @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 selectRadio() {
+ int index = 0;
+ MenuItem[] items = parent.getItems();
+ while (index < items.length && items[index] != this) {
+ index++;
+ }
+ int i = index - 1;
+ while (i >= 0 && items[i].setRadioSelection(false)) {
+ --i;
+ }
+ int j = index + 1;
+ while (j < items.length && items[j].setRadioSelection(false)) {
+ j++;
+ }
+ setSelection(true);
+ }
+
+ /**
+ * 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();
+ int seq = 0;
+ if (this.accelerator == accelerator) {
+ return;
+ }
+ this.accelerator = accelerator;
+ /*
+ * fetch the modifiers of the accelerator (something like
+ * CTRL+SHIFT...). There can be more than one modifier.
+ */
+ for (Integer modifier : modifiers.keySet()) {
+ if ((accelerator & modifier) != 0) {
+ accelerator -= modifier;
+ seq += modifiers.get(modifier);
+ }
+ }
+
+ /*
+ * Fetch uppercase characters and other ascii characters (+, =, ?...).
+ * Only one of this chars is allowed.
+ */
+ if (accelerator >= 32 && accelerator <= 96 || accelerator >= 123 && accelerator <= 127) {
+ seq += accelerator;
+ accelerator -= accelerator;
+ }
+ /*
+ * Transform lowercase characters to uppercase characters, because QT
+ * can only handle uppercase characters and there is no difference
+ * between CTRL+m and CTRL+M. Only one of this chars is allowed.
+ */
+ if (accelerator >= 97 && accelerator <= 122) {
+ seq += accelerator - 32; // make a uppercase character out of a lowercase character
+ accelerator -= accelerator;
+ }
+
+ /* fetch characters like F1, arrow keys or Page Up. Only one is allowed */
+ if (accelerator != 0) {
+ for (Integer acc : accelerators.keySet()) {
+ if (accelerator == acc) {
+ accelerator -= acc;
+ seq += accelerators.get(acc);
+ }
+ }
+ }
+
+ if (accelerator != 0) { // something went wrong here. Not every character could be fetched.
+ return;
+ }
+ getQAction().setShortcut(new QKeySequence(seq));
+
+ }
+
+ /*
+ * private QKeySequence acceleratorToString(int accelerator) { int seq = 0;
+ * if ((accelerator & SWT.MOD1) != 0 || (accelerator & SWT.CTRL) != 0) { //
+ * on Windows systems SWT.MOD1 is the ctrl key accelerator -= SWT.MOD1; seq
+ * += Qt.Modifier.CTRL.value(); } if ((accelerator & SWT.MOD2) != 0 ||
+ * (accelerator & SWT.SHIFT) != 0) { // on Windows systems SWT.MOD2 is the
+ * shift key accelerator -= SWT.MOD2; seq += Qt.Modifier.SHIFT.value(); } if
+ * ((accelerator & SWT.MOD3) != 0 || (accelerator & SWT.ALT) != 0) {
+ * accelerator -= SWT.MOD3; seq += Qt.Modifier.ALT.value(); } if
+ * (accelerator >= 65 && accelerator <= 90) { seq += accelerator; } else if
+ * (accelerator >= 97 && accelerator <= 122) { seq += accelerator - 32; //
+ * this takes care of lowercase characters. CTRL+m should be the same as
+ * CTRL+M } else if ((accelerator & SWT.ARROW_DOWN) != 0) { seq +=
+ * Qt.Key.Key_Down.value(); } else if ((accelerator & SWT.ARROW_LEFT) != 0)
+ * { seq += Qt.Key.Key_Left.value(); } else if ((accelerator &
+ * SWT.ARROW_RIGHT) != 0) { seq += Qt.Key.Key_Right.value(); } else if
+ * ((accelerator & SWT.ARROW_UP) != 0) { seq += Qt.Key.Key_Up.value(); }
+ * else if ((accelerator & SWT.F1) != 0) { seq += Qt.Key.Key_F1.value(); }
+ * return new QKeySequence(seq); }
+ */
+ /**
+ * 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();
+ getQAction().setEnabled(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). Furthermore, some
+ * platforms (such as GTK), cannot display both a check box and an image at
+ * the same time. Instead, they hide the image and display the check box.
+ * </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>
+ */
+ @Override
+ public void setImage(Image image) {
+ checkWidget();
+ if ((style & SWT.SEPARATOR) != 0) {
+ return;
+ }
+ super.setImage(image);
+ if (image != null) {
+ getQAction().setIcon(image.getQIcon());
+ } else {
+ getQAction().setIcon((QIcon) null);
+ }
+ }
+
+ /**
+ * 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();
+
+ /* Check to make sure the new menu is valid */
+ if ((style & SWT.CASCADE) == 0) {
+ error(SWT.ERROR_MENUITEM_NOT_CASCADE);
+ }
+ if (menu != null) {
+ 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);
+ }
+ }
+ setMenu(menu, false);
+ }
+
+ void setMenu(Menu menu, boolean dispose) {
+ if ((style & SWT.CASCADE) == 0) {
+ error(SWT.ERROR_MENUITEM_NOT_CASCADE);
+ }
+ QMenu qMenu = null;
+ if (menu != null) {
+ if ((menu.style & SWT.DROP_DOWN) == 0) {
+ error(SWT.ERROR_MENU_NOT_DROP_DOWN);
+ }
+ if (menu.parent != parent.parent) {
+ error(SWT.ERROR_INVALID_PARENT);
+ }
+ qMenu = menu.getQMenu();
+ }
+ Menu oldMenu = this.menu;
+ if (oldMenu == menu) {
+ return;
+ }
+ if (oldMenu != null) {
+ oldMenu.cascade = null;
+ }
+ this.menu = menu;
+ getQAction().setMenu(qMenu);
+ if (this.menu != null) {
+ this.menu.cascade = this;
+ }
+ }
+
+ boolean setRadioSelection(boolean value) {
+ if ((style & SWT.RADIO) == 0) {
+ return false;
+ }
+ if (getSelection() != value) {
+ setSelection(value);
+ postEvent(SWT.Selection);
+ }
+ return true;
+ }
+
+ /**
+ * 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;
+ }
+ getQAction().setChecked(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
+ */
+ @Override
+ 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);
+ getQAction().setText(string);
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/MessageBox.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/MessageBox.java
new file mode 100644
index 0000000000..297dd3161f
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/MessageBox.java
@@ -0,0 +1,312 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample, Dialog tab</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class MessageBox extends Dialog {
+ String message = ""; //$NON-NLS-1$
+
+ /**
+ * 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(parent, checkStyle(style)));
+ checkSubclass();
+ }
+
+ static int checkStyle(int style) {
+ 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.MB_OK;
+ // }
+ // if ((style & (SWT.OK | SWT.CANCEL)) == (SWT.OK | SWT.CANCEL)) {
+ // buttonBits = OS.MB_OKCANCEL;
+ // }
+ // if ((style & (SWT.YES | SWT.NO)) == (SWT.YES | SWT.NO)) {
+ // buttonBits = OS.MB_YESNO;
+ // }
+ // if ((style & (SWT.YES | SWT.NO | SWT.CANCEL)) == (SWT.YES | SWT.NO | SWT.CANCEL)) {
+ // buttonBits = OS.MB_YESNOCANCEL;
+ // }
+ // if ((style & (SWT.RETRY | SWT.CANCEL)) == (SWT.RETRY | SWT.CANCEL)) {
+ // buttonBits = OS.MB_RETRYCANCEL;
+ // }
+ // if ((style & (SWT.ABORT | SWT.RETRY | SWT.IGNORE)) == (SWT.ABORT | SWT.RETRY | SWT.IGNORE)) {
+ // buttonBits = OS.MB_ABORTRETRYIGNORE;
+ // }
+ // if (buttonBits == 0) {
+ // buttonBits = OS.MB_OK;
+ // }
+ //
+ // int iconBits = 0;
+ // if ((style & SWT.ICON_ERROR) != 0) {
+ // iconBits = OS.MB_ICONERROR;
+ // }
+ // if ((style & SWT.ICON_INFORMATION) != 0) {
+ // iconBits = OS.MB_ICONINFORMATION;
+ // }
+ // if ((style & SWT.ICON_QUESTION) != 0) {
+ // iconBits = OS.MB_ICONQUESTION;
+ // }
+ // if ((style & SWT.ICON_WARNING) != 0) {
+ // iconBits = OS.MB_ICONWARNING;
+ // }
+ // if ((style & SWT.ICON_WORKING) != 0) {
+ // iconBits = OS.MB_ICONINFORMATION;
+ // }
+ //
+ // /* Only MB_APPLMODAL is supported on WinCE */
+ // int modalBits = 0;
+ //
+ // if ((style & SWT.PRIMARY_MODAL) != 0) {
+ // modalBits = OS.MB_APPLMODAL;
+ // }
+ // if ((style & SWT.APPLICATION_MODAL) != 0) {
+ // modalBits = OS.MB_TASKMODAL;
+ // }
+ // if ((style & SWT.SYSTEM_MODAL) != 0) {
+ // modalBits = OS.MB_SYSTEMMODAL;
+ // }
+ //
+ // int bits = buttonBits | iconBits | modalBits;
+ // if ((style & SWT.RIGHT_TO_LEFT) != 0) {
+ // bits |= OS.MB_RTLREADING | OS.MB_RIGHT;
+ // }
+ // if ((style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT)) == 0) {
+ // if (parent != null && (parent.style & SWT.MIRRORED) != 0) {
+ // bits |= OS.MB_RTLREADING | OS.MB_RIGHT;
+ // }
+ // }
+ //
+ // /*
+ // * Feature in Windows. System modal is not supported on Windows 95 and
+ // * NT. The fix is to convert system modal to task modal.
+ // */
+ // if ((bits & OS.MB_SYSTEMMODAL) != 0) {
+ // bits |= OS.MB_TASKMODAL;
+ // bits &= ~OS.MB_SYSTEMMODAL;
+ // /* Force a system modal message box to the front */
+ // bits |= OS.MB_TOPMOST;
+ // }
+ //
+ // /*
+ // * Feature in Windows. In order for MB_TASKMODAL to work, the parent
+ // * HWND of the MessageBox () call must be NULL. If the parent is not
+ // * NULL, MB_TASKMODAL behaves the same as MB_APPLMODAL. The fix to set
+ // * the parent HWND anyway and not rely on MB_MODAL to work by making the
+ // * parent be temporarily modal.
+ // */
+ // int /* long */hwndOwner = 0; //parent != null ? parent.handle : 0;
+ // Dialog oldModal = null;
+ // Display display = null;
+ // if ((bits & OS.MB_TASKMODAL) != 0) {
+ // display = parent.getDisplay();
+ // oldModal = display.getModalDialog();
+ // display.setModalDialog(this);
+ // }
+ //
+ // /* Open the message box */
+ // /* Use the character encoding for the default locale */
+ // TCHAR buffer1 = new TCHAR(0, message, true);
+ // TCHAR buffer2 = new TCHAR(0, title, true);
+ // int code = OS.MessageBox(hwndOwner, buffer1, buffer2, bits);
+ //
+ // /* Clear the temporarily dialog modal parent */
+ // if ((bits & OS.MB_TASKMODAL) != 0) {
+ // display.setModalDialog(oldModal);
+ // }
+ //
+ // /*
+ // * 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);
+ //
+ // /* Compute and return the result */
+ // if (code != 0) {
+ // int type = bits & 0x0F;
+ // if (type == OS.MB_OK) {
+ // return SWT.OK;
+ // }
+ // if (type == OS.MB_OKCANCEL) {
+ // return code == OS.IDOK ? SWT.OK : SWT.CANCEL;
+ // }
+ // if (type == OS.MB_YESNO) {
+ // return code == OS.IDYES ? SWT.YES : SWT.NO;
+ // }
+ // if (type == OS.MB_YESNOCANCEL) {
+ // if (code == OS.IDYES) {
+ // return SWT.YES;
+ // }
+ // if (code == OS.IDNO) {
+ // return SWT.NO;
+ // }
+ // return SWT.CANCEL;
+ // }
+ // if (type == OS.MB_RETRYCANCEL) {
+ // return code == OS.IDRETRY ? SWT.RETRY : SWT.CANCEL;
+ // }
+ // if (type == OS.MB_ABORTRETRYIGNORE) {
+ // if (code == OS.IDRETRY) {
+ // return SWT.RETRY;
+ // }
+ // if (code == OS.IDABORT) {
+ // return SWT.ABORT;
+ // }
+ // return SWT.IGNORE;
+ // }
+ // }
+ 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/qt/org/eclipse/swt/widgets/ProgressBar.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ProgressBar.java
new file mode 100644
index 0000000000..dc80139bfa
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ProgressBar.java
@@ -0,0 +1,318 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.gui.QProgressBar;
+import com.trolltech.qt.gui.QWidget;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Instances of the receiver represent 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#progressbar">ProgressBar
+ * snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ProgressBar extends Control {
+ static final int DELAY = 100;
+ int foreground = -1, background = -1;
+ private int timerID = -1;
+
+ /**
+ * 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));
+ }
+
+ @Override
+ protected QWidget createQWidget(int style) {
+ QProgressBar progressBar = new QProgressBar();
+ return progressBar;
+ }
+
+ @Override
+ protected void setupQWidget() {
+ if ((style & SWT.INDETERMINATE) != 0) {
+ getQProgressBar().setRange(0, 0);
+ // Funny: this avoids a JVM crash: EXCEPTION_INT_DIVIDE_BY_ZERO (0xc0000094)
+ // http://eclipse.compeople.eu/wiki/index.php/Compeople:SWTQtImplementierungsdetails#DIVISION_BY_ZERO
+ getQProgressBar().setTextVisible(false);
+ }
+ // this causes a lot of events, commented for debugging
+ //startTimer(getQProgressBar());
+ super.setupQWidget();
+ }
+
+ private QProgressBar getQProgressBar() {
+ return (QProgressBar) getQWidget();
+ }
+
+ static int checkStyle(int style) {
+ style |= SWT.NO_FOCUS;
+ return checkBits(style, SWT.HORIZONTAL, SWT.VERTICAL, 0, 0, 0, 0);
+ }
+
+ @Override
+ public Point computeSize(int wHint, int hHint, boolean changed) {
+ checkWidget();
+ QSize size = getQProgressBar().sizeHint();
+ return new Point(size.width(), size.height());
+ }
+
+ /**
+ * 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 getQProgressBar().maximum();
+ }
+
+ /**
+ * 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 getQProgressBar().minimum();
+ }
+
+ /**
+ * 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 getQProgressBar().value();
+ }
+
+ /**
+ * Returns the state of the receiver. The value will be one of:
+ * <ul>
+ * <li>{@link SWT#NORMAL}</li>
+ * <li>{@link SWT#ERROR}</li>
+ * <li>{@link SWT#PAUSED}</li>
+ * </ul>
+ *
+ * @return the 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.4
+ */
+ public int getState() {
+ checkWidget();
+ return SWT.NORMAL;
+ }
+
+ @Override
+ void releaseWidget() {
+ stopTimer();
+ super.releaseWidget();
+ }
+
+ void startTimer(QProgressBar progressBar) {
+ stopTimer();
+ // TODO dynamic interval for startTimer
+ timerID = progressBar.startTimer(DELAY);
+ }
+
+ void stopTimer() {
+ if (timerID != -1) {
+ getQProgressBar().killTimer(timerID);
+ }
+ }
+
+ /**
+ * 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();
+ getQProgressBar().setMaximum(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();
+ getQProgressBar().setMinimum(value);
+ }
+
+ /**
+ * 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();
+ getQProgressBar().setValue(value);
+ }
+
+ /**
+ * Sets the state of the receiver. The state must be one of these values:
+ * <ul>
+ * <li>{@link SWT#NORMAL}</li>
+ * <li>{@link SWT#ERROR}</li>
+ * <li>{@link SWT#PAUSED}</li>
+ * </ul>
+ *
+ * @param state
+ * the new 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.4
+ */
+ public void setState(int state) {
+ checkWidget();
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Sash.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Sash.java
new file mode 100644
index 0000000000..399d863b45
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Sash.java
@@ -0,0 +1,387 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.core.QObject;
+import com.trolltech.qt.core.QPoint;
+import com.trolltech.qt.core.QRect;
+import com.trolltech.qt.core.Qt.CursorShape;
+import com.trolltech.qt.core.Qt.MouseButton;
+import com.trolltech.qt.gui.QCursor;
+import com.trolltech.qt.gui.QFrame;
+import com.trolltech.qt.gui.QMouseEvent;
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.qt.gui.QFrame.Shadow;
+import com.trolltech.qt.gui.QFrame.Shape;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * 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.sw
+ * <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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#sash">Sash snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class Sash extends Control {
+ private boolean dragging;
+ private int startX, startY, lastX, lastY;
+
+ /**
+ * 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));
+ }
+
+ @Override
+ protected QWidget createQWidget(int style) {
+ state |= THEME_BACKGROUND;
+ return new QFrame();
+ }
+
+ protected QFrame getQFrame() {
+ return (QFrame) getQWidget();
+ }
+
+ @Override
+ protected void checkAndUpdateBorder() {
+ if ((style & SWT.BORDER) != 0) {
+ getQFrame().setFrameShape(Shape.Panel);
+ getQFrame().setFrameShadow(Shadow.Sunken);
+ } else {
+ getQFrame().setFrameShape(Shape.NoFrame);
+ }
+ }
+
+ /**
+ * Adds the listener to the collection of listeners who will be notified
+ * when the control is selected by the user, 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 when the control is
+ * selected by the user
+ *
+ * @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);
+ }
+
+ @Override
+ 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 += DEFAULT_WIDTH;
+ height += 3;
+ } else {
+ width += 3;
+ height += DEFAULT_HEIGHT;
+ }
+ if (wHint != SWT.DEFAULT) {
+ width = wHint + border * 2;
+ }
+ if (hHint != SWT.DEFAULT) {
+ height = hHint + border * 2;
+ }
+ return new Point(width, height);
+ }
+
+ /**
+ * Removes the listener from the collection of listeners who will be
+ * notified when the control is selected by the user.
+ *
+ * @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);
+ }
+
+ @Override
+ public boolean qtMouseMoveEvent(QObject source, QMouseEvent mouseEvent) {
+ if (source == getQWidget()) {
+ return handleMouseMove(mouseEvent);
+ }
+ return super.qtMouseMoveEvent(source, mouseEvent);
+ }
+
+ @Override
+ public boolean qtMouseButtonPressEvent(QObject source, QMouseEvent mouseEvent) {
+ if (super.qtMouseButtonPressEvent(source, mouseEvent)) {
+ return true; // cancel;
+ }
+ return handleMousePress(mouseEvent);
+ }
+
+ @Override
+ public boolean qtMouseButtonReleaseEvent(QObject source, QMouseEvent mouseEvent) {
+ if (super.qtMouseButtonReleaseEvent(source, mouseEvent)) {
+ return true; // cancel
+ }
+ return handleMouseRelease(mouseEvent);
+ }
+
+ private boolean handleMousePress(QMouseEvent mouseEvent) {
+ if (!isLeftMouseButton(mouseEvent)) {
+ return false;
+ }
+ QPoint pt = mouseEvent.globalPos();
+ QRect rect = getQWidget().frameGeometry();
+ startX = pt.x() - rect.left();
+ startY = pt.y() - rect.top();
+ lastX = rect.left();
+ lastY = rect.top();
+ int width = rect.width();
+ int height = rect.height();
+
+ Event event = new Event();
+ event.x = lastX;
+ event.y = lastY;
+ event.width = width;
+ event.height = height;
+ if ((style & SWT.SMOOTH) == 0) {
+ event.detail = SWT.DRAG;
+ }
+ sendEvent(SWT.Selection, event);
+ if (isDisposed()) {
+ return true;
+ }
+
+ /* Draw the banding rectangle */
+ if (event.doit) {
+ dragging = true;
+ lastX = event.x;
+ lastY = event.y;
+ menuShell().bringToTop();
+ if (isDisposed()) {
+ return true;
+ }
+ if ((style & SWT.SMOOTH) != 0) {
+ setBounds(event.x, event.y, width, height, true, true);
+ // widget could be disposed at this point
+ }
+ }
+ return false;
+ }
+
+ private boolean isLeftMouseButton(QMouseEvent mouseEvent) {
+ return MouseButton.LeftButton.equals(mouseEvent.button()) || mouseEvent.buttons().isSet(MouseButton.LeftButton);
+ }
+
+ private boolean handleMouseRelease(QMouseEvent mouseEvent) {
+ if (!(dragging && isLeftMouseButton(mouseEvent))) {
+ return false;
+ }
+
+ dragging = false;
+ QRect rect = getQWidget().frameGeometry();
+ int width = rect.width();
+ int height = rect.height();
+
+ Event event = new Event();
+ event.x = lastX;
+ event.y = lastY;
+ event.width = width;
+ event.height = height;
+ sendEvent(SWT.Selection, event);
+ if (isDisposed()) {
+ return true;
+ }
+ if (event.doit) {
+ if ((style & SWT.SMOOTH) != 0) {
+ setBounds(event.x, event.y, width, height, true, true);
+ // widget could be disposed at this point
+ }
+ }
+ return false;
+ }
+
+ private boolean handleMouseMove(QMouseEvent mouseEvent) {
+ if (!(dragging && isLeftMouseButton(mouseEvent))) {
+ return false;
+ }
+
+ QPoint pt = mouseEvent.globalPos();
+ QRect rect = getQWidget().frameGeometry();
+ int width = rect.width();
+ int height = rect.height();
+ QRect clientRect = getQWidget().parentWidget().frameGeometry();
+
+ int newX = lastX, newY = lastY;
+ if ((style & SWT.VERTICAL) != 0) {
+ int clientWidth = clientRect.width();
+ newX = Math.min(Math.max(0, pt.x() - startX), clientWidth - width);
+ } else {
+ int clientHeight = clientRect.height();
+ newY = Math.min(Math.max(0, pt.y() - startY), clientHeight - height);
+ }
+ if (newX == lastX && newY == lastY) {
+ return false;
+ }
+
+ /* The event must be sent because doit flag is used */
+ Event event = new Event();
+ event.x = newX;
+ event.y = newY;
+ event.width = width;
+ event.height = height;
+ if ((style & SWT.SMOOTH) == 0) {
+ event.detail = SWT.DRAG;
+ }
+ sendEvent(SWT.Selection, event);
+ if (isDisposed()) {
+ return true;
+ }
+
+ if (event.doit) {
+ lastX = event.x;
+ lastY = event.y;
+ }
+ if ((style & SWT.SMOOTH) != 0) {
+ setBounds(lastX, lastY, width, height, true, true);
+ // widget could be disposed at this point
+ }
+ return false;
+ }
+
+ @Override
+ public boolean qtMouseEnterEvent(Object source) {
+ if (source == getQWidget()) {
+ if ((style & SWT.HORIZONTAL) != 0) {
+ getQWidget().setCursor(new QCursor(CursorShape.SizeVerCursor));
+ } else {
+ getQWidget().setCursor(new QCursor(CursorShape.SizeHorCursor));
+ }
+ }
+ return super.qtMouseEnterEvent(source);
+ }
+
+ @Override
+ public boolean qtMouseLeaveEvent(Object source) {
+ if (source == getQWidget()) {
+ getQWidget().setCursor(new QCursor(CursorShape.ArrowCursor));
+ }
+ return super.qtMouseLeaveEvent(source);
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Scale.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Scale.java
new file mode 100644
index 0000000000..b7ee6cb7c0
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Scale.java
@@ -0,0 +1,494 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.core.Qt.Orientation;
+import com.trolltech.qt.gui.QAbstractSlider;
+import com.trolltech.qt.gui.QSlider;
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.qt.gui.QSlider.TickPosition;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#scale">Scale snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+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));
+ }
+
+ @Override
+ protected QWidget createQWidget(int style) {
+ final Orientation orientation = (style & SWT.HORIZONTAL) != 0 ? Orientation.Horizontal : Orientation.Vertical;
+ return new QSlider(orientation);
+ }
+
+ @Override
+ protected void setupQWidget() {
+ super.setupQWidget();
+ setMinimum(0);
+ setMaximum(100);
+ setIncrement(1);
+ setPageIncrement(10);
+ getQSlider().setTickPosition(TickPosition.TicksBothSides);
+ }
+
+ QSlider getQSlider() {
+ return (QSlider) getQWidget();
+ }
+
+ @Override
+ protected void connectSignals() {
+ getQSlider().actionTriggered.connect(this, "actionTriggered(int)"); //$NON-NLS-1$
+ getQSlider().rangeChanged.connect(this, "rangeChanged(int,int)"); //$NON-NLS-1$
+ getQSlider().sliderMoved.connect(this, "sliderMoved(int)"); //$NON-NLS-1$
+ getQSlider().sliderPressed.connect(this, "sliderPressed()"); //$NON-NLS-1$
+ getQSlider().sliderReleased.connect(this, "sliderReleased()"); //$NON-NLS-1$
+ getQSlider().valueChanged.connect(this, "valueChanged(int)"); //$NON-NLS-1$
+ }
+
+ protected void actionTriggered(int action) {
+ System.out.println("actionTriggered :" + action + " " + getQSlider().value()); //$NON-NLS-1$//$NON-NLS-2$
+ Event event = new Event();
+ if (action == QAbstractSlider.SliderAction.SliderToMinimum.value()) {
+ event.detail = SWT.HOME;
+ } else if (action == QAbstractSlider.SliderAction.SliderToMaximum.value()) {
+ event.detail = SWT.END;
+ } else if (action == QAbstractSlider.SliderAction.SliderSingleStepAdd.value()) {
+ event.detail = SWT.ARROW_DOWN;
+ } else if (action == QAbstractSlider.SliderAction.SliderSingleStepSub.value()) {
+ event.detail = SWT.ARROW_UP;
+ } else if (action == QAbstractSlider.SliderAction.SliderPageStepAdd.value()) {
+ event.detail = SWT.PAGE_UP;
+ } else if (action == QAbstractSlider.SliderAction.SliderPageStepSub.value()) {
+ event.detail = SWT.PAGE_DOWN;
+ } else if (action == QAbstractSlider.SliderAction.SliderMove.value()) {
+ event.detail = SWT.DRAG;
+ } else {
+ return;
+ }
+ // see actionTrigger signal
+ getQSlider().setValue(getQSlider().sliderPosition());
+ sendEvent(SWT.Selection, event);
+ }
+
+ // TODO: implement the events
+ protected void rangeChanged(int min, int max) {
+ System.out.println("rangeChanged :" + min + ", " + max); //$NON-NLS-1$//$NON-NLS-2$
+ }
+
+ protected void sliderMoved(int pos) {
+ System.out.println("sliderMoved :" + pos); //$NON-NLS-1$
+ }
+
+ protected void sliderPressed() {
+ System.out.println("sliderPressed"); //$NON-NLS-1$
+ }
+
+ protected void sliderReleased() {
+ System.out.println("sliderReleased"); //$NON-NLS-1$
+ Event event = new Event();
+ event.detail = SWT.NONE;
+ sendEvent(SWT.Selection, event);
+ }
+
+ protected void valueChanged(int value) {
+ System.out.println("valueChanged :" + value); //$NON-NLS-1$
+ }
+
+ /**
+ * Adds the listener to the collection of listeners who will be notified
+ * when the user changes the receiver's value, by sending it one of the
+ * messages defined in the <code>SelectionListener</code> interface.
+ * <p>
+ * <code>widgetSelected</code> is called when the user changes the
+ * receiver's value. <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);
+ }
+
+ @Override
+ public Point computeSize(int wHint, int hHint, boolean changed) {
+ checkWidget();
+ int border = getBorderWidth();
+ int width = border * 2;
+ int height = border * 2;
+ // default size: this is just the two arrows + thumb
+ Point defaultSize = super.computeSize(wHint, hHint, changed);
+ if ((style & SWT.HORIZONTAL) != 0) {
+ width += defaultSize.y * 6;
+ height += defaultSize.y;
+ } else {
+ width += defaultSize.x;
+ height += defaultSize.x * 6;
+ }
+ if (wHint != SWT.DEFAULT) {
+ width = wHint + border * 2;
+ }
+ if (hHint != SWT.DEFAULT) {
+ height = hHint + border * 2;
+ }
+ return new Point(width, height);
+ }
+
+ // TODO What should happen here?
+ // int defaultForeground() {
+ // return display.getSystemColor(SWT.COLOR_LIST_FOREGROUND);
+ // }
+
+ /**
+ * 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 getQSlider().singleStep();
+ }
+
+ /**
+ * 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 getQSlider().maximum();
+ }
+
+ /**
+ * 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 getQSlider().minimum();
+ }
+
+ /**
+ * 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 getQSlider().pageStep();
+ }
+
+ /**
+ * 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 getQSlider().value();
+ }
+
+ /**
+ * Removes the listener from the collection of listeners who will be
+ * notified when the user changes the receiver's value.
+ *
+ * @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;
+ }
+ if (increment > getMaximum() - getMinimum()) {
+ return;
+ }
+ getQSlider().setSingleStep(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();
+ if (0 <= getMinimum() && getMinimum() < value) {
+ getQSlider().setMaximum(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 (0 <= value && value < getMaximum()) {
+ getQSlider().setMinimum(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;
+ }
+ if (pageIncrement > getMaximum() - getMinimum()) {
+ return;
+ }
+ getQSlider().setPageStep(pageIncrement);
+ getQSlider().setTickInterval(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();
+ getQSlider().setValue(value);
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ScrollBar.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ScrollBar.java
new file mode 100644
index 0000000000..1b839a5fab
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ScrollBar.java
@@ -0,0 +1,876 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.gui.QScrollBar;
+import com.trolltech.qt.gui.QAbstractSlider.SliderAction;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.internal.qt.QtSWTConverter;
+
+/**
+ * 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
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public class ScrollBar extends Widget {
+ private Scrollable parent;
+ private boolean visible = true;
+ private boolean enabled = true;
+
+ /**
+ * 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(style);
+ connectSignals();
+ }
+
+ static int checkStyle(int style) {
+ return checkBits(style, SWT.HORIZONTAL, SWT.VERTICAL, 0, 0, 0, 0);
+ }
+
+ private void createWidget(int style) {
+ if (!parent.isQScrollArea()) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+
+ QScrollBar scrollBar = null;
+ if ((style & SWT.HORIZONTAL) != 0) {
+ scrollBar = parent.getQScrollArea().horizontalScrollBar();
+ } else {
+ scrollBar = parent.getQScrollArea().verticalScrollBar();
+ }
+ if (scrollBar == null) {
+ SWT.error(SWT.ERROR_UNSPECIFIED);
+ }
+ setQWidget(scrollBar);
+ scrollBar.setMinimum(0);
+ scrollBar.setSliderPosition(0);
+ scrollBar.setTracking(false);
+ }
+
+ private void connectSignals() {
+ QScrollBar sb = getQScrollBar();
+ sb.sliderMoved.connect(this, "dragging()"); //$NON-NLS-1$
+ sb.sliderReleased.connect(this, "dragEnd()"); //$NON-NLS-1$
+ sb.actionTriggered.connect(this, "actionTriggered(int)"); //$NON-NLS-1$
+ }
+
+ void dragging() {
+ postSliderEvent(SWT.DRAG);
+ }
+
+ void dragEnd() {
+ postSliderEvent(SWT.NONE);
+ }
+
+ void actionTriggered(int code) {
+ SliderAction action = SliderAction.resolve(code);
+ switch (action) {
+ case SliderSingleStepSub: // button up
+ postSliderEvent(SWT.ARROW_UP);
+ break;
+ case SliderSingleStepAdd: // button down
+ postSliderEvent(SWT.ARROW_DOWN);
+ break;
+ case SliderPageStepSub: // page up
+ postSliderEvent(SWT.PAGE_UP);
+ break;
+ case SliderPageStepAdd: // page down
+ postSliderEvent(SWT.PAGE_DOWN);
+ break;
+ case SliderToMinimum: // at start
+ postSliderEvent(SWT.HOME);
+ break;
+ case SliderToMaximum: // at end
+ postSliderEvent(SWT.END);
+ break;
+ case SliderMove: // at end
+ postSliderEvent(SWT.DRAG);
+ break;
+ default:
+ System.err.println("unknown action: " + action); //$NON-NLS-1$
+ }
+ }
+
+ QScrollBar getQScrollBar() {
+ return (QScrollBar) getQWidget();
+ }
+
+ private void postSliderEvent(int subType) {
+ Event event = new Event();
+ event.detail = subType;
+ postEvent(SWT.Selection, event);
+ }
+
+ @Override
+ void releaseQWidget() {
+ super.releaseQWidget();
+ parent = null;
+ }
+
+ @Override
+ void releaseParent() {
+ super.releaseParent();
+ parent.releaseBar(this);
+ }
+
+ @Override
+ void destroyWidget() {
+ parent.destroyScrollBar(style);
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Adds the listener to the collection of listeners who will be notified
+ * when the user changes the receiver's value, 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 when the user changes
+ * the receiver's value
+ *
+ * @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);
+ }
+
+ /**
+ * Removes the listener from the collection of listeners who will be
+ * notified when the user changes the receiver's value.
+ *
+ * @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);
+ }
+
+ /**
+ * 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 getQScrollBar().singleStep();
+ }
+
+ /**
+ * 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;
+ }
+ getQScrollBar().setSingleStep(value);
+ }
+
+ /**
+ * 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 getQScrollBar().maximum(); // + getQScrollBar().pageStep();
+ }
+
+ /**
+ * 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;
+ }
+ QScrollBar scrollBar = getQScrollBar();
+ int min = scrollBar.minimum();
+ if (value <= min) {
+ return;
+ }
+
+ // int maxValue = value - scrollBar.pageStep();
+ // if (maxValue < min) {
+ // scrollBar.setPageStep(value - min);
+ // maxValue = min;
+ // }
+ //
+ // if (scrollBar.value() > maxValue) {
+ // scrollBar.setValue(maxValue);
+ // }
+ scrollBar.setMaximum(value);
+ }
+
+ /**
+ * 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 getQScrollBar().minimum();
+ }
+
+ /**
+ * 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;
+ }
+ QScrollBar scrollBar = getQScrollBar();
+ int max = scrollBar.maximum();
+ if (value >= max) {
+ return;
+ }
+ //
+ // if (max + pageStep - value < pageStep) {
+ // scrollBar.setPageStep(max + pageStep - value);
+ // scrollBar.setMaximum(value);
+ // }
+ //
+ // if (scrollBar.value() < value) {
+ // scrollBar.setValue(value);
+ // }
+ scrollBar.setMinimum(value);
+ }
+
+ /**
+ * 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 getQScrollBar().pageStep();
+ }
+
+ /**
+ * 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;
+ }
+ getQScrollBar().setPageStep(value);
+ }
+
+ /**
+ * 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 getQScrollBar().sliderPosition();
+ }
+
+ /**
+ * 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();
+ int min = getQScrollBar().minimum();
+ if (selection < min) {
+ selection = min;
+ } else {
+ int max = getQScrollBar().maximum();
+ if (selection > max) {
+ selection = max;
+ }
+ }
+ int value = getQScrollBar().value();
+ if (value != selection) {
+ getQScrollBar().setSliderPosition(selection);
+ }
+ //System.out.println(this);
+ }
+
+ /**
+ * 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();
+ if (!isVisible()) {
+ parent.updateQLayouts();
+ }
+ return QtSWTConverter.convert(getQWidget().size());
+ }
+
+ /**
+ * 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 getQScrollBar().pageStep();
+ }
+
+ /**
+ * 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;
+ }
+ if (value < 1) {
+ return;
+ }
+ int pageStep = getQScrollBar().pageStep();
+ if (value == pageStep) {
+ return;
+ }
+
+ int qMax = getQScrollBar().maximum();
+ int range = qMax + pageStep - getQScrollBar().minimum();
+ if (value > range) {
+ value = range;
+ }
+ int newQMaximum = qMax - (value - pageStep);
+ if (getQScrollBar().value() > newQMaximum) {
+ getQScrollBar().setValue(newQMaximum);
+ }
+
+ getQScrollBar().setPageStep(value);
+
+ getQScrollBar().setMaximum(newQMaximum);
+ }
+
+ /**
+ * 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();
+ setSelection(selection);
+ setMinimum(minimum);
+ setMaximum(maximum);
+ setThumb(thumb);
+ setIncrement(increment);
+ setPageIncrement(pageIncrement);
+ }
+
+ /**
+ * 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 this.visible;
+ }
+
+ /**
+ * 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 getQWidget().isVisible() && parent.isVisible();
+ }
+
+ /**
+ * 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 == getVisible()) {
+ return;
+ }
+ this.visible = visible;
+ getQWidget().setVisible(visible);
+ }
+
+ /**
+ * 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 enabled;
+ }
+
+ /**
+ * 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 getQWidget().isEnabled() && parent.isEnabled();
+ }
+
+ /**
+ * 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();
+ this.enabled = enabled;
+ getQWidget().setEnabled(enabled);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("ScrollBar{"); //$NON-NLS-1$
+ sb.append("orient: "); //$NON-NLS-1$
+ sb.append(((style & SWT.HORIZONTAL) != 0 ? "HORI" : "VERT")); //$NON-NLS-1$ //$NON-NLS-2$
+ sb.append(", selection: "); //$NON-NLS-1$
+ sb.append(getSelection());
+ sb.append(", minimum: "); //$NON-NLS-1$
+ sb.append(getMinimum());
+ sb.append(", maximum: "); //$NON-NLS-1$
+ sb.append(getMaximum());
+ sb.append(", thumb: "); //$NON-NLS-1$
+ sb.append(getThumb());
+ sb.append(", increment: "); //$NON-NLS-1$
+ sb.append(getIncrement());
+ sb.append(", pageIncrement: "); //$NON-NLS-1$
+ sb.append(getPageIncrement());
+ sb.append("}"); //$NON-NLS-1$
+ return sb.toString();
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Scrollable.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Scrollable.java
new file mode 100644
index 0000000000..a9b7b8738a
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Scrollable.java
@@ -0,0 +1,430 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.core.Qt.FocusPolicy;
+import com.trolltech.qt.core.Qt.ScrollBarPolicy;
+import com.trolltech.qt.gui.QAbstractScrollArea;
+import com.trolltech.qt.gui.QLayout;
+import com.trolltech.qt.gui.QScrollArea;
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.qt.gui.QFrame.Shape;
+import com.trolltech.qt.gui.QSizePolicy.Policy;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.internal.qt.QtSWTConverter;
+import org.eclipse.swt.internal.qt.StylableScrollArea;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public abstract class Scrollable extends Control {
+ private ScrollBar horizontalBar;
+ private ScrollBar verticalBar;
+ private QWidget masterWidget;
+ private QWidget contentWidget;
+
+ /**
+ * 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);
+ createScrollBars(style);
+ }
+
+ @Override
+ QWidget createQWidget(int style) {
+ QScrollArea scrollArea = new StylableScrollArea();
+ scrollArea.setFrameShape(Shape.NoFrame);
+ scrollArea.setFocusPolicy(FocusPolicy.TabFocus);
+ scrollArea.setWidgetResizable(!isScrollingEnabled());
+ setQMasterWidget(scrollArea);
+
+ contentWidget = new QWidget();
+ contentWidget.setSizePolicy(Policy.MinimumExpanding, Policy.MinimumExpanding);
+ contentWidget.setProperty("widgetType", "scrollareaContent"); //$NON-NLS-1$//$NON-NLS-2$
+ contentWidget.setContentsMargins(0, 0, 0, 0);
+ contentWidget.resize(0, 0);
+
+ scrollArea.setWidget(contentWidget);
+ scrollArea.resize(0, 0);
+
+ return contentWidget;
+ }
+
+ @Override
+ boolean isQScrollArea() {
+ return getQMasterWidget() instanceof QAbstractScrollArea;
+ }
+
+ protected void setQMasterWidget(QWidget masterWidget) {
+ this.masterWidget = masterWidget;
+ }
+
+ @Override
+ protected QWidget getQMasterWidget() {
+ if (masterWidget != null) {
+ return masterWidget;
+ }
+ return super.getQMasterWidget();
+ }
+
+ @Override
+ protected void updateFocusPolicy() {
+ super.updateFocusPolicy();
+ if ((style & SWT.NO_FOCUS) != 0) {
+ if (isQScrollArea()) {
+ getQMasterWidget().setFocusPolicy(FocusPolicy.NoFocus);
+ }
+ }
+ }
+
+ QAbstractScrollArea getQScrollArea() {
+ return (QAbstractScrollArea) getQMasterWidget();
+ }
+
+ private StylableScrollArea getStylableScrollArea() {
+ return (StylableScrollArea) getQMasterWidget();
+ }
+
+ private void createScrollBars(int style) {
+ if (isQScrollArea()) {
+ if ((style & SWT.H_SCROLL) != 0) {
+ setHBarPolicy(true);
+ if (horizontalBar == null) {
+ horizontalBar = createScrollBar(SWT.HORIZONTAL);
+ }
+ } else {
+ setHBarPolicy(false);
+ }
+
+ if ((style & SWT.V_SCROLL) != 0) {
+ setVBarPolicy(true);
+ if (verticalBar == null) {
+ verticalBar = createScrollBar(SWT.VERTICAL);
+ }
+ } else {
+ setVBarPolicy(false);
+ }
+ }
+ }
+
+ protected boolean isScrollingEnabled() {
+ return (style & SWT.V_SCROLL) != 0 || (style & SWT.H_SCROLL) != 0;
+ }
+
+ protected void setHBarPolicy(boolean enableScrollbar) {
+ getQScrollArea().setHorizontalScrollBarPolicy(
+ enableScrollbar ? ScrollBarPolicy.ScrollBarAsNeeded : ScrollBarPolicy.ScrollBarAlwaysOff);
+ }
+
+ protected void setVBarPolicy(boolean enableScrollbar) {
+ getQScrollArea().setVerticalScrollBarPolicy(
+ enableScrollbar ? ScrollBarPolicy.ScrollBarAsNeeded : ScrollBarPolicy.ScrollBarAlwaysOff);
+ }
+
+ void destroyScrollBar(int type) {
+ if ((type & SWT.HORIZONTAL) != 0) {
+ style &= ~SWT.H_SCROLL;
+ horizontalBar.dispose();
+ horizontalBar = null;
+ }
+ if ((type & SWT.VERTICAL) != 0) {
+ style &= ~SWT.V_SCROLL;
+ verticalBar.dispose();
+ verticalBar = null;
+ }
+ }
+
+ @Override
+ protected void setBounds(int x, int y, int width, int height, boolean move, boolean resize) {
+ super.setBounds(x, y, width, height, move, resize);
+ if (resize && contentWidget != null && isScrollingEnabled()) { //
+ Point prefSize = computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ int newWidth = Math.max(width - getVerticalBarWidth(), prefSize.x);
+ int newHeight = Math.max(height - getHorizontalBarHeight(), prefSize.y);
+ QSize sizeHint = contentWidget.sizeHint();
+ if (sizeHint.isValid()) {
+ newWidth = Math.max(newWidth, sizeHint.width());
+ newHeight = Math.max(newHeight, sizeHint.height());
+ }
+ contentWidget.resize(newWidth, newHeight);
+ }
+ }
+
+ @Override
+ public Object getData(String key) {
+ checkWidget();
+ if (key == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+
+ if ("__Qt_gradientStart".equals(key)) { //$NON-NLS-1$
+ return Color.qt_new(display, getStylableScrollArea().getGradientStart());
+ } else if ("__Qt_gradientEnd".equals(key)) { //$NON-NLS-1$
+ return Color.qt_new(display, getStylableScrollArea().getGradientEnd());
+ } else if ("__Qt_text".equals(key)) { //$NON-NLS-1$
+ return Color.qt_new(display, getStylableScrollArea().getText());
+ } else if ("__Qt_border".equals(key)) { //$NON-NLS-1$
+ return Color.qt_new(display, getStylableScrollArea().getBorder());
+ }
+
+ return super.getData(key);
+ }
+
+ /**
+ * 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();
+ int border = getBorderWidth();
+ int xn = x - border;
+ int yn = y - border;
+ int widthNew = width + 2 * border;
+ int heightNew = height + 2 * border;
+
+ widthNew += getVerticalBarWidth();
+
+ heightNew += getHorizontalBarHeight();
+
+ return new Rectangle(xn, yn, widthNew, heightNew);
+ }
+
+ private int getVerticalBarWidth() {
+ ScrollBar bar = getVerticalBar();
+ if (bar != null) {
+ return bar.getSize().x;
+ }
+ return 0;
+ }
+
+ private int getHorizontalBarHeight() {
+ ScrollBar bar = getHorizontalBar();
+ if (bar != null) {
+ return bar.getSize().y;
+ }
+ return 0;
+ }
+
+ ScrollBar createScrollBar(int type) {
+ ScrollBar bar = new ScrollBar(this, type);
+ if ((state & CANVAS) != 0) {
+ bar.setMaximum(100);
+ bar.setThumb(10);
+ }
+ return bar;
+ }
+
+ /**
+ * 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();
+ if (!isVisible()) {
+ updateQLayouts();
+ }
+
+ Rectangle clientArea = QtSWTConverter.convert(getQWidget().geometry());
+ if (clientArea.width < 0) {
+ clientArea.width = DEFAULT_WIDTH;
+ }
+ if (clientArea.height < 0) {
+ clientArea.height = DEFAULT_HEIGHT;
+ }
+
+ return clientArea;
+ }
+
+ void updateQLayouts() {
+ if (parent != null) {
+ parent.updateQLayouts();
+ }
+ updateLayoutOfQWidget();
+ }
+
+ void updateLayoutOfQWidget() {
+ QLayout layout = getQWidget().layout();
+ if (layout != null) {
+ layout.activate();
+ layout.update();
+ }
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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;
+ }
+
+ @Override
+ void releaseQWidget() {
+ masterWidget = null;
+ contentWidget = null;
+ super.releaseQWidget();
+ }
+
+ void releaseBar(ScrollBar bar) {
+ if (horizontalBar == bar) {
+ horizontalBar = null;
+ }
+ if (verticalBar == bar) {
+ verticalBar = null;
+ }
+ }
+
+ @Override
+ void releaseChildren(boolean destroy) {
+ if (horizontalBar != null) {
+ horizontalBar.release(false);
+ horizontalBar = null;
+ }
+ if (verticalBar != null) {
+ verticalBar.release(false);
+ verticalBar = null;
+ }
+ super.releaseChildren(destroy);
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Shell.java
new file mode 100644
index 0000000000..662756b606
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Shell.java
@@ -0,0 +1,1490 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.core.QObject;
+import com.trolltech.qt.core.QPoint;
+import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.core.Qt.FocusPolicy;
+import com.trolltech.qt.core.Qt.FocusReason;
+import com.trolltech.qt.core.Qt.WindowFlags;
+import com.trolltech.qt.core.Qt.WindowModality;
+import com.trolltech.qt.core.Qt.WindowState;
+import com.trolltech.qt.core.Qt.WindowStates;
+import com.trolltech.qt.core.Qt.WindowType;
+import com.trolltech.qt.gui.QDialog;
+import com.trolltech.qt.gui.QMainWindow;
+import com.trolltech.qt.gui.QMouseEvent;
+import com.trolltech.qt.gui.QScrollArea;
+import com.trolltech.qt.gui.QStyle;
+import com.trolltech.qt.gui.QVBoxLayout;
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.qt.gui.QWindowStateChangeEvent;
+import com.trolltech.qt.gui.QFrame.Shape;
+import com.trolltech.qt.gui.QSizePolicy.Policy;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.ShellListener;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.graphics.Region;
+import org.eclipse.swt.internal.qt.QtSWTConverter;
+
+/**
+ * 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
+ * @see <a href="http://www.eclipse.org/swt/snippets/#shell">Shell snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ */
+public class Shell extends Decorations {
+ Menu activeMenu;
+ boolean fullScreen, wasMaximized, modified;
+ Control lastActive;
+ private QMainWindow mainWindow;
+ private QDialog dialogWindow;
+ private QStyle oldStyle;
+
+ /**
+ * 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#TOOL
+ * @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#TOOL
+ * @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, false);
+ }
+
+ Shell(Display display, Shell parent, int style, boolean embedded) {
+ 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;
+ // if (handle != 0 && !embedded) {
+ // state |= FOREIGN_HANDLE;
+ // }
+ createWidget(parent, style);
+ }
+
+ /**
+ * 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, false);
+ }
+
+ @Override
+ QWidget createQWidget(int style) {
+ QScrollArea scrollArea;
+ if (parent == null) {
+ // new window
+ mainWindow = new QMainWindow(null, createWindowFlags(style));
+ scrollArea = new QScrollArea(mainWindow);
+ mainWindow.setCentralWidget(scrollArea);
+ } else {
+ // new dialog
+ dialogWindow = new QDialog(parent.getQWidget(), createWindowFlags(style));
+ scrollArea = new QScrollArea(dialogWindow);
+
+ QVBoxLayout layout = new QVBoxLayout(dialogWindow);
+ layout.addWidget(scrollArea);
+ layout.setContentsMargins(0, 0, 0, 0);
+ }
+
+ scrollArea.setFrameShape(Shape.NoFrame);
+ scrollArea.setContentsMargins(0, 0, 0, 0);
+ scrollArea.setWidgetResizable(true);
+ setQMasterWidget(scrollArea);
+
+ QWidget contentWidget = new QWidget();
+ contentWidget.setProperty("widgetType", "scrollareaContent"); //$NON-NLS-1$ //$NON-NLS-2$
+ contentWidget.setSizePolicy(Policy.MinimumExpanding, Policy.MinimumExpanding);
+ contentWidget.setContentsMargins(0, 0, 0, 0);
+ contentWidget.resize(0, 0);
+ scrollArea.setWidget(contentWidget);
+
+ scrollArea.resize(0, 0);
+
+ int policy = getWindowControl().focusPolicy().value() & ~FocusPolicy.ClickFocus.value();
+ getWindowControl().setFocusPolicy(FocusPolicy.resolve(policy));
+
+ state |= CANVAS;
+
+ return scrollArea.widget();
+ }
+
+ private WindowFlags createWindowFlags(int style) {
+ int flags = parent == null ? WindowType.Window.value() : WindowType.Dialog.value()
+ | WindowModality.WindowModal.value();
+ flags |= WindowType.CustomizeWindowHint.value();
+ if ((style & SWT.CLOSE) != 0) {
+ flags |= WindowType.WindowSystemMenuHint.value() | WindowType.WindowCloseButtonHint.value();
+ }
+ if ((style & SWT.MIN) != 0) {
+ flags |= WindowType.WindowMinimizeButtonHint.value();
+ }
+ if ((style & SWT.MAX) != 0) {
+ flags |= WindowType.WindowMaximizeButtonHint.value();
+ }
+ if ((style & SWT.NO_TRIM) != 0) {
+ flags |= WindowType.FramelessWindowHint.value();
+ }
+ if ((style & SWT.TITLE) != 0) {
+ flags |= WindowType.WindowTitleHint.value();
+ }
+ if ((style & SWT.ON_TOP) != 0) {
+ flags |= WindowType.WindowStaysOnTopHint.value();
+ }
+ return new WindowFlags(flags);
+ }
+
+ @Override
+ protected void setupQWidget() {
+ getWindowControl().adjustSize();
+ // no setup
+ }
+
+ @Override
+ void registerQWidget() {
+ super.registerQWidget();
+ display.addControl(getWindowControl(), this);
+ }
+
+ @Override
+ void deregisterQWidget() {
+ display.removeControl(getWindowControl());
+ super.deregisterQWidget();
+ }
+
+ @Override
+ protected QWidget getQMasterWidget() {
+ return getWindowControl();
+ }
+
+ @Override
+ QWidget getMenuContainer() {
+ return getWindowControl();
+ }
+
+ QDialog getQDialog() {
+ return dialogWindow;
+ }
+
+ boolean isDialog() {
+ return dialogWindow != null;
+ }
+
+ @Override
+ public void setStyleSheet(String style) {
+ if (style == null || style.trim().length() == 0) {
+ getWindowControl().setStyleSheet(null);
+ if (oldStyle != null) {
+ getWindowControl().setStyle(oldStyle);
+ oldStyle = null;
+ }
+ } else {
+ oldStyle = getWindowControl().style();
+ getWindowControl().setStyleSheet(style);
+ }
+ updateLayout();
+ }
+
+ @Override
+ public void updateStyleSheet() {
+ if (null != getWindowControl().style()) {
+ getWindowControl().setStyle(getWindowControl().style());
+ updateLayout();
+ }
+ }
+
+ @Override
+ protected QWidget getWindowControl() {
+ return mainWindow != null ? mainWindow : dialogWindow;
+ }
+
+ /**
+ * Invokes platform specific functionality to allocate a new shell that is
+ * embedded.
+ * <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 qMetrics
+ * the handle for the shell
+ * @return a new shell object containing the specified display and handle
+ */
+ public static Shell qt_new(Display display) {
+ return new Shell(display, null, SWT.NO_TRIM, true);
+ }
+
+ static int checkStyle(int style) {
+ style = Decorations.checkStyle(style);
+ style &= ~SWT.TRANSPARENT;
+ 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);
+ }
+
+ /**
+ * 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();
+ }
+
+ @Override
+ void enableWidget(boolean enabled) {
+ Control oldFocus = display.getFocusControl();
+ super.enableWidget(enabled);
+ if (enabled) {
+ _update();
+ } else {
+
+ // All children were looped through and disabled by QWidget unless
+ // they
+ // were explicitly disabled. SWT behavior is not to disable the
+ // dialog
+ // Shells so we have to restore their states.
+ Shell shells[] = getShells();
+ for (int i = 0; i < shells.length; ++i) {
+ if (shells[i].parent == this) {
+ if (shells[i].getEnabled()) {
+ shells[i].getQWidget().setEnabled(true);
+ }
+ }
+ }
+ // Because dialog Shell might have been temporarily disabled the
+ // focus might
+ // have been lost and must be restored.
+ if (oldFocus != null) {
+ oldFocus.menuShell().restoreFocus();
+ }
+ }
+ }
+
+ @Override
+ Control findBackgroundControl() {
+ return background != null || backgroundImage != null ? this : null;
+ }
+
+ @Override
+ Cursor findCursor() {
+ return cursor;
+ }
+
+ @Override
+ Control findThemeControl() {
+ return null;
+ }
+
+ void fixShell(Shell newShell, Control control) {
+ if (this == newShell) {
+ return;
+ }
+ if (control == lastActive) {
+ setActiveControl(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(Button)
+ * @see Shell#open
+ * @see Shell#setActive
+ */
+ public void forceActive() {
+ checkWidget();
+ if (!isVisible()) {
+ return;
+ }
+ bringToTop();
+ }
+
+ void forceResize() {
+ /* Do nothing */
+ }
+
+ /**
+ * Returns the receiver's alpha value. The alpha value is between 0
+ * (transparent) and 255 (opaque).
+ *
+ * @return the alpha 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.4
+ */
+ public int getAlpha() {
+ checkWidget();
+ double opacity = getQWidget().windowOpacity();
+ return (int) (255 * opacity);
+ }
+
+ @Override
+ public Rectangle getBounds() {
+ checkWidget();
+ QPoint pos = getWindowControl().pos();
+ QSize size = getWindowControl().size();
+ return new Rectangle(pos.x(), pos.y(), size.width(), size.height());
+ }
+
+ @Override
+ public Rectangle getClientArea() {
+ checkWidget();
+ if (!isVisible()) {
+ updateQLayouts();
+ }
+
+ Rectangle clientArea = QtSWTConverter.convert(getQWidget().rect());
+ if (clientArea.width < 0) {
+ clientArea.width = 0;
+ }
+ if (clientArea.height < 0) {
+ clientArea.height = 0;
+ }
+
+ return clientArea;
+ }
+
+ /**
+ * Returns <code>true</code> if the receiver is currently in fullscreen
+ * state, and false otherwise.
+ * <p>
+ *
+ * @return the fullscreen 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.4
+ */
+ public boolean getFullScreen() {
+ checkWidget();
+ return fullScreen;
+ }
+
+ /**
+ * 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 how to do it with Qt?
+ return SWT.NONE;
+ }
+
+ @Override
+ public Point getLocation() {
+ checkWidget();
+ if (getWindowControl().isMinimized()) {
+ return super.getLocation();
+ }
+ return QtSWTConverter.convert(getWindowControl().pos());
+ }
+
+ @Override
+ public boolean getMaximized() {
+ checkWidget();
+ return !fullScreen && super.getMaximized();
+ }
+
+ /**
+ * 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();
+ return QtSWTConverter.convert(getWindowControl().minimumSize());
+ }
+
+ /**
+ * Gets the receiver's modified state.
+ *
+ * </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.5
+ */
+ public boolean getModified() {
+ checkWidget();
+ return modified;
+ }
+
+ /**
+ * 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
+ *
+ */
+ @Override
+ public Region getRegion() {
+ /* This method is needed for the @since 3.0 Javadoc */
+ checkWidget();
+ return region;
+ }
+
+ @Override
+ public Shell getShell() {
+ checkWidget();
+ return this;
+ }
+
+ @Override
+ public Point getSize() {
+ checkWidget();
+ return QtSWTConverter.convert(getWindowControl().size());
+ }
+
+ /**
+ * Returns an array containing all shells which are descendants 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;
+ }
+
+ @Override
+ protected Composite findDeferredControl() {
+ return layoutCount > 0 ? this : null;
+ }
+
+ // @Override
+ // public boolean isEnabled() {
+ // checkWidget();
+ // return getEnabled();
+ //}
+
+ /**
+ * 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(Button)
+ * @see Shell#setActive
+ * @see Shell#forceActive
+ */
+ public void open() {
+ checkWidget();
+ updateLayout();
+ setVisible(true);
+ bringToTop();
+ if (isDisposed()) {
+ return;
+ }
+ if (!restoreFocus() && !traverseGroup(true)) {
+ setFocus(FocusReason.OtherFocusReason);
+ }
+ }
+
+ @Override
+ public boolean print(GC gc) {
+ checkWidget();
+ if (gc == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (gc.isDisposed()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ //TODO
+ return false;
+ }
+
+ @Override
+ 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);
+ }
+
+ @Override
+ void releaseParent() {
+ /* Do nothing */
+ }
+
+ @Override
+ void releaseQWidget() {
+ getWindowControl().close();
+ super.releaseQWidget();
+ mainWindow = null;
+ dialogWindow = null;
+ }
+
+ @Override
+ void releaseWidget() {
+ super.releaseWidget();
+ lastActive = null;
+ }
+
+ @Override
+ void removeMenu(Menu menu) {
+ super.removeMenu(menu);
+ if (menu == activeMenu) {
+ activeMenu = 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(Button)
+ * @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);
+ }
+ }
+ }
+
+ /**
+ * Sets the receiver's alpha value which must be between 0 (transparent) and
+ * 255 (opaque).
+ * <p>
+ * This operation requires the operating system's advanced widgets subsystem
+ * which may not be available on some platforms.
+ * </p>
+ *
+ * @param alpha
+ * the alpha 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.4
+ */
+ public void setAlpha(int alpha) {
+ checkWidget();
+ if (alpha < 0 || alpha > 255) {
+ return;
+ }
+ getQWidget().setWindowOpacity((double) alpha / 255);
+ }
+
+ @Override
+ protected void setBounds(int x, int y, int width, int height, boolean move, boolean resize) {
+ if (fullScreen) {
+ setFullScreen(false);
+ }
+
+ Rectangle geometry = QtSWTConverter.convert(getWindowControl().frameGeometry());
+ if (move) {
+ int oldX = geometry.x;
+ int oldY = geometry.y;
+ boolean moved = oldX != x || oldY != y;
+ if (moved) {
+ getWindowControl().move(x, y);
+ }
+ }
+
+ if (resize) {
+ int oldW = geometry.width;
+ int oldH = geometry.height;
+ boolean resized = oldW != width || oldH != height;
+
+ if (resized) {
+ if ((style & SWT.RESIZE) == 0) {
+ unlockSize();
+ }
+
+ getWindowControl().resize(width, height);
+
+ if ((style & SWT.RESIZE) == 0) {
+ getWindowControl().setFixedSize(Math.max(0, width), Math.max(0, height));
+ }
+ }
+ }
+ }
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ checkWidget();
+ if (super.getEnabled() == enabled) {
+ return;
+ }
+ super.setEnabled(enabled);
+ if (enabled && getWindowControl().isActiveWindow()) {
+ if (!restoreFocus()) {
+ traverseGroup(true);
+ }
+ }
+ }
+
+ /**
+ * Sets the full screen state of the receiver. If the argument is
+ * <code>true</code> causes the receiver to switch to the full screen state,
+ * and if the argument is <code>false</code> and the receiver was previously
+ * switched into full screen state, causes the receiver to switch back to
+ * either the maximmized or normal states.
+ * <p>
+ * Note: The result of intermixing calls to <code>setFullScreen(true)</code>, <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 fullScreen
+ * the new fullscreen 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.4
+ */
+ public void setFullScreen(boolean fullScreen) {
+ checkWidget();
+ if (this.fullScreen == fullScreen) {
+ return;
+ }
+ this.fullScreen = fullScreen;
+ if (fullScreen) {
+ getWindowControl().showFullScreen();
+ } else {
+ getWindowControl().showNormal();
+ }
+ }
+
+ /**
+ * 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();
+ getQWidget().setMinimumSize(width, height);
+ }
+
+ /**
+ * 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);
+ }
+
+ /**
+ * Sets the receiver's modified state as specified by the argument.
+ *
+ * @param modified
+ * the new modified state for the receiver
+ *
+ * </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.5
+ */
+ public void setModified(boolean modified) {
+ checkWidget();
+ this.modified = modified;
+ }
+
+ /**
+ * 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
+ *
+ */
+ @Override
+ public void setRegion(Region region) {
+ checkWidget();
+ if ((style & SWT.NO_TRIM) == 0) {
+ return;
+ }
+ super.setRegion(region);
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ checkWidget();
+ int mask = SWT.PRIMARY_MODAL | SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL;
+ if ((style & mask) != 0) {
+ if (visible) {
+ display.setModalShell(this);
+ if ((style & (SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) != 0) {
+ display.setModalDialog(null);
+ }
+ Control control = display.getFocusControl();
+ if (control != null && !control.isActive()) {
+ bringToTop();
+ if (isDisposed()) {
+ return;
+ }
+ }
+ getWindowControl().setWindowModality(getModalityFromStyle());
+ QWidget mouseGrabber = QWidget.mouseGrabber();
+ if (mouseGrabber != null) {
+ mouseGrabber.releaseMouse();
+ }
+ } else {
+ display.clearModal(this);
+ }
+ } else {
+ updateModal();
+ }
+
+ _setVisible(getWindowControl(), visible);
+ }
+
+ private WindowModality getModalityFromStyle() {
+ if ((style & SWT.SYSTEM_MODAL) != 0) {
+ return WindowModality.ApplicationModal;
+ }
+ if ((style & SWT.APPLICATION_MODAL) != 0) {
+ return WindowModality.ApplicationModal;
+ }
+ if ((style & SWT.PRIMARY_MODAL) != 0) {
+ return WindowModality.ApplicationModal;
+ }
+ return WindowModality.NonModal;
+ }
+
+ @Override
+ boolean traverseEscape() {
+ if (parent == null) {
+ return false;
+ }
+ if (!isVisible() || !isEnabled()) {
+ return false;
+ }
+ close();
+ return true;
+ }
+
+ void updateModal() {
+ }
+
+ @Override
+ public boolean qtCloseEvent() {
+ return closeWidget();
+ }
+
+ @Override
+ public boolean qtWindowStateChangeEvent(QObject source, QWindowStateChangeEvent event) {
+ if (source != getWindowControl()) {
+ return false;
+ }
+ WindowStates oldState = event.oldState();
+ WindowStates newState = getWindowControl().windowState();
+ if (oldState.isSet(WindowState.WindowMinimized) && !newState.isSet(WindowState.WindowMinimized)) {
+ sendEvent(SWT.Deiconify);
+ return false;
+ }
+ if (!oldState.isSet(WindowState.WindowMinimized) && newState.isSet(WindowState.WindowMinimized)) {
+ sendEvent(SWT.Iconify);
+ menuShell().saveFocus();
+ return false;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean qtMouseButtonPressEvent(QObject source, QMouseEvent mouseEvent) {
+ if (source == getQWidget()) {
+ QWidget clickTarget = getQWidget().childAt(mouseEvent.x(), mouseEvent.y());
+ if (clickTarget != null && clickTarget != getQWidget()) {
+ Widget swtControl = display.findControl(clickTarget);
+ if (swtControl instanceof Control) {
+ setActiveControl((Control) swtControl);
+ }
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Slider.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Slider.java
new file mode 100644
index 0000000000..b85060a66c
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Slider.java
@@ -0,0 +1,632 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.core.Qt.FocusPolicy;
+import com.trolltech.qt.core.Qt.Orientation;
+import com.trolltech.qt.gui.QAbstractSlider;
+import com.trolltech.qt.gui.QScrollBar;
+import com.trolltech.qt.gui.QWidget;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * 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
+ * @see <a href="http://www.eclipse.org/swt/snippets/#slider">Slider
+ * snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class Slider extends Control {
+
+ private int thumb; // TODO Not supported by Qt?
+ private int maximum;
+
+ /**
+ * 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));
+ }
+
+ @Override
+ protected void connectSignals() {
+ getQScrollBar().actionTriggered.connect(this, "actionTriggered(int)"); //$NON-NLS-1$
+ getQScrollBar().rangeChanged.connect(this, "rangeChanged(int,int)"); //$NON-NLS-1$
+ getQScrollBar().sliderMoved.connect(this, "sliderMoved(int)"); //$NON-NLS-1$
+ getQScrollBar().sliderPressed.connect(this, "sliderPressed()"); //$NON-NLS-1$
+ getQScrollBar().sliderReleased.connect(this, "sliderReleased()"); //$NON-NLS-1$
+ getQScrollBar().valueChanged.connect(this, "valueChanged(int)"); //$NON-NLS-1$
+ }
+
+ protected void actionTriggered(int action) {
+ System.out.println("actionTriggered :" + action + " " + getQScrollBar().value()); //$NON-NLS-1$//$NON-NLS-2$
+ Event event = new Event();
+ if (action == QAbstractSlider.SliderAction.SliderToMinimum.value()) {
+ event.detail = SWT.HOME;
+ } else if (action == QAbstractSlider.SliderAction.SliderToMaximum.value()) {
+ event.detail = SWT.END;
+ } else if (action == QAbstractSlider.SliderAction.SliderSingleStepAdd.value()) {
+ event.detail = SWT.ARROW_DOWN;
+ } else if (action == QAbstractSlider.SliderAction.SliderSingleStepSub.value()) {
+ event.detail = SWT.ARROW_UP;
+ } else if (action == QAbstractSlider.SliderAction.SliderPageStepAdd.value()) {
+ event.detail = SWT.PAGE_UP;
+ } else if (action == QAbstractSlider.SliderAction.SliderPageStepSub.value()) {
+ event.detail = SWT.PAGE_DOWN;
+ } else if (action == QAbstractSlider.SliderAction.SliderMove.value()) {
+ event.detail = SWT.DRAG;
+ } else {
+ return;
+ }
+ // see actionTrigger signal
+ getQScrollBar().setValue(getQScrollBar().sliderPosition());
+ sendEvent(SWT.Selection, event);
+ }
+
+ protected void rangeChanged(int min, int max) {
+ System.out.println("rangeChanged :" + min + ", " + max); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ protected void sliderMoved(int pos) {
+ System.out.println("sliderMoved :" + pos); //$NON-NLS-1$
+ }
+
+ protected void sliderPressed() {
+ System.out.println("sliderPressed"); //$NON-NLS-1$
+ }
+
+ protected void sliderReleased() {
+ System.out.println("sliderReleased"); //$NON-NLS-1$
+ Event event = new Event();
+ event.detail = SWT.NONE;
+ sendEvent(SWT.Selection, event);
+ }
+
+ protected void valueChanged(int value) {
+ System.out.println("valueChanged :" + value); //$NON-NLS-1$
+ }
+
+ @Override
+ protected QWidget createQWidget(int style) {
+ final Orientation orientation = (style & SWT.HORIZONTAL) != 0 ? Orientation.Horizontal : Orientation.Vertical;
+ return new QScrollBar(orientation);
+ }
+
+ @Override
+ protected void setupQWidget() {
+ super.setupQWidget();
+ getQScrollBar().setFocusPolicy(FocusPolicy.WheelFocus);
+ setThumb(10);
+ setMinimum(0);
+ setMaximum(100);
+ setIncrement(1);
+ setPageIncrement(10);
+ }
+
+ QAbstractSlider getQScrollBar() {
+ return (QAbstractSlider) getQWidget();
+ }
+
+ /**
+ * Adds the listener to the collection of listeners who will be notified
+ * when the user changes the receiver's value, 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 when the user changes
+ * the receiver's value
+ *
+ * @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);
+ }
+
+ @Override
+ public Point computeSize(int wHint, int hHint, boolean changed) {
+ checkWidget();
+ int border = getBorderWidth();
+ int width = border * 2;
+ int height = border * 2;
+ // default size: this is just the two arrows + thumb
+ Point defaultSize = super.computeSize(wHint, hHint, changed);
+ if ((style & SWT.HORIZONTAL) != 0) {
+ width += defaultSize.y * 10;
+ height += defaultSize.y;
+ } else {
+ width += defaultSize.x;
+ height += defaultSize.x * 10;
+ }
+ if (wHint != SWT.DEFAULT) {
+ width = wHint + border * 2;
+ }
+ if (hHint != SWT.DEFAULT) {
+ height = hHint + border * 2;
+ }
+ return new Point(width, height);
+ }
+
+ // TODO Is this ok?
+
+ // int defaultBackground() {
+ // return OS.GetSysColor(OS.COLOR_SCROLLBAR);
+ // }
+ //
+ // int defaultForeground() {
+ // return OS.GetSysColor(OS.COLOR_BTNFACE);
+ // }
+
+ /**
+ * 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 getQScrollBar().singleStep();
+ }
+
+ /**
+ * 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 maximum;
+ }
+
+ /**
+ * 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 getQScrollBar().minimum();
+ }
+
+ /**
+ * 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 getQScrollBar().pageStep();
+ }
+
+ /**
+ * 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 getQScrollBar().value();
+ }
+
+ /**
+ * 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 thumb;
+ }
+
+ /**
+ * Removes the listener from the collection of listeners who will be
+ * notified when the user changes the receiver's value.
+ *
+ * @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;
+ }
+ getQScrollBar().setSingleStep(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 || value <= getQScrollBar().minimum()) {
+ return;
+ }
+ maximum = value;
+ getQScrollBar().setMaximum(maximum - thumb);
+ }
+
+ /**
+ * 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 || value >= getQScrollBar().maximum()) {
+ return;
+ }
+ getQScrollBar().setMinimum(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;
+ }
+ getQScrollBar().setPageStep(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();
+ getQScrollBar().setValue(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;
+ }
+ this.thumb = value;
+ setMaximum(maximum); // adjust the maximum which depends on the thumb
+ }
+
+ /**
+ * 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;
+ }
+ setMinimum(minimum);
+ setMaximum(maximum);
+ setThumb(thumb);
+ setSelection(selection);
+ setIncrement(increment);
+ setPageIncrement(pageIncrement);
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Spinner.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Spinner.java
new file mode 100644
index 0000000000..19c26a6a6e
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Spinner.java
@@ -0,0 +1,948 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.gui.QApplication;
+import com.trolltech.qt.gui.QDoubleSpinBox;
+import com.trolltech.qt.gui.QWidget;
+
+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.graphics.Rectangle;
+
+/**
+ * Instances of this class are selectable user interface objects that allow the
+ * user to enter and modify numeric values.
+ * <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>
+ * <p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>READ_ONLY, WRAP</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Selection, Modify, Verify</dd>
+ * </dl>
+ * </p>
+ * <p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#spinner">Spinner
+ * snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ *
+ * @since 3.1
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class Spinner extends Composite {
+ boolean ignoreModify;
+ int pageIncrement, digits;
+ int selection = 0;
+
+ /**
+ * the operating system limit for the number of characters that the text
+ * field in an instance of this class can hold
+ *
+ * @since 3.4
+ */
+ 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 {
+ //TODO: 3 is just an imaginary value. see bug 161
+ LIMIT = 3;
+ }
+
+ /**
+ * 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));
+
+ // setting default values of the SWT widget:
+ ((QDoubleSpinBox) getQWidget()).setDecimals(0);
+ ((QDoubleSpinBox) getQWidget()).setMaximum(100);
+
+ ((QDoubleSpinBox) getQWidget()).setSingleStep(getIncrement() / Math.pow(10, this.digits));
+ }
+
+ @Override
+ protected QWidget createQWidget(int style) {
+ state &= ~(CANVAS | THEME_BACKGROUND);
+ QWidget spinner = new QDoubleSpinBox();
+ connectSignals(spinner);
+ return spinner;
+ }
+
+ 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);
+ }
+
+ @Override
+ protected void checkSubclass() {
+ if (!isValidSubclass()) {
+ error(SWT.ERROR_INVALID_SUBCLASS);
+ }
+ }
+
+ private void connectSignals(QWidget spinner) {
+ ((QDoubleSpinBox) spinner).valueChanged.connect(this, "valueChanged()"); //$NON-NLS-1$
+ //TODO: connection for selection and verify event is missing, but there's not suitable event in QDoubleSpinBox (bug 159)
+ }
+
+ protected void valueChanged() {
+ Event event = new Event();
+ sendEvent(SWT.Modify, event);
+ }
+
+ /**
+ * 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 the user, 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 when the control is
+ * selected by the user
+ *
+ * @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);
+ }
+
+ @Override
+ public Point computeSize(int wHint, int hHint, boolean changed) {
+ checkWidget();
+ QSize size = ((QDoubleSpinBox) getQWidget()).sizeHint();
+ return new Point(size.width(), size.height());
+ }
+
+ @Override
+ public Rectangle computeTrim(int x, int y, int width, int height) {
+ checkWidget();
+ return super.computeTrim(x, y, 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>
+ */
+ public void copy() {
+ checkWidget();
+ QApplication.clipboard().setText(((QDoubleSpinBox) getQWidget()).text());
+ }
+
+ /**
+ * 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;
+ }
+ QApplication.clipboard().setText(((QDoubleSpinBox) getQWidget()).text());
+ ((QDoubleSpinBox) getQWidget()).setValue(0);
+ this.selection = 0;
+ }
+
+ @Override
+ void enableWidget(boolean enabled) {
+ super.enableWidget(enabled);
+ }
+
+ @Override
+ void deregisterQWidget() {
+ super.deregisterQWidget();
+ }
+
+ @Override
+ boolean hasFocus() {
+ return getQWidget().hasFocus();
+ }
+
+ /**
+ * 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;
+ }
+
+ String getDecimalSeparator() {
+ // TODO check locale
+ return "."; //$NON-NLS-1$
+ }
+
+ /**
+ * 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();
+ double step = ((QDoubleSpinBox) getQWidget()).singleStep();
+ int qstep = (int) (step * Math.pow(10, this.digits));
+ return qstep;
+ }
+
+ /**
+ * 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) (((QDoubleSpinBox) getQWidget()).maximum() * Math.pow(10, this.digits));
+ }
+
+ /**
+ * 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) (((QDoubleSpinBox) getQWidget()).minimum() * Math.pow(10, this.digits));
+ }
+
+ /**
+ * 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 (int) ((QDoubleSpinBox) getQWidget()).singleStep();
+ }
+
+ /**
+ * 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();
+ int qselection = (int) (((QDoubleSpinBox) getQWidget()).value() * Math.pow(10, this.digits));
+ this.selection = qselection;
+ return qselection;
+ }
+
+ int getSelectionText(boolean[] parseFail) {
+ // TODO
+ return -1;
+ }
+
+ /**
+ * 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>
+ *
+ * @since 3.4
+ */
+ public String getText() {
+ checkWidget();
+ return ((QDoubleSpinBox) getQWidget()).text();
+ }
+
+ /**
+ * 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>Spinner.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
+ *
+ * @since 3.4
+ */
+ public int getTextLimit() {
+ checkWidget();
+ //TODO: not sure about this...
+ int maxChars = String.valueOf(getMaximum()).trim().length();
+ int minChars = String.valueOf(getMinimum()).trim().length();
+ return maxChars > minChars ? maxChars : minChars;
+ }
+
+ /**
+ * 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() {
+ boolean isNumber = true;
+ double pasteNumber;
+
+ checkWidget();
+ if ((style & SWT.READ_ONLY) != 0) {
+ return;
+ }
+ String pasteText = QApplication.clipboard().text();
+
+ try {
+ pasteNumber = Double.parseDouble(pasteText);
+ } catch (NumberFormatException e) {
+ isNumber = false;
+ return; // it's not a valid number, so just return and don't paste anything
+ }
+ if (isNumber && pasteNumber <= getMaximum() && pasteNumber >= getMinimum()) {
+ this.selection = Integer.valueOf(QApplication.clipboard().text());
+ ((QDoubleSpinBox) getQWidget()).setValue(pasteNumber);
+ }
+ }
+
+ @Override
+ void registerQWidget() {
+ super.registerQWidget();
+ }
+
+ @Override
+ void releaseQWidget() {
+ super.releaseQWidget();
+ }
+
+ /**
+ * 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 by the user.
+ *
+ * @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);
+ }
+ if (value == this.digits) {
+ return;
+ }
+
+ this.digits = value;
+ ((QDoubleSpinBox) getQWidget()).setDecimals(value);
+ ((QDoubleSpinBox) getQWidget()).setValue(selection / Math.pow(10, 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;
+ }
+ ((QDoubleSpinBox) getQWidget()).setSingleStep(value / Math.pow(10, this.digits));
+ }
+
+ /**
+ * 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();
+ ((QDoubleSpinBox) getQWidget()).setMaximum(value / Math.pow(10, this.digits));
+ }
+
+ /**
+ * Sets the minimum value that the receiver will allow. This new value will
+ * be ignored if it 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 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();
+ ((QDoubleSpinBox) getQWidget()).setMinimum(value / Math.pow(10, this.digits));
+ }
+
+ /**
+ * 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; // TODO: see bug 160
+ }
+
+ /**
+ * 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.selection = value;
+ ((QDoubleSpinBox) getQWidget()).setDecimals(this.digits);
+ ((QDoubleSpinBox) getQWidget()).setValue(value / Math.pow(10, digits));
+
+ }
+
+ /**
+ * 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(Spinner.LIMIT)</code>. Specifying a limit value larger
+ * than <code>Spinner.LIMIT</code> sets the receiver's limit to
+ * <code>Spinner.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
+ *
+ * @since 3.4
+ */
+ public void setTextLimit(int limit) {
+ checkWidget();
+ if (limit == 0) {
+ error(SWT.ERROR_CANNOT_BE_ZERO);
+ }
+
+ if (limit < 0 || limit > LIMIT) {
+ limit = LIMIT;
+ }
+
+ //TODO setting the text limit to the QDoubleSpinBox
+ }
+
+ /**
+ * 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 (maximum <= minimum) {
+ return;
+ }
+ if (digits < 0) {
+ return;
+ }
+ if (increment < 1) {
+ return;
+ }
+ if (pageIncrement < 1) {
+ return;
+ }
+ this.selection = Math.min(Math.max(minimum, selection), maximum);
+ ((QDoubleSpinBox) getQWidget()).setValue(this.selection);
+ setIncrement(increment);
+ this.pageIncrement = pageIncrement;
+ this.digits = digits;
+ }
+
+ 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;
+ // }
+ // if (string.length() > 0) {
+ // int[] min = new int[1];
+ // OS.SendMessage(hwndUpDown, OS.UDM_GETRANGE32, min, null);
+ // if (min[0] < 0 && string.charAt(0) == '-')
+ // index++;
+ // }
+ // 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 );
+ // }
+ // sendEvent(SWT.Verify, event);
+ // if (!event.doit || isDisposed())
+ return null;
+ // return event.text;
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TabFolder.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TabFolder.java
new file mode 100644
index 0000000000..90fd790cba
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TabFolder.java
@@ -0,0 +1,755 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import java.util.ArrayList;
+
+import com.trolltech.qt.gui.QTabWidget;
+import com.trolltech.qt.gui.QVBoxLayout;
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.qt.gui.QSizePolicy.Policy;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.internal.qt.QtSWTConverter;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#tabfolder">TabFolder,
+ * TabItem snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class TabFolder extends Composite {
+ private java.util.List<TabItem> items;
+ private java.util.List<QWidget> tabWidgets;
+
+ /**
+ * 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));
+ }
+
+ @Override
+ protected QWidget createQWidget(int style) {
+ state &= ~(CANVAS | THEME_BACKGROUND);
+ items = new ArrayList<TabItem>(4);
+ tabWidgets = new ArrayList<QWidget>(4);
+ return new QTabWidget();
+ }
+
+ @Override
+ protected void connectSignals() {
+ getQTabWidget().currentChanged.connect(this, "selectionEvent(int)");//$NON-NLS-1$
+ }
+
+ QTabWidget getQTabWidget() {
+ return (QTabWidget) getQWidget();
+ }
+
+ protected void selectionEvent(int index) {
+ if (index != -1 && items != null) {
+ TabItem item = getItem(index);
+ Event event = new Event();
+ event.item = item;
+ sendEvent(SWT.Selection, event);
+ }
+ }
+
+ protected void addQChild() {
+ // do nothing
+ }
+
+ static int checkStyle(int style) {
+ 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);
+ }
+
+ @Override
+ protected void checkSubclass() {
+ if (!isValidSubclass()) {
+ error(SWT.ERROR_INVALID_SUBCLASS);
+ }
+ }
+
+ void createItem(TabItem item, int index) {
+ int count = getQTabWidget().count();
+ if (!(0 <= index && index <= count)) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+
+ items.add(index, item);
+
+ QWidget widget = new QWidget();
+ widget.setSizePolicy(Policy.Expanding, Policy.Expanding);
+ widget.setContentsMargins(0, 0, 0, 0);
+ QVBoxLayout layout = new QVBoxLayout();
+ layout.setContentsMargins(0, 0, 0, 0);
+ widget.setLayout(layout);
+
+ tabWidgets.add(index, widget);
+
+ getQTabWidget().insertTab(index, widget, item.getText());
+
+ /*
+ * Send a selection event when the item that is added becomes the new
+ * selection. This only happens when the first item is added.
+ */
+ if (index == 0) {
+ Event event = new Event();
+ event.item = item;
+ sendEvent(SWT.Selection, event);
+ }
+ }
+
+ void updateItem(TabItem item, Control oldControl) {
+ int index = indexOf(item);
+ QWidget container = tabWidgets.get(index);
+
+ if (oldControl != null) {
+ QWidget widget = oldControl.getQMasterWidget();
+ if (widget != null) {
+ container.layout().removeWidget(widget);
+ }
+ }
+
+ Control control = item.getControl();
+ QWidget widget = null;
+ if (control != null) {
+ widget = control.getQMasterWidget();
+ }
+ if (widget == null) {
+ return;
+ }
+ container.layout().addWidget(widget);
+ }
+
+ void destroyItem(TabItem item) {
+ int count = getQTabWidget().count();
+ int index = 0;
+ while (index < count) {
+ if (items.get(index) == item) {
+ break;
+ }
+ index++;
+ }
+ if (index == count) {
+ return;
+ }
+ int selectionIndex = getQTabWidget().currentIndex();
+ items.remove(count);
+ if (count > 0 && index == selectionIndex) {
+ setSelection(Math.max(0, selectionIndex - 1), true);
+ }
+ }
+
+ @Override
+ Control findThemeControl() {
+ /* It is not possible to change the background of this control */
+ return this;
+ }
+
+ @Override
+ public Rectangle getClientArea() {
+ checkWidget();
+ return QtSWTConverter.convert(getQTabWidget().contentsRect());
+ }
+
+ /**
+ * Adds the listener to the collection of listeners who will be notified
+ * when the user changes the receiver's selection, 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 when the user changes
+ * the receiver's selection
+ *
+ * @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);
+ }
+
+ /**
+ * 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();
+ int count = getQTabWidget().count();
+ if (!(0 <= index && index < count)) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+ return items.get(index);
+ }
+
+ /**
+ * Returns the tab 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 tab item at the given point, or null if the point is not in a
+ * tab 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>
+ *
+ * @since 3.4
+ */
+ public TabItem getItem(Point point) {
+ checkWidget();
+ if (point == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ QWidget widget = getQTabWidget().childAt(point.x, point.y);
+ if (widget == null) {
+ return null;
+ }
+ int index = getQTabWidget().indexOf(widget);
+ if (index < 0 || index >= items.size()) {
+ return null;
+ }
+ return items.get(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 getQTabWidget().count();
+ }
+
+ /**
+ * 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();
+ int count = getQTabWidget().count();
+ TabItem[] result = new TabItem[count];
+ System.arraycopy(items, 0, result, 0, count);
+ 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 = getQTabWidget().currentIndex();
+ if (index == -1) {
+ return new TabItem[0];
+ }
+ return new TabItem[] { items.get(index) };
+ }
+
+ /**
+ * 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 getQTabWidget().currentIndex();
+ }
+
+ /**
+ * 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>
+ * </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 count = getQTabWidget().count();
+ for (int i = 0; i < count; i++) {
+ if (items.get(i) == item) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ Point minimumSize(int wHint, int hHint, boolean flushCache) {
+ Control[] children = _getChildren();
+ int width = 0, height = 0;
+ for (int i = 0; i < children.length; i++) {
+ Control child = children[i];
+ int index = 0;
+ int count = getChildrenCount();
+ while (index < count) {
+ if (items.get(index).control == child) {
+ break;
+ }
+ index++;
+ }
+ if (index == count) {
+ Rectangle rect = child.getBounds();
+ width = Math.max(width, rect.x + rect.width);
+ height = Math.max(height, rect.y + rect.height);
+ } else {
+ Point size = child.computeSize(wHint, hHint, flushCache);
+ width = Math.max(width, size.x);
+ height = Math.max(height, size.y);
+ }
+ }
+ return new Point(width, height);
+ }
+
+ @Override
+ boolean mnemonicHit(char key) {
+ for (int i = 0; i < items.size(); i++) {
+ TabItem item = items.get(i);
+ if (item != null) {
+ char ch = findMnemonic(item.getText());
+ if (Character.toUpperCase(key) == Character.toUpperCase(ch)) {
+ if (forceFocus()) {
+ if (i != getSelectionIndex()) {
+ setSelection(i, true);
+ }
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ boolean mnemonicMatch(char key) {
+ for (int i = 0; i < items.size(); i++) {
+ TabItem item = items.get(i);
+ if (item != null) {
+ char ch = findMnemonic(item.getText());
+ if (Character.toUpperCase(key) == Character.toUpperCase(ch)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ void releaseChildren(boolean destroy) {
+ if (items != null) {
+ int count = getQTabWidget().count();
+ for (int i = 0; i < count; i++) {
+ TabItem item = items.get(i);
+ if (item != null && !item.isDisposed()) {
+ item.release(false);
+ }
+ }
+ items = null;
+ }
+ super.releaseChildren(destroy);
+ }
+
+ @Override
+ void removeControl(Control control) {
+ super.removeControl(control);
+ int count = getQTabWidget().count();
+ for (int i = 0; i < count; i++) {
+ TabItem item = items.get(i);
+ if (item.control == control) {
+ getQTabWidget().removeTab(i);
+ item.setControl(null);
+ }
+ }
+ }
+
+ /**
+ * Removes the listener from the collection of listeners who will be
+ * notified when the user changes the receiver's selection.
+ *
+ * @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 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);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void setFont(Font font) {
+ checkWidget();
+ Rectangle oldRect = getClientArea();
+ super.setFont(font);
+ Rectangle newRect = getClientArea();
+ if (!oldRect.equals(newRect)) {
+ //sendResize();
+ int index = getQTabWidget().currentIndex();
+ if (index != -1) {
+ TabItem item = items.get(index);
+ Control control = item.control;
+ if (control != null && !control.isDisposed()) {
+ control.setBounds(getClientArea());
+ }
+ }
+ }
+ }
+
+ /**
+ * 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();
+ int count = getQTabWidget().count();
+ if (!(0 <= index && index < count)) {
+ return;
+ }
+ setSelection(index, false);
+ }
+
+ void setSelection(int index, boolean notify) {
+ int oldIndex = getQTabWidget().currentIndex();
+ if (oldIndex == index) {
+ return;
+ }
+ if (oldIndex != -1) {
+ TabItem item = items.get(oldIndex);
+ Control control = item.control;
+ if (control != null && !control.isDisposed()) {
+ control.setVisible(false);
+ }
+ }
+ getQTabWidget().setCurrentIndex(index);
+ int newIndex = getQTabWidget().currentIndex();
+ if (newIndex != -1) {
+ TabItem item = items.get(newIndex);
+ 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);
+ }
+ }
+ }
+
+ @Override
+ boolean traversePage(boolean next) {
+ 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()) {
+ // TODO
+ //OS.SendMessage(handle, OS.WM_CHANGEUISTATE, OS.UIS_INITIALIZE, 0);
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TabItem.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TabItem.java
new file mode 100644
index 0000000000..e6a3286797
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TabItem.java
@@ -0,0 +1,389 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#tabfolder">TabFolder,
+ * TabItem snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public class TabItem extends Item {
+ TabFolder parent;
+ Control control;
+ private String toolTipText;
+
+ /**
+ * 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);
+ }
+
+ void _setText(int index, String string) {
+ parent.getQTabWidget().setTabText(index, string);
+ }
+
+ @Override
+ protected void checkSubclass() {
+ if (!isValidSubclass()) {
+ error(SWT.ERROR_INVALID_SUBCLASS);
+ }
+ }
+
+ @Override
+ void destroyWidget() {
+ parent.destroyItem(this);
+ releaseQWidget();
+ }
+
+ /**
+ * 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 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.4
+ */
+ public Rectangle getBounds() {
+ checkWidget();
+ int index = parent.indexOf(this);
+ if (index == -1 || control == null) {
+ return new Rectangle(0, 0, 0, 0);
+ }
+ return control.getBounds();
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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;
+ }
+
+ @Override
+ void releaseQWidget() {
+ super.releaseQWidget();
+ parent = null;
+ }
+
+ @Override
+ void releaseParent() {
+ super.releaseParent();
+ int index = parent.indexOf(this);
+ if (index == parent.getSelectionIndex()) {
+ if (control != null) {
+ control.setVisible(false);
+ }
+ }
+ }
+
+ @Override
+ void releaseWidget() {
+ super.releaseWidget();
+ control = null;
+ }
+
+ /**
+ * 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);
+ }
+ }
+ if (this.control != null && this.control.isDisposed()) {
+ this.control = null;
+ }
+ Control oldControl = this.control, newControl = control;
+ this.control = control;
+ parent.updateItem(this, oldControl);
+ int index = parent.indexOf(this), selectionIndex = parent.getSelectionIndex();
+ if (index != selectionIndex) {
+ if (newControl != null) {
+ if (selectionIndex != -1) {
+ Control selectedControl = parent.getItem(selectionIndex).getControl();
+ if (selectedControl == newControl) {
+ return;
+ }
+ }
+ return;
+ }
+ }
+ }
+
+ @Override
+ public void setImage(Image image) {
+ checkWidget();
+ int index = parent.indexOf(this);
+ if (index == -1) {
+ return;
+ }
+ super.setImage(image);
+ // TODO
+ }
+
+ /**
+ * 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>
+ *
+ */
+ @Override
+ public void setText(String string) {
+ checkWidget();
+ if (string == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (string.equals(text)) {
+ return;
+ }
+ int index = parent.indexOf(this);
+ if (index == -1) {
+ return;
+ }
+ super.setText(string);
+ _setText(index, string);
+ }
+
+ /**
+ * Sets the receiver's tool tip text to the argument, which may be null
+ * indicating that the default tool tip for the control will be shown. For a
+ * control that has a default tool tip, such as the Tree control on Windows,
+ * setting the tool tip text to an empty string replaces the default,
+ * causing no tool tip text to be shown.
+ * <p>
+ * The mnemonic indicator (character '&amp;') is not displayed in a tool
+ * tip. To display a single '&amp;' in the tool tip, the character '&amp;'
+ * can be escaped by doubling it in the string.
+ * </p>
+ *
+ * @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;
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Table.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Table.java
new file mode 100644
index 0000000000..4783422fed
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Table.java
@@ -0,0 +1,2561 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import static com.trolltech.qt.core.Qt.ItemDataRole.*;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import com.trolltech.qt.core.QModelIndex;
+import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.core.Qt;
+import com.trolltech.qt.core.Qt.AlignmentFlag;
+import com.trolltech.qt.core.Qt.DropActions;
+import com.trolltech.qt.core.Qt.ItemFlag;
+import com.trolltech.qt.core.Qt.ItemFlags;
+import com.trolltech.qt.core.Qt.Orientation;
+import com.trolltech.qt.core.Qt.ScrollBarPolicy;
+import com.trolltech.qt.core.Qt.SortOrder;
+import com.trolltech.qt.gui.QAbstractTableModel;
+import com.trolltech.qt.gui.QBrush;
+import com.trolltech.qt.gui.QDragEnterEvent;
+import com.trolltech.qt.gui.QDragLeaveEvent;
+import com.trolltech.qt.gui.QDragMoveEvent;
+import com.trolltech.qt.gui.QDropEvent;
+import com.trolltech.qt.gui.QHeaderView;
+import com.trolltech.qt.gui.QItemSelection;
+import com.trolltech.qt.gui.QTableView;
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.qt.gui.QAbstractItemView.DragDropMode;
+import com.trolltech.qt.gui.QAbstractItemView.EditTrigger;
+import com.trolltech.qt.gui.QAbstractItemView.SelectionBehavior;
+import com.trolltech.qt.gui.QAbstractItemView.SelectionMode;
+import com.trolltech.qt.gui.QHeaderView.ResizeMode;
+import com.trolltech.qt.gui.QItemSelectionModel.SelectionFlag;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.internal.qt.QtSWTConverter;
+import org.eclipse.swt.internal.qt.SignalConnector;
+
+/**
+ * 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 normally make sense to add <code>Control</code> children to it, or
+ * set a layout on it, unless implementing something like a cell editor.
+ * </p>
+ * <p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>SINGLE, MULTI, CHECK, FULL_SELECTION, HIDE_SELECTION, VIRTUAL, NO_SCROLL</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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#table">Table, TableItem,
+ * TableColumn snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public class Table extends Composite {
+ // aka rows, contains the cells/data
+ TableColumn sortColumn;
+ private int sortDirection;
+ private TableModel model;
+
+ private SignalConnector itemSelectionChanged;
+ private static final int DEFAULT_ITEMHIGHT = 14;
+ private int itemHeight = DEFAULT_ITEMHIGHT;
+
+ /**
+ * 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 SWT#NO_SCROLL
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+ public Table(Composite parent, int style) {
+ super(parent, checkStyle(style));
+ }
+
+ @Override
+ protected QWidget createQWidget(int style) {
+ state &= ~(CANVAS | THEME_BACKGROUND);
+
+ QTableView table = new MyQTableWidget();
+ model = new TableModel(isVirtual());
+ table.setModel(model);
+
+ table.verticalHeader().hide();
+ table.horizontalHeader().hide();
+ table.setEditTriggers(EditTrigger.NoEditTriggers);
+ table.setShowGrid(false);
+ table.setWordWrap(false);
+ table.setHorizontalScrollBarPolicy(ScrollBarPolicy.ScrollBarAsNeeded);
+ table.setVerticalScrollBarPolicy(ScrollBarPolicy.ScrollBarAsNeeded);
+ table.horizontalHeader().setResizeMode(ResizeMode.Interactive);
+ table.horizontalHeader().setStretchLastSection(true);
+ table.horizontalHeader().setDefaultAlignment(Qt.AlignmentFlag.AlignLeft);
+ table.horizontalHeader().setContentsMargins(0, 0, 0, 0);
+ if ((style & SWT.MULTI) != 0) {
+ table.setSelectionMode(SelectionMode.ExtendedSelection);
+ } else {
+ table.setSelectionMode(SelectionMode.SingleSelection);
+ }
+ table.setSelectionBehavior(SelectionBehavior.SelectRows);
+ setQMasterWidget(table);
+ return table.viewport();
+ }
+
+ @Override
+ protected void connectSignals() {
+ itemSelectionChanged = new SignalConnector(getQTableWidget().selectionModel().selectionChanged, this,
+ "qtItemSelectionChangedEvent()").connect(); //$NON-NLS-1$
+ }
+
+ protected void qtItemSelectionChangedEvent() {
+ int selectionIndex = getSelectionIndex();
+ Event event = new Event();
+ event.type = SWT.Selection;
+ if (selectionIndex != -1) {
+ event.item = getItem(selectionIndex);
+ }
+ sendEvent(SWT.Selection, event, true);
+ }
+
+ protected void selectionEvent(QItemSelection selected, QItemSelection deselected) {
+ sendEvent(SWT.Selection);
+ }
+
+ public QTableView getQTableWidget() {
+ return (QTableView) getQMasterWidget();
+ }
+
+ static int checkStyle(int style) {
+ if ((style & SWT.NO_SCROLL) == 0) {
+ style |= SWT.H_SCROLL | SWT.V_SCROLL;
+ }
+ return checkBits(style, SWT.SINGLE, SWT.MULTI, 0, 0, 0, 0);
+ }
+
+ @Override
+ protected void updateAutoFillBackground() {
+ // nothing
+ }
+
+ @Override
+ protected void updateBackground() {
+ super.updateBackground();
+ }
+
+ @Override
+ void updateBackgroundImage() {
+ //super.updateBackgroundImage();
+ }
+
+ @Override
+ protected Color getDefaultBackgroundColor() {
+ return display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
+ }
+
+ @Override
+ public void setDragEnabled(boolean enabled) {
+ getQTableWidget().setDragEnabled(enabled);
+ }
+
+ @Override
+ public void setAcceptDrops(boolean accept) {
+ super.setAcceptDrops(accept);
+ getQTableWidget().setDragDropMode(DragDropMode.DragDrop);
+ getQTableWidget().setDropIndicatorShown(true);
+ }
+
+ void addItem(TableItem item, int row) {
+ model.addItem(item, row, false);
+ }
+
+ void removeRow(TableItem row) {
+ model.removeRow(row);
+ }
+
+ void addColumn(TableColumn column, int index) {
+ model.addColumn(column, index);
+ }
+
+ void removeColumn(TableColumn column) {
+ model.removeColumn(column);
+ }
+
+ void rowChanged(TableItem row) {
+ model.rowChanged(row);
+ }
+
+ void cellChanged(TableItem row, int column) {
+ model.cellChanged(row, column);
+ }
+
+ void columnChanged(TableColumn column) {
+ model.columnChanged(column);
+ }
+
+ Rectangle visualRect(TableItem row, int column) {
+ return QtSWTConverter.convert(getQTableWidget().visualRect(model.index(indexOf(row), column)));
+ }
+
+ /**
+ * Adds the listener to the collection of listeners who will be notified
+ * when the user changes the receiver's selection, 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 the <code>SWT.CHECK</code> style 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 when the user changes
+ * the receiver's selection
+ *
+ * @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);
+ }
+
+ boolean checkData(TableItem item, boolean redraw) {
+ 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;
+ }
+
+ @Override
+ 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();
+ validateItemIndex(index);
+ model.getRow(index).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();
+ if (start > end) {
+ return;
+ }
+ int count = model.rowCount();
+ if (!(0 <= start && start <= end && end < count)) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+ if (start == 0 && end == count - 1) {
+ clearAll();
+ }
+ for (int index = start; index < end; index++) {
+ model.getRow(index).clear();
+ }
+ }
+
+ /**
+ * 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;
+ }
+ int count = model.rowCount();
+ for (int i = 0; i < indices.length; i++) {
+ if (!(0 <= indices[i] && indices[i] < count)) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+ }
+ for (int index : indices) {
+ model.getRow(index).clear();
+ }
+ }
+
+ /**
+ * 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();
+ model.clearAllItems();
+ //getQTableWidget().clearContents();
+ }
+
+ @Override
+ public void pack() {
+ // getQTableWidget().resizeColumnsToContents();
+ // getQTableWidget().resizeRowsToContents();
+ }
+
+ @Override
+ public Point computeSize(int wHint, int hHint, boolean changed) {
+ checkWidget();
+ QSize size = getQTableWidget().sizeHint();
+
+ if (getItemCount() > 0) {
+ int width = 0;
+ int height = 0;
+
+ // Checkbox column
+ if ((style & SWT.CHECK) != 0 || (style & SWT.RADIO) != 0) {
+ width += getQTableWidget().columnWidth(0);
+ }
+
+ if (getColumnCount() > 0) {
+ for (int i = 0; i < getColumnCount(); i++) {
+ // if ( getColumn( i ).useFixedWidth ) {
+ // width += getQTableWidget().columnWidth( i );
+ // } else {
+ width += getColumn(i).getPreferredColumnWidth(i);
+ // }
+ }
+ } else { // list mode width +=
+ getQTableWidget().sizeHintForColumn(1);
+ }
+
+ int borderWidth = getBorderWidth();
+ width += 2 * borderWidth;
+ height += 2 * borderWidth;
+ height += getHeaderHeight();
+ int items = getItemCount();
+ height += items * _getItemHeight();
+ size.setWidth(width);
+ size.setHeight(height);
+ }
+
+ return QtSWTConverter.convert(size);
+ }
+
+ /**
+ * 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;
+ }
+ for (int index : indices) {
+ _select(index, false);
+ }
+ }
+
+ /**
+ * 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();
+ _select(index, false);
+ }
+
+ /**
+ * 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();
+ _select(start, end, false);
+ }
+
+ /**
+ * 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();
+ itemSelectionChanged.runDisconnected(new Runnable() {
+ public void run() {
+ getQTableWidget().clearSelection();
+ }
+ });
+ }
+
+ /**
+ * 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();
+ return model.getColumn(index);
+ }
+
+ /**
+ * 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 model.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();
+ if (model.columnCount() == 0) {
+ return new int[0];
+ }
+ return _getColumnOrder();
+ }
+
+ private int[] _getColumnOrder() {
+ int columnCount = model.columnCount();
+ int[] order = new int[columnCount];
+ QHeaderView header = getQTableWidget().horizontalHeader();
+ for (int i = 0; i < columnCount; i++) {
+ order[i] = header.visualIndex(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();
+ return model.getColumns();
+ }
+
+ /**
+ * 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 getQTableWidget().showGrid() ? 1 : 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 2.0
+ */
+ public int getHeaderHeight() {
+ checkWidget();
+ if (getQTableWidget().horizontalHeader().isVisible()) {
+ return getQTableWidget().horizontalHeader().height();
+ }
+ 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>
+ */
+ public boolean getHeaderVisible() {
+ checkWidget();
+ return !getQTableWidget().horizontalHeader().isHidden();
+ }
+
+ /**
+ * 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();
+ validateItemIndex(index);
+ return model.getRow(index);
+ }
+
+ void validateItemIndex(int index) {
+ if (!(0 <= index && index < model.rowCount())) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+ }
+
+ /**
+ * 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 row = getQTableWidget().rowAt(point.y);
+ if (row < 0) {
+ return null;
+ }
+ return model.getRow(row);
+ }
+
+ /**
+ * 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 model.rowCount();
+ }
+
+ /**
+ * Returns the height of the area which would be used to display
+ * <em>one</em> of the items in the receiver.
+ *
+ * @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();
+ return _getItemHeight();
+ }
+
+ int _getItemHeight() {
+ int itemHeight = 0;
+ if (model.rowCount() > 0) {
+ itemHeight = getQTableWidget().rowHeight(0);
+ } else {
+ // getQTableWidget().insertRow(0);
+ // itemHeight = getQTableWidget().rowHeight(0);
+ // getQTableWidget().removeRow(0);
+ }
+ return itemHeight;
+ }
+
+ /**
+ * 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();
+ return model.getRows();
+ }
+
+ /**
+ * Returns <code>true</code> if the receiver's lines are visible, and
+ * <code>false</code> otherwise. Note that some platforms draw grid lines
+ * while others may draw alternating row colors.
+ * <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();
+ return getQTableWidget().showGrid();
+ }
+
+ /**
+ * 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();
+ List<QModelIndex> selection = getQTableWidget().selectionModel().selectedRows();
+
+ /*
+ * This is an insert sort for sorting items according to their rows. In
+ * SWT/Win32 the selection is returned sorted that way.
+ */
+ for (int i = 0; i < selection.size(); i++) {
+ QModelIndex selectedItem = selection.get(i);
+ int j = i;
+ while (j > 0 && selection.get(j - 1).row() > selectedItem.row()) {
+ selection.set(j, selection.get(j - 1));
+ j = j - 1;
+ }
+ selection.set(j, selectedItem);
+ }
+
+ TableItem items[] = new TableItem[selection.size()];
+ int i = 0;
+ for (QModelIndex index : selection) {
+ items[i++] = model.getRow(index.row());
+ }
+ return items;
+ }
+
+ /**
+ * 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();
+ return getQTableWidget().selectionModel().selectedRows().size();
+ }
+
+ /**
+ * 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();
+ if (model.rowCount() == 0) {
+ return -1;
+ }
+ // if (getQTableWidget().selectionModel().hasSelection()) {
+ List<QModelIndex> selectedRows = getQTableWidget().selectionModel().selectedRows();
+ if (selectedRows.size() > 0) {
+ return selectedRows.get(0).row();
+ }
+ // }
+ return -1;
+ }
+
+ /**
+ * 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();
+ List<QModelIndex> selectedIndices = getQTableWidget().selectionModel().selectedRows();
+ int[] result = new int[selectedIndices.size()];
+ int i = 0;
+ for (QModelIndex index : selectedIndices) {
+ result[i++] = index.row();
+ }
+ return result;
+ }
+
+ /**
+ * 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();
+ return sortColumn;
+ }
+
+ /**
+ * 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();
+ return sortDirection;
+ }
+
+ /**
+ * 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();
+ return getQTableWidget().rowAt(1);
+ }
+
+ /**
+ * 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 column 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);
+ }
+ return model.indexOf(column);
+ }
+
+ /**
+ * 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>
+ * </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);
+ }
+ return model.indexOf(item);
+ }
+
+ boolean isCustomToolTip() {
+ return hooks(SWT.MeasureItem);
+ }
+
+ /**
+ * 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 selection 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();
+ validateItemIndex(index);
+ return model.getRow(index).isSelected();
+ }
+
+ @Override
+ void releaseChildren(boolean destroy) {
+ model.release();
+ super.releaseChildren(destroy);
+ }
+
+ /**
+ * 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;
+ }
+ model.removeItems(indices);
+ }
+
+ /**
+ * 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();
+ validateItemIndex(index);
+ model.removeRowItem(index);
+ }
+
+ /**
+ * 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 = model.rowCount();
+ if (!(0 <= start && start <= end && end < count)) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+ if (start == 0 && end == count - 1) {
+ removeAll();
+ } else {
+ for (int index = end; index >= start; index--) {
+ model.removeRowItem(index);
+ }
+ }
+ }
+
+ /**
+ * 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();
+ model.releaseItems();
+ // getQTableWidget().clearContents();
+ // getQTableWidget().setRowCount(0);
+ }
+
+ /**
+ * Removes the listener from the collection of listeners who will be
+ * notified when the user changes the receiver's selection.
+ *
+ * @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;
+ }
+ for (int index : indices) {
+ _select(index, true);
+ }
+ }
+
+ /**
+ * 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();
+ _select(index, true);
+ }
+
+ void _select(int index, boolean selected) {
+ if (index < 0 || index >= model.rowCount()) {
+ return;
+ }
+ getQTableWidget().selectionModel().select(model.index(index, 0),
+ SelectionFlag.createQFlags(SelectionFlag.Select, SelectionFlag.Rows));
+ model.getRow(index).setSelected(selected);
+ }
+
+ /**
+ * 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();
+ _select(start, end, true);
+ }
+
+ void _select(int start, int end, boolean selected) {
+ if (end < 0 || start > end || (style & SWT.SINGLE) != 0 && start != end) {
+ return;
+ }
+ int count = model.rowCount();
+ if (count == 0 || start >= count) {
+ return;
+ }
+ start = Math.max(0, start);
+ end = Math.min(end, count - 1);
+ if (start == 0 && end == count - 1) {
+ if (selected) {
+ selectAll();
+ } else {
+ deselectAll();
+ }
+ } else {
+ for (int index = start; index < end; index++) {
+ _select(index, selected);
+ }
+ }
+ }
+
+ /**
+ * 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;
+ }
+ getQTableWidget().selectAll();
+ }
+
+ /**
+ * 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 (validateColumnOrder(order)) {
+ int columnCount = getColumnCount();
+ QHeaderView header = getQTableWidget().horizontalHeader();
+ for (int i = 0; i < columnCount; i++) {
+ int visualIndex = header.visualIndex(i);
+ header.moveSection(visualIndex, order[i]);
+ }
+ }
+ }
+
+ private boolean validateColumnOrder(int[] order) {
+ if (order == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ int columnCount = model.columnCount();
+ if (columnCount == 0) {
+ if (order.length != 0) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ return false;
+ }
+ if (order.length != columnCount) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ int[] oldOrder = _getColumnOrder();
+
+ boolean reorder = false;
+ boolean[] seen = new boolean[columnCount];
+ for (int i = 0; i < order.length; i++) {
+ int index = order[i];
+ if (index < 0 || index >= columnCount) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+ if (seen[index]) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ seen[index] = true;
+ if (index != oldOrder[i]) {
+ reorder = true;
+ }
+ }
+ return reorder;
+ }
+
+ /**
+ * 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();
+ if (show) {
+ getQTableWidget().horizontalHeader().show();
+ } else {
+ getQTableWidget().horizontalHeader().hide();
+ }
+ }
+
+ /**
+ * 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();
+ model.setItemCount(count);
+ }
+
+ /**
+ * @return true if Table was created with SWT.VIRTUAL style
+ */
+ boolean isVirtual() {
+ return (style & SWT.VIRTUAL) != 0;
+ }
+
+ /**
+ * Sets the height of the area which would be used to display <em>one</em>
+ * of the items in the table.
+ *
+ * @param itemHeight
+ * 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);
+ }
+ this.itemHeight = itemHeight;
+ int rows = model.rowCount();
+ for (int row = 0; row < rows; row++) {
+ getQTableWidget().setRowHeight(row, itemHeight);
+ }
+ }
+
+ /**
+ * Marks the receiver's lines as visible if the argument is
+ * <code>true</code>, and marks it invisible otherwise. Note that some
+ * platforms draw grid lines while others may draw alternating row colors.
+ * <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();
+ getQTableWidget().setShowGrid(show);
+ }
+
+ /**
+ * 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);
+ 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);
+ }
+ }
+ 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);
+ 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;
+ }
+ int count = model.rowCount();
+ if (count == 0 || start >= count) {
+ return;
+ }
+ start = Math.max(0, start);
+ end = Math.min(end, count - 1);
+ select(start, end);
+ 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);
+ }
+ sortColumn = column;
+ if (sortColumn != null && sortDirection != SWT.NONE) {
+ getQTableWidget().sortByColumn(column.getColumn(), getSortOrder());
+ }
+ }
+
+ private SortOrder getSortOrder() {
+ if ((sortDirection & SWT.UP) != 0) {
+ return SortOrder.AscendingOrder;
+ }
+ return SortOrder.DescendingOrder;
+ }
+
+ /**
+ * 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;
+ }
+ sortDirection = direction;
+ if (sortColumn != null && !sortColumn.isDisposed()) {
+ getQTableWidget().sortByColumn(sortColumn.getColumn(), getSortOrder());
+ }
+ }
+
+ /**
+ * 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();
+ if (!(0 <= index && index < model.rowCount())) {
+ return;
+ }
+ // int currentColumn = getQTableWidget().currentColumn();
+ // QTableWidgetItem item = model.getItem(index).getCellItem(currentColumn);
+ // getQTableWidget().scrollToItem(item, ScrollHint.PositionAtTop);
+ }
+
+ /**
+ * 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.getParent() != this) {
+ return;
+ }
+ if (model.rowCount() == 0) {
+ return;
+ }
+ QModelIndex index = getQTableWidget().currentIndex();
+ getQTableWidget().scrollTo(model.index(index.row(), model.indexOf(column)));
+ }
+
+ /**
+ * 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);
+ }
+ int index = indexOf(item);
+ if (index != -1) {
+ showItem(index, 0);
+ }
+ }
+
+ void showItem(int row, int col) {
+ getQTableWidget().scrollTo(model.index(row, col));
+ }
+
+ /**
+ * 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();
+ getQTableWidget().scrollTo(getQTableWidget().selectionModel().currentIndex());
+ }
+
+ void update(boolean all) {
+ getQTableWidget().update();
+ }
+
+ private final class MyQTableWidget extends QTableView {
+
+ @Override
+ protected void startDrag(DropActions supportedActions) {
+ // System.out.println("MyQTreeWidget.startDrag: " + supportedActions);
+ }
+
+ @Override
+ protected void dropEvent(QDropEvent event) {
+ sendDropEvent(event);
+ }
+
+ @Override
+ protected void dragMoveEvent(QDragMoveEvent event) {
+ sendDragMoveEvent(event);
+ }
+
+ @Override
+ protected void dragEnterEvent(QDragEnterEvent event) {
+ sendDragEnterEvent(event);
+ }
+
+ @Override
+ protected void dragLeaveEvent(QDragLeaveEvent event) {
+ sendDragLeaveEvent(event);
+ }
+
+ }
+
+ final class TableModel extends QAbstractTableModel {
+ private ArrayList<TableItem> rows;
+ private List<TableColumn> columns;
+ private final boolean virtual;
+
+ TableModel(boolean virtual) {
+ this.virtual = virtual;
+ init();
+ }
+
+ public void init() {
+ rows = new ArrayList<TableItem>(4);
+ columns = new ArrayList<TableColumn>(4);
+ }
+
+ @Override
+ public Object data(QModelIndex index, int role) {
+ int row = index.row();
+ int column = index.column();
+ TableItem rowItem = getRow(row);
+ switch (role) {
+ case DisplayRole:
+ return rowItem.getText(column);
+ case CheckStateRole:
+ if ((style & SWT.CHECK) != 0 && column == 0) {
+ return rowItem.getChecked();
+ }
+ break;
+ case DecorationRole:
+ Image img = rowItem.getImage(column);
+ if (img != null) {
+ return img.getQPixmap();
+ }
+ break;
+ case BackgroundRole: {
+ Color color = rowItem.getBackground(column);
+ if (color != null) {
+ return new QBrush(color.getColor());
+ }
+ break;
+ }
+ case ForegroundRole: {
+ Color color = rowItem.getForeground(column);
+ if (color != null) {
+ return new QBrush(color.getColor());
+ }
+ break;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean setData(QModelIndex index, Object value, int role) {
+ if (role == CheckStateRole) {
+ getRow(index.row()).setChecked(((Boolean) value).booleanValue());
+ dataChanged.emit(index, index);
+ return true;
+ }
+ return super.setData(index, value, role);
+ }
+
+ @Override
+ public ItemFlags flags(QModelIndex index) {
+ int column = index.column();
+ if ((style & SWT.CHECK) != 0 && column == 0) {
+ return new ItemFlags(new ItemFlag[] { ItemFlag.ItemIsSelectable, ItemFlag.ItemIsEditable,
+ ItemFlag.ItemIsEnabled, ItemFlag.ItemIsUserCheckable });
+ }
+ return super.flags(index);
+ }
+
+ @Override
+ public int rowCount(QModelIndex index) {
+ return rows.size();
+ }
+
+ void setItemCount(int count) {
+ count = Math.max(0, count);
+ if (count < rows.size()) {
+ beginRemoveRows(null, rows.size(), count - 1);
+ for (int i = rows.size() - 1; i >= count; i--) {
+ TableItem row = rows.remove(i);
+ row.release(false);
+ }
+ endRemoveRows();
+ } else {
+ beginInsertRows(null, rows.size(), count - 1);
+ rows.ensureCapacity(count);
+ boolean virtual = isVirtual();
+ for (int i = rows.size(); i < count; i++) {
+ if (virtual) {
+ rows.add(null);
+ } else {
+ rows.add(new TableItem(Table.this, SWT.NONE, i));
+ }
+ }
+ endInsertRows();
+ }
+ }
+
+ TableItem getRow(int index) {
+ TableItem item = rows.get(index);
+ if (item != null) {
+ return item;
+ }
+ if (!virtual) {
+ return null;
+ }
+ item = new TableItem(Table.this, SWT.NONE, index, false);
+ addItem(item, index, true);
+ return item;
+ }
+
+ public TableItem[] getRows() {
+ TableItem[] out = new TableItem[rows.size()];
+ if (virtual) {
+ int count = out.length;
+ for (int i = 0; i < count; i++) {
+ out[i] = getRow(i);
+ }
+ } else {
+ rows.toArray(out);
+ }
+ return out;
+ }
+
+ int indexOf(TableItem row) {
+ return rows.indexOf(row);
+ }
+
+ void addItem(TableItem rowItem, int row, boolean update) {
+ beginInsertRows(null, row, row);
+ // if we add items then we need an first column to hold them
+ if (columns.size() == 0) {
+ new TableColumn(Table.this, SWT.NONE);
+ }
+ if (update) {
+ rows.set(row, rowItem);
+ } else {
+ if (row == rows.size()) {
+ rows.add(rowItem);
+ } else {
+ rows.add(row, rowItem);
+ }
+ }
+ endInsertRows();
+ getQTableWidget().setRowHeight(row, itemHeight);
+ }
+
+ void cellChanged(TableItem rowItem, int column) {
+ int row = indexOf(rowItem);
+ QModelIndex index = index(row, column);
+ dataChanged.emit(index, index);
+ }
+
+ void rowChanged(TableItem rowItem) {
+ int row = indexOf(rowItem);
+ dataChanged.emit(index(row, 0), index(row, columns.size() - 1));
+ }
+
+ void removeRow(TableItem row) {
+ removeRowItem(rows.indexOf(row));
+ }
+
+ void removeRowItem(int index) {
+ if (index != -1) {
+ beginRemoveRows(null, index, index);
+ TableItem item = rows.remove(index);
+ if (item != null && !item.isDisposed()) {
+ item.release(false);
+ }
+ endRemoveRows();
+ }
+ }
+
+ void removeItems(int[] indices) {
+ int[] newIndices = new int[indices.length];
+ System.arraycopy(indices, 0, newIndices, 0, indices.length);
+ Arrays.sort(newIndices);
+ for (int i = indices.length - 1; i >= 0; i--) {
+ validateItemIndex(indices[i]);
+ removeRowItem(indices[i]);
+ }
+ }
+
+ void clearAllItems() {
+ for (TableItem item : rows) {
+ if (item != null) {
+ item.clear();
+ }
+ }
+ }
+
+ @Override
+ public int columnCount(QModelIndex index) {
+ return columns.size();
+ }
+
+ TableColumn getColumn(int index) {
+ validateColumnIndex(index);
+ return columns.get(index);
+ }
+
+ int indexOf(TableColumn column) {
+ return columns.indexOf(column);
+ }
+
+ private void validateColumnIndex(int index) {
+ if (!(0 <= index && index < columnCount())) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+ }
+
+ void addColumn(TableColumn column, int index) {
+ if (!(0 <= index && index <= columnCount())) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+ beginInsertColumns(null, index, index);
+ if (index == columns.size()) {
+ columns.add(column);
+ } else {
+ columns.add(index, column);
+ }
+ int columnCount = columns.size();
+ for (TableItem item : rows) {
+ if (item != null) {
+ item.addColumn(index, columnCount);
+ }
+ }
+ endInsertColumns();
+ }
+
+ void removeColumn(TableColumn column) {
+ int index = columns.indexOf(column);
+ if (index == -1) {
+ return;
+ }
+ beginRemoveColumns(null, index, index);
+ int columnCount = columnCount();
+ columns.remove(column);
+ for (TableItem item : rows) {
+ if (item != null) {
+ item.removeColumn(index, columnCount);
+ }
+ }
+ endRemoveColumns();
+ }
+
+ TableColumn[] getColumns() {
+ TableColumn[] out = new TableColumn[columns.size()];
+ return columns.toArray(out);
+ }
+
+ void release() {
+ releaseItems();
+ releaseColumns();
+ }
+
+ private void releaseItems() {
+ beginRemoveRows(null, 0, rows.size() - 1);
+ for (TableItem item : rows) {
+ if (item != null && !item.isDisposed()) {
+ item.release(false);
+ }
+ }
+ rows.clear();
+ endRemoveRows();
+ }
+
+ private void releaseColumns() {
+ beginRemoveColumns(null, 0, columns.size() - 1);
+ for (TableColumn column : columns) {
+ if (!column.isDisposed()) {
+ column.release(false);
+ }
+ }
+ columns.clear();
+ endRemoveColumns();
+ }
+
+ @Override
+ public Object headerData(int index, Orientation orientation, int role) {
+ if (index >= columns.size()) {
+ return null;
+ }
+ switch (role) {
+ case DisplayRole:
+ return columnText(index);
+ case ToolTipRole:
+ return columnTooltip(index);
+ case TextAlignmentRole:
+ return columnAlignment(index);
+ }
+ return null;
+ }
+
+ private Object columnAlignment(int index) {
+ int alignment = columns.get(index).getAlignment();
+ switch (alignment) {
+ case SWT.LEFT:
+ return AlignmentFlag.AlignLeft;
+ case SWT.CENTER:
+ return AlignmentFlag.AlignCenter;
+ case SWT.RIGHT:
+ return AlignmentFlag.AlignRight;
+ }
+ return null;
+ }
+
+ private Object columnText(int index) {
+ return columns.get(index).getText();
+ }
+
+ private Object columnTooltip(int index) {
+ return columns.get(index).getToolTipText();
+ }
+
+ void columnChanged(TableColumn column) {
+ int index = indexOf(column);
+ columnChanged(index, index);
+ }
+
+ void columnChanged(int from, int to) {
+ headerDataChanged.emit(Orientation.Horizontal, from, to);
+ }
+
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TableColumn.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TableColumn.java
new file mode 100644
index 0000000000..84e2e3da83
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TableColumn.java
@@ -0,0 +1,664 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.gui.QTableView;
+import com.trolltech.qt.gui.QHeaderView.ResizeMode;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#table">Table, TableItem,
+ * TableColumn snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class TableColumn extends Item {
+ private Table parent;
+ private boolean resizable, moveable;
+ private String tooltip;
+
+ /**
+ * 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, style, parent.getColumnCount());
+ }
+
+ /**
+ * 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>
+ * <p>
+ * Note that due to a restriction on some platforms, the first column is
+ * always left aligned.
+ * </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.addColumn(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 the user, 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 when the control is
+ * selected by the user
+ *
+ * @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);
+ }
+
+ @Override
+ protected void checkSubclass() {
+ if (!isValidSubclass()) {
+ error(SWT.ERROR_INVALID_SUBCLASS);
+ }
+ }
+
+ QTableView getQTableView() {
+ return parent.getQTableWidget();
+ }
+
+ int getColumn() {
+ return parent.indexOf(this);
+ }
+
+ @Override
+ void destroyWidget() {
+ parent.removeColumn(this);
+ releaseQWidget();
+ }
+
+ /**
+ * 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;
+ }
+
+ @Override
+ 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;
+ }
+
+ protected int getPreferredColumnWidth(int index) {
+ if (index != -1) {
+ int width = getQTableView().sizeHintForColumn(index);
+ if (parent.getHeaderVisible()) {
+ width = Math.max(width, getQTableView().horizontalHeader().sectionSizeHint(index));
+ }
+ return width;
+ }
+ return 0;
+ }
+
+ /**
+ * 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();
+ return this.tooltip;
+ }
+
+ /**
+ * 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();
+ int index = getColumn();
+ if (index == -1) {
+ return 0;
+ }
+ return getQTableView().columnWidth(index);
+ }
+
+ /**
+ * 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();
+ getQTableView().resizeColumnToContents(getColumn());
+ }
+
+ @Override
+ void releaseQWidget() {
+ super.releaseQWidget();
+ parent = null;
+ }
+
+ @Override
+ void releaseParent() {
+ super.releaseParent();
+ if (parent.sortColumn == this) {
+ parent.sortColumn = 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 by the user.
+ *
+ * @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>.
+ * <p>
+ * Note that due to a restriction on some platforms, the first column is
+ * always left aligned.
+ * </p>
+ *
+ * @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;
+ }
+ style &= ~(SWT.LEFT | SWT.RIGHT | SWT.CENTER);
+ style |= alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER);
+ parent.columnChanged(this);
+ }
+
+ @Override
+ public void setImage(Image image) {
+ checkWidget();
+ if (image != null && image.isDisposed()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ super.setImage(image);
+ parent.columnChanged(this);
+ }
+
+ /**
+ * 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;
+ // TODO how to it for single column?
+ getQTableView().horizontalHeader().setMovable(moveable);
+ }
+
+ /**
+ * 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;
+ ResizeMode resizeMode = resizable ? ResizeMode.Interactive : ResizeMode.Fixed;
+ int col = getColumn();
+ if (col != -1) {
+ getQTableView().horizontalHeader().setResizeMode(col, resizeMode);
+ }
+ }
+
+ @Override
+ public void setText(String string) {
+ checkWidget();
+ if (string == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (string.equals(text)) {
+ return;
+ }
+ super.setText(string);
+ parent.columnChanged(this);
+ }
+
+ /**
+ * Sets the receiver's tool tip text to the argument, which may be null
+ * indicating that the default tool tip for the control will be shown. For a
+ * control that has a default tool tip, such as the Tree control on Windows,
+ * setting the tool tip text to an empty string replaces the default,
+ * causing no tool tip text to be shown.
+ * <p>
+ * The mnemonic indicator (character '&amp;') is not displayed in a tool
+ * tip. To display a single '&amp;' in the tool tip, the character '&amp;'
+ * can be escaped by doubling it in the string.
+ * </p>
+ *
+ * @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();
+ this.tooltip = string;
+ parent.columnChanged(this);
+ }
+
+ /**
+ * 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();
+ if (width < 0) {
+ return;
+ }
+ int index = getColumn();
+ if (index == -1) {
+ return;
+ }
+ getQTableView().setColumnWidth(index, width);
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TableItem.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TableItem.java
new file mode 100644
index 0000000000..fc27cd11a4
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TableItem.java
@@ -0,0 +1,1441 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.core.Qt.FocusPolicy;
+import com.trolltech.qt.gui.QRadioButton;
+import com.trolltech.qt.gui.QTableView;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#table">Table, TableItem,
+ * TableColumn snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public class TableItem extends Item {
+ Table parent;
+ String[] strings;
+ Image[] images;
+ Font font;
+ Font[] cellFont;
+ boolean checked, grayed, cached;
+ int imageIndent;
+ Color background;
+ Color foreground;
+ int[] cellBackground, cellForeground;
+ private QRadioButton radioButton;
+ private boolean selected;
+
+ /**
+ * 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, checkNull(parent).getItemCount(), true);
+ }
+
+ /**
+ * 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, true);
+ }
+
+ TableItem(Table parent, int style, int index, boolean create) {
+ super(parent, style);
+ this.parent = parent;
+ if (create) {
+ parent.addItem(this, index);
+ updateCheckAndRadioPropertyForRow(index);
+ }
+ setText(index, "");//$NON-NLS-1$
+ }
+
+ private void updateCheckAndRadioPropertyForRow(int row) {
+ if (radioButton == null && (parent.style & SWT.RADIO) != 0 && (parent.style & SWT.SINGLE) != 0) {
+ //TODO
+ radioButton = new QRadioButton();
+ radioButton.released.connect(this, "radioButtonClickEvent()");//$NON-NLS-1$
+ radioButton.setFocusPolicy(FocusPolicy.NoFocus);
+ //getQTableWidget().setCellWidget(row, 0, radioButton);
+ }
+ }
+
+ protected void radioButtonClickEvent() {
+ sendEvent(SWT.Selection);
+ }
+
+ static Table checkNull(Table control) {
+ if (control == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ return control;
+ }
+
+ @Override
+ protected void checkSubclass() {
+ if (!isValidSubclass()) {
+ error(SWT.ERROR_INVALID_SUBCLASS);
+ }
+ }
+
+ QTableView getQTableWidget() {
+ return parent.getQTableWidget();
+ }
+
+ // int getRow() {
+ // return parent.indexOf(this);
+ // }
+
+ void clear() {
+ text = "";//$NON-NLS-1$
+ image = null;
+ font = null;
+ strings = null;
+ images = null;
+ imageIndent = 0;
+ checked = grayed = false;
+ if (background != null) {
+ background.dispose();
+ background = null;
+ }
+ if (foreground != null) {
+ foreground.dispose();
+ foreground = null;
+ }
+ cellFont = null;
+ cellBackground = cellForeground = null;
+ if (parent.isVirtual()) {
+ cached = false;
+ }
+ }
+
+ @Override
+ void destroyWidget() {
+ parent.removeRow(this);
+ releaseQWidget();
+ }
+
+ /**
+ * 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, true)) {
+ error(SWT.ERROR_WIDGET_DISPOSED);
+ }
+ if (background == null) {
+ return parent.getBackground();
+ }
+ return 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, true)) {
+ error(SWT.ERROR_WIDGET_DISPOSED);
+ }
+ int count = Math.max(1, parent.getColumnCount());
+ if (0 > index || index > count - 1) {
+ return getBackground();
+ }
+ int pixel = cellBackground != null ? cellBackground[index] : -1;
+ return pixel == -1 ? getBackground() : Color.qt_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, true)) {
+ error(SWT.ERROR_WIDGET_DISPOSED);
+ }
+ return getBounds(0);
+ }
+
+ /**
+ * Returns a rectangle describing the receiver's size and location relative
+ * to its parent at a column in the table.
+ *
+ * @param column
+ * 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 column) {
+ checkWidget();
+ if (!parent.checkData(this, true)) {
+ error(SWT.ERROR_WIDGET_DISPOSED);
+ }
+
+ if (column < 0 || column >= parent.getItemCount()) {
+ return new Rectangle(0, 0, 0, 0);
+ }
+ return parent.visualRect(this, column);
+ }
+
+ /**
+ * 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, true)) {
+ 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, true)) {
+ error(SWT.ERROR_WIDGET_DISPOSED);
+ }
+ return font != null ? font : 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.0
+ */
+ public Font getFont(int index) {
+ checkWidget();
+ if (!parent.checkData(this, true)) {
+ error(SWT.ERROR_WIDGET_DISPOSED);
+ }
+ int count = Math.max(1, parent.getColumnCount());
+ if (0 > index || index > count - 1) {
+ return getFont();
+ }
+ if (cellFont == null || cellFont[index] == null) {
+ return getFont();
+ }
+ return cellFont[index];
+ }
+
+ /**
+ * 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, true)) {
+ error(SWT.ERROR_WIDGET_DISPOSED);
+ }
+ if (foreground == null) {
+ return parent.getForeground();
+ }
+ return 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, true)) {
+ error(SWT.ERROR_WIDGET_DISPOSED);
+ }
+ int count = Math.max(1, parent.getColumnCount());
+ if (0 > index || index > count - 1) {
+ return getForeground();
+ }
+ int pixel = cellForeground != null ? cellForeground[index] : -1;
+ return pixel == -1 ? getForeground() : Color.qt_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, true)) {
+ error(SWT.ERROR_WIDGET_DISPOSED);
+ }
+ if ((parent.style & SWT.CHECK) == 0) {
+ return false;
+ }
+ return grayed;
+ }
+
+ @Override
+ public Image getImage() {
+ checkWidget();
+ if (!parent.checkData(this, true)) {
+ 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>
+ */
+ public Image getImage(int index) {
+ checkWidget();
+ if (!parent.checkData(this, true)) {
+ 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 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, true)) {
+ error(SWT.ERROR_WIDGET_DISPOSED);
+ }
+ //TODO
+ return getBounds(index);
+ }
+
+ /**
+ * 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, true)) {
+ error(SWT.ERROR_WIDGET_DISPOSED);
+ }
+ return imageIndent;
+ }
+
+ @Override
+ 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;
+ }
+
+ @Override
+ public String getText() {
+ checkWidget();
+ if (!parent.checkData(this, true)) {
+ error(SWT.ERROR_WIDGET_DISPOSED);
+ }
+ return super.getText();
+ }
+
+ /**
+ * 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, true)) {
+ error(SWT.ERROR_WIDGET_DISPOSED);
+ }
+ if (index == 0) {
+ return getText();
+ }
+ if (strings != null) {
+ if (0 <= index && index < strings.length) {
+ String string = strings[index];
+ return string != null ? string : "";//$NON-NLS-1$
+ }
+ }
+ return "";//$NON-NLS-1$
+ }
+
+ /**
+ * Returns a rectangle describing the size and location relative to its
+ * parent of the text 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 text 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.3
+ */
+ public Rectangle getTextBounds(int index) {
+ checkWidget();
+ if (!parent.checkData(this, true)) {
+ error(SWT.ERROR_WIDGET_DISPOSED);
+ }
+ //TODO
+ return getBounds(index);
+ }
+
+ @Override
+ void releaseQWidget() {
+ super.releaseQWidget();
+ radioButton = null;
+ parent = null;
+ }
+
+ @Override
+ void releaseWidget() {
+ super.releaseWidget();
+ strings = null;
+ images = null;
+ cellFont = null;
+ cellBackground = cellForeground = null;
+ }
+
+ /**
+ * 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);
+ }
+ Color oldColor = background;
+ if (color == null) {
+ background = null;
+ } else {
+ if (color.equals(background)) {
+ return;
+ }
+ background = color;
+ }
+ if (oldColor != null) {
+ oldColor.dispose();
+ }
+ if ((parent.style & SWT.VIRTUAL) != 0) {
+ cached = true;
+ }
+
+ parent.rowChanged(this);
+ }
+
+ /**
+ * 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;
+ if (color != null) {
+ pixel = color.getPixel();
+ }
+ 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;
+ }
+ parent.cellChanged(this, index);
+ // QBrush brush = new QBrush(QtSWTConverter.convert(color));
+ // getCellItem(index).setBackground(brush);
+ }
+
+ /**
+ * 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;
+ }
+ setChecked(checked, false);
+ }
+
+ void setChecked(boolean checked, boolean notify) {
+ this.checked = checked;
+ if ((parent.style & SWT.VIRTUAL) != 0) {
+ cached = true;
+ }
+ if (notify) {
+ Event event = new Event();
+ event.item = this;
+ event.detail = SWT.CHECK;
+ parent.postEvent(SWT.Selection, event);
+ }
+ parent.cellChanged(this, 0);
+ // CheckState state = checked ? CheckState.Checked : CheckState.Unchecked;
+ // getCellItem(0).setData(ItemDataRole.CheckStateRole, state);
+ }
+
+ /**
+ * 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);
+ }
+ Font oldFont = this.font;
+ if (oldFont == font) {
+ return;
+ }
+ this.font = font;
+ if (oldFont != null && oldFont.equals(font)) {
+ return;
+ }
+ if (font != null) {
+ if ((parent.style & SWT.VIRTUAL) != 0) {
+ cached = true;
+ }
+ }
+ parent.rowChanged(this);
+ // int row = getRow();
+ // int columnCount = parent.getColumnCount();
+ // for (int col = 0; col < columnCount; col++) {
+ // getCellItem(row, col).setFont(font.getQFont());
+ // }
+ }
+
+ /**
+ * 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;
+ }
+ if (cellFont == null) {
+ if (font == null) {
+ return;
+ }
+ cellFont = new Font[count];
+ }
+ Font oldFont = cellFont[index];
+ if (oldFont == font) {
+ return;
+ }
+ cellFont[index] = font;
+ if (oldFont != null && oldFont.equals(font)) {
+ return;
+ }
+ if ((parent.style & SWT.VIRTUAL) != 0) {
+ cached = true;
+ }
+ parent.cellChanged(this, index);
+ //getCellItem(index).setFont(font.getQFont());
+ }
+
+ /**
+ * 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);
+ }
+ Color oldColor = foreground;
+ if (color == null) {
+ foreground = null;
+ } else {
+ if (color.equals(foreground)) {
+ return;
+ }
+ foreground = color;
+ }
+ if (oldColor != null) {
+ oldColor.dispose();
+ }
+ if ((parent.style & SWT.VIRTUAL) != 0) {
+ cached = true;
+ }
+ parent.rowChanged(this);
+ // int row = getRow();
+ // int columnCount = parent.getColumnCount();
+ // QBrush brush = null;
+ // if (foreground != null) {
+ // brush = new QBrush(foreground.getColor());
+ // }
+ // for (int col = 0; col < columnCount; col++) {
+ // getCellItem(row, col).setForeground(brush);
+ // }
+ }
+
+ /**
+ * 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;
+ }
+ int pixel = -1;
+ if (color != null) {
+ pixel = color.getPixel();
+ }
+ 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.isVirtual()) {
+ cached = true;
+ }
+ parent.cellChanged(this, index);
+ //getCellItem(index).setForeground(new QBrush(QtSWTConverter.convert(color)));
+ }
+
+ /**
+ * 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;
+ }
+ parent.cellChanged(this, 0);
+ //getCellItem(0).setCheckState(CheckState.PartiallyChecked);
+ }
+
+ /**
+ * 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);
+ }
+ if (index == 0) {
+ if (image != null && image.isIcon()) {
+ if (image.equals(this.image)) {
+ return;
+ }
+ }
+ super.setImage(image);
+ }
+ int count = Math.max(1, parent.getColumnCount());
+ if (0 > index || index > count - 1) {
+ return;
+ }
+ if (images == null && index != 0) {
+ images = new Image[count];
+ images[0] = image;
+ }
+ if (images != null) {
+ if (image != null && image.isIcon()) {
+ if (image.equals(images[index])) {
+ return;
+ }
+ }
+ images[index] = image;
+ }
+ if ((parent.style & SWT.VIRTUAL) != 0) {
+ cached = true;
+ }
+ parent.cellChanged(this, index);
+ //getCellItem(index).setIcon(image.getQIcon());
+ }
+
+ @Override
+ 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
+ */
+ @Deprecated
+ public void setImageIndent(int indent) {
+ checkWidget();
+ //TODO
+ // if ( indent < 0 )
+ // return;
+ // if ( imageIndent == indent )
+ // return;
+ // imageIndent = indent;
+ // if ( ( parent.style & SWT.VIRTUAL ) != 0 ) {
+ // cached = true;
+ // } else {
+ // }
+ }
+
+ /**
+ * 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);
+ }
+ if (index == 0) {
+ if (string.equals(text)) {
+ return;
+ }
+ super.setText(string);
+ }
+ int count = Math.max(1, parent.getColumnCount());
+ if (0 > index || index > count - 1) {
+ return;
+ }
+ if (strings == null && index != 0) {
+ strings = new String[count];
+ strings[0] = text;
+ }
+ if (strings != null) {
+ if (string.equals(strings[index])) {
+ return;
+ }
+ strings[index] = string;
+ }
+ if (parent.isVirtual()) {
+ cached = true;
+ }
+ parent.cellChanged(this, index);
+ //getCellItem(index).setText(string);
+ }
+
+ @Override
+ public void setText(String string) {
+ checkWidget();
+ setText(0, string);
+ }
+
+ void addColumn(int index, int columnCount) {
+ String[] strings = this.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);
+ strings = temp;
+ }
+ Image[] images = this.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);
+ this.images = temp;
+ }
+ if (index == 0) {
+ if (columnCount != 0) {
+ if (strings == null) {
+ this.strings = new String[columnCount + 1];
+ this.strings[1] = text;
+ }
+ text = ""; //$NON-NLS-1$
+ if (images == null) {
+ images = new Image[columnCount + 1];
+ images[1] = image;
+ }
+ image = null;
+ }
+ }
+ if (cellBackground != null) {
+ int[] cellBackground = this.cellBackground;
+ int[] temp = new int[columnCount + 1];
+ System.arraycopy(cellBackground, 0, temp, 0, index);
+ System.arraycopy(cellBackground, index, temp, index + 1, columnCount - index);
+ temp[index] = -1;
+ this.cellBackground = temp;
+ }
+ if (cellForeground != null) {
+ int[] cellForeground = this.cellForeground;
+ int[] temp = new int[columnCount + 1];
+ System.arraycopy(cellForeground, 0, temp, 0, index);
+ System.arraycopy(cellForeground, index, temp, index + 1, columnCount - index);
+ temp[index] = -1;
+ this.cellForeground = temp;
+ }
+ if (cellFont != null) {
+ Font[] cellFont = this.cellFont;
+ Font[] temp = new Font[columnCount + 1];
+ System.arraycopy(cellFont, 0, temp, 0, index);
+ System.arraycopy(cellFont, index, temp, index + 1, columnCount - index);
+ this.cellFont = temp;
+ }
+ }
+
+ void removeColumn(int index, int columnCount) {
+ if (columnCount == 0) {
+ strings = null;
+ images = null;
+ cellBackground = null;
+ cellForeground = null;
+ cellFont = null;
+ } else {
+ if (strings != null) {
+ String[] strings = this.strings;
+ if (index == 0) {
+ text = strings[1] != null ? strings[1] : ""; //$NON-NLS-1$
+ }
+ String[] temp = new String[columnCount];
+ System.arraycopy(strings, 0, temp, 0, index);
+ System.arraycopy(strings, index + 1, temp, index, columnCount - index);
+ this.strings = temp;
+ } else {
+ if (index == 0) {
+ text = ""; //$NON-NLS-1$
+ }
+ }
+ if (images != null) {
+ Image[] images = this.images;
+ if (index == 0) {
+ image = images[1];
+ }
+ Image[] temp = new Image[columnCount];
+ System.arraycopy(images, 0, temp, 0, index);
+ System.arraycopy(images, index + 1, temp, index, columnCount - index);
+ this.images = temp;
+ } else {
+ if (index == 0) {
+ image = null;
+ }
+ }
+ if (cellBackground != null) {
+ int[] cellBackground = this.cellBackground;
+ int[] temp = new int[columnCount];
+ System.arraycopy(cellBackground, 0, temp, 0, index);
+ System.arraycopy(cellBackground, index + 1, temp, index, columnCount - index);
+ this.cellBackground = temp;
+ }
+ if (cellForeground != null) {
+ int[] cellForeground = this.cellForeground;
+ int[] temp = new int[columnCount];
+ System.arraycopy(cellForeground, 0, temp, 0, index);
+ System.arraycopy(cellForeground, index + 1, temp, index, columnCount - index);
+ this.cellForeground = temp;
+ }
+ if (cellFont != null) {
+ Font[] cellFont = this.cellFont;
+ Font[] temp = new Font[columnCount];
+ System.arraycopy(cellFont, 0, temp, 0, index);
+ System.arraycopy(cellFont, index + 1, temp, index, columnCount - index);
+ this.cellFont = temp;
+ }
+ }
+
+ }
+
+ void setSelected(boolean selected) {
+ this.selected = selected;
+ // int columns = parent.getColumnCount();
+ parent.cellChanged(this, 0);
+ // int row = getRow();
+ // for (int col = 0; col < columns; col++) {
+ // //getCellItem(row, col).setSelected(selected);
+ // }
+ if ((parent.style & SWT.SINGLE) != 0 && (parent.style & SWT.RADIO) != 0) {
+ radioButton.setChecked(selected);
+ }
+ }
+
+ public boolean isSelected() {
+ return selected;
+
+ // int columns = parent.getColumnCount();
+ // int row = getRow();
+ // for (int col = 0; col < columns; col++) {
+ // //TODO
+ // // if (getCellItem(row, col).isSelected()) {
+ // // return true;
+ // // }
+ // }
+ // return false;
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Text.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Text.java
new file mode 100644
index 0000000000..c456792f05
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Text.java
@@ -0,0 +1,1875 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.core.QPoint;
+import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.core.Qt.LayoutDirection;
+import com.trolltech.qt.gui.QAbstractScrollArea;
+import com.trolltech.qt.gui.QContentsMargins;
+import com.trolltech.qt.gui.QFontMetrics;
+import com.trolltech.qt.gui.QLineEdit;
+import com.trolltech.qt.gui.QMouseEvent;
+import com.trolltech.qt.gui.QScrollBar;
+import com.trolltech.qt.gui.QSizePolicy;
+import com.trolltech.qt.gui.QStyle;
+import com.trolltech.qt.gui.QTextBlock;
+import com.trolltech.qt.gui.QTextCursor;
+import com.trolltech.qt.gui.QTextDocument;
+import com.trolltech.qt.gui.QTextEdit;
+import com.trolltech.qt.gui.QTextLayout;
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.qt.gui.QFrame.Shape;
+import com.trolltech.qt.gui.QLineEdit.EchoMode;
+import com.trolltech.qt.gui.QTextCursor.MoveMode;
+import com.trolltech.qt.gui.QTextCursor.MoveOperation;
+import com.trolltech.qt.gui.QTextEdit.LineWrapMode;
+
+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.Font;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.internal.qt.QtSWTConverter;
+
+/**
+ * Instances of this class are selectable user interface objects that allow the
+ * user to enter and modify text. Text controls can be either single or
+ * multi-line. When a text control is created with a border, the operating
+ * system includes a platform specific inset around the contents of the control.
+ * When created without a border, an effort is made to remove the inset such
+ * that the preferred size of the control is the same size as the contents.
+ * <p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>CENTER, ICON_CANCEL, ICON_SEARCH, LEFT, MULTI, PASSWORD, SEARCH, 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, and only one
+ * of the styles LEFT, CENTER, and RIGHT may be specified.
+ * </p>
+ * <p>
+ * Note: The styles ICON_CANCEL and ICON_SEARCH are hints used in combination
+ * with SEARCH. When the platform supports the hint, the text control shows
+ * these icons. When an icon is selected, a default selection event is sent with
+ * the detail field set to one of ICON_CANCEL or ICON_SEARCH. Normally,
+ * application code does not need to check the detail. In the case of
+ * ICON_CANCEL, the text is cleared before the default selection event is sent
+ * causing the application to search for an empty string.
+ * </p>
+ * <p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#text">Text snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class Text extends Scrollable {
+ private static final int minimumLineSpacing = 14;
+ private static final int verticalMargin = 1;
+ private static final int horizontalMargin = 2;
+
+ int tabs = 8;
+ int oldStart, oldEnd;
+ boolean doubleClick, ignoreModify, ignoreVerify, ignoreCharacter;
+ private int textLimit;
+ /**
+ * 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;
+
+ /*
+ * These values can be different on different platforms. Therefore they are
+ * not initialized in the declaration to stop the compiler from inlining.
+ */
+ static {
+ // LIMIT is the default maxlength of the QLineEdit
+ LIMIT = new QLineEdit().maxLength();
+ DELIMITER = "\n";//$NON-NLS-1$
+ }
+
+ /**
+ * 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));
+ setTabStops(tabs);
+ }
+
+ boolean isSingleLineEdit() {
+ return (style & SWT.MULTI) == 0;
+ }
+
+ @Override
+ protected QWidget createQWidget(int style) {
+ doubleClick = true;
+ if (isSingleLineEdit()) {
+ return createQLineEdit(style);
+ }
+ return createQTextEdit(style);
+ }
+
+ QLineEdit createQLineEdit(int style) {
+ QLineEdit lineEdit = new QLineEdit();
+ if ((style & SWT.READ_ONLY) != 0) {
+ lineEdit.setReadOnly(true);
+ }
+ if ((style & SWT.PASSWORD) != 0) {
+ lineEdit.setEchoMode(EchoMode.Password);
+ }
+ lineEdit.setSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum);
+ lineEdit.setContentsMargins(0, 0, 0, 0);
+
+ connectQLineEditSignals(lineEdit);
+
+ lineEdit.setFrame(false);
+
+ return lineEdit;
+ }
+
+ QWidget createQTextEdit(int style) {
+ QTextEdit textEdit = new MyQTextEdit();
+ if ((style & SWT.READ_ONLY) != 0) {
+ textEdit.setReadOnly(true);
+ }
+ if ((style & SWT.WRAP) != 0) {
+ textEdit.setLineWrapMode(LineWrapMode.WidgetWidth);
+ } else {
+ textEdit.setLineWrapMode(LineWrapMode.NoWrap);
+ }
+ connectQTextEditSignals(textEdit);
+
+ textEdit.setFrameShape(Shape.NoFrame);
+ textEdit.setLineWidth(0);
+
+ return textEdit;
+ }
+
+ @Override
+ protected void checkAndUpdateBorder(QWidget control) {
+ if (isSingleLineEdit()) {
+ if ((style & SWT.BORDER) != 0) {
+ getQLineEdit().setFrame(true);
+ }
+ } else {
+ super.checkAndUpdateBorder(control);
+ }
+ }
+
+ protected void connectQLineEditSignals(QLineEdit lineEdit) {
+ lineEdit.textChanged.connect(this, "textChangeEvent(String)"); //$NON-NLS-1$
+ }
+
+ protected void connectQTextEditSignals(QTextEdit textEdit) {
+ textEdit.textChanged.connect(this, "textChangeEvent()"); //$NON-NLS-1$
+ }
+
+ protected void textChangeEvent() {
+ textChangeEvent(null);
+ }
+
+ protected void textChangeEvent(String text) {
+ Event event = new Event();
+ event.data = text;
+ sendEvent(SWT.Modify, event);
+ }
+
+ @Override
+ void registerQWidget() {
+ super.registerQWidget();
+ if (!isSingleLineEdit()) {
+ display.addControl(getQTextEdit().viewport(), this);
+ }
+ }
+
+ @Override
+ void deregisterQWidget() {
+ if (!isSingleLineEdit()) {
+ display.removeControl(getQTextEdit().viewport());
+ }
+ super.deregisterQWidget();
+ }
+
+ private QLineEdit getQLineEdit() {
+ return (QLineEdit) getQWidget();
+ }
+
+ private QTextEdit getQTextEdit() {
+ return (QTextEdit) getQWidget();
+ }
+
+ @Override
+ QAbstractScrollArea getQScrollArea() {
+ if (!isSingleLineEdit()) {
+ return getQTextEdit();
+ }
+ return null;
+ }
+
+ /**
+ * 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 the user, 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, or when ENTER is pressed in a search text.
+ * If the receiver has the <code>SWT.SEARCH | SWT.CANCEL</code> style and
+ * the user cancels the search, the event object detail field contains the
+ * value <code>SWT.CANCEL</code>.
+ * </p>
+ *
+ * @param listener
+ * the listener which should be notified when the control is
+ * selected by the user
+ *
+ * @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);
+ }
+ string = Display.withCrLf(string);
+ if (isSingleLineEdit()) {
+ getQLineEdit().setText(getQLineEdit().text() + string);
+ } else {
+ getQTextEdit().append(string);
+ }
+ }
+
+ static int checkStyle(int style) {
+ if ((style & SWT.SEARCH) != 0) {
+ style |= SWT.SINGLE | SWT.BORDER;
+ style &= ~SWT.PASSWORD;
+ style &= ~SWT.ICON_CANCEL;
+ /*
+ * NOTE: ICON_CANCEL has the same value as H_SCROLL and ICON_SEARCH
+ * has the same value as V_SCROLL so they are cleared because
+ * SWT.SINGLE is set.
+ */
+ }
+ 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 (isSingleLineEdit()) {
+ getQLineEdit().setCursorPosition(getQLineEdit().cursorPosition());
+ } else {
+ getQTextEdit().textCursor().clearSelection();
+ }
+ }
+
+ @Override
+ public Point computeSize(int wHint, int hHint, boolean changed) {
+ checkWidget();
+
+ if (wHint != SWT.DEFAULT && wHint < 0) {
+ wHint = SWT.DEFAULT;
+ }
+ if (hHint != SWT.DEFAULT && hHint < 0) {
+ hHint = SWT.DEFAULT;
+ }
+
+ Point preferredSize;
+ if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT) {
+ preferredSize = new Point(wHint, hHint);
+ } else if (isSingleLineEdit()) {
+ if (wHint == SWT.DEFAULT && hHint == SWT.DEFAULT) {
+ preferredSize = getPreferredSingleLineClientAreaSize();
+ } else if (hHint == SWT.DEFAULT) {
+ preferredSize = new Point(wHint, getPreferredSingleLineClientAreaSize().y);
+ } else {
+ preferredSize = new Point(getPreferredSingleLineClientAreaSize().x, hHint);
+ }
+ } else {
+ if (wHint == SWT.DEFAULT && hHint == SWT.DEFAULT) {
+ preferredSize = getPreferredClientAreaSize(-1);
+ } else if (hHint == SWT.DEFAULT) {
+ preferredSize = new Point(wHint, getPreferredClientAreaSize(wHint).y);
+ } else {
+ preferredSize = new Point(getPreferredClientAreaSize(hHint).y, hHint);
+ }
+ }
+
+ Rectangle trim = computeTrim(0, 0, preferredSize.x, preferredSize.y);
+
+ return new Point(trim.width, trim.height);
+ }
+
+ private Point getPreferredSingleLineClientAreaSize() {
+ QFontMetrics fm = new QFontMetrics(getQLineEdit().font());
+ QContentsMargins margins = getQLineEdit().getContentsMargins();
+ int left = margins.left;
+ int top = margins.top;
+ int right = margins.right;
+ int bottom = margins.bottom;
+ int h = Math.max(fm.lineSpacing(), minimumLineSpacing) + 2 * verticalMargin + top + bottom;
+ int w = fm.width(getQLineEdit().text()) + 2 * horizontalMargin + left + right;
+ Point size = new Point(w, h);
+ if (size == null) {
+ return new Point(DEFAULT_WIDTH, DEFAULT_HEIGHT);
+ }
+ if (size.x < 0) {
+ size.x = DEFAULT_WIDTH;
+ }
+ if (size.y < 0) {
+ size.y = DEFAULT_HEIGHT;
+ }
+ return size;
+ }
+
+ private Point getPreferredClientAreaSize(int wHint) {
+ QTextDocument doc = getQTextEdit().document();
+ Point size = null;
+ if (doc != null) {
+ double oldTextWidth = doc.textWidth();
+ if (wHint >= 0) {
+ doc.setTextWidth(wHint);
+ } else {
+ doc.adjustSize();
+ }
+ QSize preferredSize = doc.size().toSize();
+ doc.setTextWidth(oldTextWidth);
+ size = new Point(preferredSize.width(), preferredSize.height());
+ }
+
+ if (size == null) {
+ return new Point(DEFAULT_WIDTH, DEFAULT_HEIGHT);
+ }
+ if (size.x < 0) {
+ size.x = DEFAULT_WIDTH;
+ }
+ if (size.y < 0) {
+ size.y = DEFAULT_HEIGHT;
+ }
+ return size;
+ }
+
+ @Override
+ public Rectangle computeTrim(int x, int y, int width, int height) {
+ checkWidget();
+ if (isSingleLineEdit()) {
+ if ((style & SWT.BORDER) != 0) {
+ int border = 0;
+ QStyle style = getQWidget().style();
+ if (style != null) {
+ border = style.pixelMetric(QStyle.PixelMetric.PM_DefaultFrameWidth);
+ }
+ x -= border;
+ y -= border;
+ width += 2 * border;
+ height += 2 * border;
+ }
+ return new Rectangle(x, y, width, height);
+ }
+ return super.computeTrim(x, y, 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>
+ */
+ public void copy() {
+ checkWidget();
+ if (isSingleLineEdit()) {
+ getQLineEdit().copy();
+ } else {
+ getQTextEdit().copy();
+ }
+ }
+
+ /**
+ * 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 (isSingleLineEdit()) {
+ getQLineEdit().cut();
+ } else {
+ getQTextEdit().cut();
+ }
+ }
+
+ /**
+ * 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 (!isSingleLineEdit()) {
+ int lineNumber = 0;
+ QTextCursor textCursor = getQTextEdit().textCursor();
+ QTextBlock textBlock = textCursor.block();
+ QTextLayout textLayout = textBlock.layout();
+ if (textLayout != null) {
+ lineNumber = textLayout.lineForTextPosition(textCursor.position() - textBlock.position()).lineNumber();
+ }
+ lineNumber += getNumberOfPrecedingTextLines(textBlock);
+ return lineNumber;
+ }
+ return 0;
+ }
+
+ private int getNumberOfPrecedingTextLines(QTextBlock textBlock) {
+ int lineCount = 0;
+ while (textBlock.isValid()) {
+ QTextLayout textLayout = textBlock.layout();
+ if (textLayout != null) {
+ int lines = textLayout.lineCount();
+ lineCount += lines > 0 ? lines : 1;
+ }
+ textBlock = textBlock.previous();
+ }
+ return lineCount;
+ }
+
+ /**
+ * 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 (isSingleLineEdit()) {
+ return new Point(0, 0);
+ }
+ return QtSWTConverter.convertPosition(getQTextEdit().cursorRect());
+ }
+
+ /**
+ * 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 (isSingleLineEdit()) {
+ return getQLineEdit().cursorPosition();
+ }
+ return getQTextEdit().textCursor().position();
+ }
+
+ /**
+ * 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();
+ if (isSingleLineEdit()) {
+ return getText().length();
+
+ }
+ QTextCursor cursor = getQTextEdit().textCursor();
+ int oldPosition = cursor.position();
+ cursor.movePosition(MoveOperation.End);
+ int count = cursor.position();
+ cursor.setPosition(oldPosition);
+ return count;
+ }
+
+ /**
+ * 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 (isSingleLineEdit()) {
+ if ((style & SWT.PASSWORD) != 0) {
+ return '*';
+ }
+ }
+ return '\0';
+ }
+
+ /**
+ * 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 (isSingleLineEdit()) {
+ return !getQLineEdit().isReadOnly();
+ }
+ return !getQTextEdit().isReadOnly();
+ }
+
+ /**
+ * 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 (isSingleLineEdit()) {
+ return 1;
+ }
+ QTextDocument textDocument = getQTextEdit().document();
+ if (textDocument != null) {
+ return getNumberOfPrecedingTextLines(textDocument.end());
+ }
+ return 0;
+ }
+
+ /**
+ * 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();
+ if (isSingleLineEdit()) {
+ return getQLineEdit().fontMetrics().lineSpacing();
+ }
+ QTextLayout textLayout = getQTextEdit().textCursor().block().layout();
+ if (textLayout != null) {
+ return (int) Math.round(textLayout.lineAt(0).height());
+ }
+ return 0;
+ }
+
+ /**
+ * 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 the widget message. The message text is displayed as a hint for
+ * the user, indicating the purpose of the field.
+ * <p>
+ * Typically this is used in conjunction with <code>SWT.SEARCH</code>.
+ * </p>
+ *
+ * @return the widget message
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - 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 String getMessage() {
+ checkWidget();
+ return getQWidget().whatsThis();
+ }
+
+ /**
+ * Returns the character position at the given point in the receiver or -1
+ * if no such position exists. The point is in the coordinate system of the
+ * receiver.
+ * <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>
+ *
+ * @since 3.3
+ */
+ // TODO - Javadoc
+ // /* public */int getPosition( Point point ) {
+ // checkWidget();
+ // if ( point == null )
+ // error( SWT.ERROR_NULL_ARGUMENT );
+ // int /* long */lParam = OS.MAKELPARAM( point.x, point.y );
+ // int position = OS.LOWORD( OS.SendMessage( handle, OS.EM_CHARFROMPOS, 0,
+ // lParam ) );
+ // if ( !OS.IsUnicode && OS.IsDBLocale )
+ // position = mbcsToWcsPos( position );
+ // return position;
+ // }
+
+ /**
+ * 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 (isSingleLineEdit()) {
+ int selectionStart = getQLineEdit().selectionStart();
+ if (selectionStart == -1) {
+ int cursorPos = getQLineEdit().cursorPosition();
+ return new Point(cursorPos, cursorPos);
+ }
+ return new Point(selectionStart, selectionStart + getQLineEdit().selectedText().length());
+ }
+ int start = getQTextEdit().textCursor().selectionStart();
+ int end = getQTextEdit().textCursor().selectionStart();
+ return new Point(Math.min(start, end), Math.max(start, end));
+ }
+
+ /**
+ * 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 Math.abs(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 (isSingleLineEdit()) {
+ return getQLineEdit().selectedText();
+ }
+ return getQTextEdit().textCursor().selectedText();
+ }
+
+ /**
+ * 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();
+ return tabs;
+ }
+
+ /**
+ * 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();
+ if (isSingleLineEdit()) {
+ return getQLineEdit().text();
+ }
+ return getQTextEdit().toPlainText();
+ }
+
+ /**
+ * 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 || end < 0) {
+ return "";//$NON-NLS-1$
+ }
+
+ String text = getText();
+ if (text != null) {
+ if (start >= text.length()) {
+ text = "";//$NON-NLS-1$
+ } else {
+ start = Math.max(0, start);
+ end = Math.min(end, text.length() - 1);
+ text = text.substring(start, end + 1);
+ }
+ }
+ return text;
+ }
+
+ /**
+ * 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 (isSingleLineEdit()) {
+ return getQLineEdit().maxLength();
+ }
+ return textLimit > 0 ? textLimit : LIMIT;
+ }
+
+ /**
+ * 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 (isSingleLineEdit()) {
+ return 0;
+ }
+ QScrollBar scrollBar = getQTextEdit().verticalScrollBar();
+ int index = 0;
+ if (scrollBar != null) {
+ int top = scrollBar.value();
+ QTextCursor textCursor = getQTextEdit().cursorForPosition(new QPoint(0, 0));
+ QTextBlock topBlock = textCursor.block();
+ QTextLayout layout = topBlock.layout();
+ if (layout != null && layout.position().y() < top) {
+ int layoutPos = (int) Math.round(layout.position().y());
+ for (int i = 0; i < layout.lineCount()
+ && layoutPos + layout.lineAt(i).rect().bottom() <= top + layout.lineAt(i).rect().height() / 2; ++i) {
+ ++index;
+ }
+ }
+ index += getNumberOfPrecedingTextLines(topBlock);
+ }
+ return 0;
+ }
+
+ /**
+ * 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();
+ if (isSingleLineEdit()) {
+ return 0;
+ }
+ return getQTextEdit().verticalScrollBar().value();
+ }
+
+ /**
+ * 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);
+ }
+ string = Display.withCrLf(string);
+ getQLineEdit().insert(string);
+ }
+
+ /**
+ * 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 (isSingleLineEdit()) {
+ getQLineEdit().paste();
+ } else {
+ getQTextEdit().paste();
+ }
+ }
+
+ /**
+ * 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 by the user.
+ *
+ * @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 (isSingleLineEdit()) {
+ getQLineEdit().selectAll();
+ } else {
+ QTextCursor textCursor = getQTextEdit().textCursor();
+ textCursor.select(QTextCursor.SelectionType.Document);
+ getQTextEdit().setTextCursor(textCursor);
+ }
+ }
+
+ /**
+ * 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 (isSingleLineEdit()) {
+ if (echo == '\0') {
+ getQLineEdit().setEchoMode(EchoMode.Normal);
+ } else {
+ getQLineEdit().setEchoMode(EchoMode.Password);
+ }
+ }
+ }
+
+ /**
+ * 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();
+ if (isSingleLineEdit()) {
+ getQLineEdit().setReadOnly(!editable);
+ } else {
+ getQTextEdit().setReadOnly(!editable);
+ }
+ }
+
+ @Override
+ public void setFont(Font font) {
+ checkWidget();
+ super.setFont(font);
+ setTabStops(tabs);
+ }
+
+ /**
+ * Sets the widget message. The message text is displayed as a hint for the
+ * user, indicating the purpose of the field.
+ * <p>
+ * Typically this is used in conjunction with <code>SWT.SEARCH</code>.
+ * </p>
+ *
+ * @param message
+ * the new message
+ *
+ * @exception IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the message 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.3
+ */
+ public void setMessage(String message) {
+ checkWidget();
+ getQWidget().setWhatsThis(message);
+ }
+
+ /**
+ * 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;
+
+ LayoutDirection direction = LayoutDirection.LeftToRight;
+ if (orientation == SWT.RIGHT_TO_LEFT) {
+ direction = LayoutDirection.RightToLeft;
+ }
+ getQWidget().setLayoutDirection(direction);
+ }
+
+ /**
+ * 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();
+ setSelection(start, 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();
+ int length = getCharCount();
+ start = Math.min(Math.max(0, start), length);
+ end = Math.min(Math.max(0, end), length);
+
+ if (isSingleLineEdit()) {
+ getQLineEdit().setSelection(start, end - start);
+ } else {
+ setCursorPosition(start, true);
+ setCursorPosition(end, false);
+ }
+
+ }
+
+ private void setCursorPosition(int pos, boolean moveAnchor) {
+ QTextCursor textCursor = getQTextEdit().textCursor();
+ textCursor.setPosition(pos, moveAnchor ? MoveMode.MoveAnchor : MoveMode.KeepAnchor);
+ getQTextEdit().setTextCursor(textCursor);
+ }
+
+ /**
+ * 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;
+ }
+ this.tabs = tabs;
+ setTabStops(this.tabs);
+ }
+
+ void setTabStops(int tabs) {
+ if (!isSingleLineEdit()) {
+ getQTextEdit().setTabStopWidth(getQTextEdit().fontMetrics().width(" ") * tabs);//$NON-NLS-1$
+ }
+ }
+
+ /**
+ * 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);
+ }
+ string = Display.withCrLf(string);
+ if (isSingleLineEdit()) {
+ getQLineEdit().setText(string);
+ } else {
+ getQTextEdit().setText(string);
+ }
+ }
+
+ /**
+ * 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 = LIMIT;
+ }
+
+ if (isSingleLineEdit()) {
+ getQLineEdit().setMaxLength(limit);
+ } else {
+ textLimit = limit;
+ if (getCharCount() > limit) {
+ getQTextEdit().setPlainText(getText().substring(0, 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 (!isSingleLineEdit()) {
+ index = Math.min(Math.max(index, 0), getLineCount() - 1);
+ QScrollBar scrollBar = getQTextEdit().verticalScrollBar();
+ QTextDocument textDocument = getQTextEdit().document();
+ if (scrollBar != null && textDocument != null) {
+ if (index == 0) {
+ scrollBar.setValue(0);
+ } else {
+ QTextBlock textBlock = textDocument.begin();
+ int lineCount = 0;
+ while (textBlock.isValid()) {
+ QTextLayout layout = textBlock.layout();
+ if (layout != null) {
+ int oldLineCount = lineCount;
+ int lines = layout.lineCount();
+ lineCount += lines > 0 ? lines : 1;
+ if (index < lineCount) {
+ int linePosition = (int) Math.round(layout.position().y()
+ + layout.lineAt(index - oldLineCount).y());
+ scrollBar.setValue(linePosition);
+ break;
+ }
+ }
+ textBlock = textBlock.next();
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * 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 (!isSingleLineEdit()) {
+ getQTextEdit().ensureCursorVisible();
+ }
+ }
+
+ private final class MyQTextEdit extends QTextEdit {
+
+ @Override
+ protected void mousePressEvent(QMouseEvent e) {
+ super.mousePressEvent(e);
+ e.setAccepted(false);
+ }
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ToolBar.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ToolBar.java
new file mode 100644
index 0000000000..3e7a1a152a
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ToolBar.java
@@ -0,0 +1,530 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import java.util.List;
+
+import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.core.Qt.ContextMenuPolicy;
+import com.trolltech.qt.core.Qt.Orientation;
+import com.trolltech.qt.core.Qt.ToolButtonStyle;
+import com.trolltech.qt.gui.QAction;
+import com.trolltech.qt.gui.QToolBar;
+import com.trolltech.qt.gui.QWidget;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#toolbar">ToolBar, ToolItem
+ * snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ToolBar extends Composite {
+ /*
+ * From the Windows SDK for TB_SETBUTTONSIZE:
+ *
+ * "If an application does not explicitly set the button size, the size
+ * defaults to 24 by 22 pixels".
+ */
+ private static final int DEFAULT_WIDTH = 24;
+ private static final int DEFAULT_HEIGHT = 22;
+
+ /**
+ * 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));
+ }
+
+ @Override
+ protected QWidget createQWidget(int style) {
+ state &= ~CANVAS;
+ QToolBar toolbar = new QToolBar();
+ initOrientation(toolbar, style);
+ toolbar.setStyleSheet("QToolBar { border: 0px; margin: 0px;}"); //$NON-NLS-1$ // background-color: #234;
+ toolbar.setContentsMargins(0, 0, 0, 0);
+ toolbar.setIconSize(new QSize(16, 16));
+ toolbar.setToolButtonStyle(ToolButtonStyle.ToolButtonTextBesideIcon);
+ toolbar.setContextMenuPolicy(ContextMenuPolicy.CustomContextMenu);
+ toolbar.setMovable(false);
+ toolbar.setFloatable(false);
+ toolbar.resize(0, 0);
+ // TODO if ( ( style & SWT.RIGHT ) != 0 ) {
+ // TODO if ( ( style & SWT.SHADOW_OUT ) != 0 ) {
+ // Visually, the tool bar is often separated from the menu bar by a separator.
+ // SWT.SHADOW_OUT style was defined for ToolBar. This style causes tool bars to draw the appropriate separator.
+ // On the Macintosh and platforms that do not support this look, the separator is not drawn.
+
+ // if ( ( style & SWT.WRAP ) != 0 )
+ // qt does not support wrapped mode! :(
+
+ return toolbar;
+ }
+
+ private void initOrientation(QToolBar toolbar, int style) {
+ if ((style & SWT.VERTICAL) != 0) {
+ toolbar.setOrientation(Orientation.Vertical);
+ this.style |= SWT.VERTICAL;
+ } else {
+ this.style |= SWT.HORIZONTAL;
+ toolbar.setOrientation(Orientation.Horizontal);
+ }
+ }
+
+ QToolBar getQToolBar() {
+ return (QToolBar) getQWidget();
+ }
+
+ void addAction(QAction action, int index) {
+ int itemCount = _getItemCount();
+ if (index >= 0 && index < itemCount) {
+ QAction before = getItems()[index].getQAction();
+ getQToolBar().insertAction(before, action);
+ } else {
+ getQToolBar().addAction(action);
+ }
+ }
+
+ QAction addWidget(QWidget widget, int index) {
+ int itemCount = _getItemCount();
+ QAction action;
+ if (index >= 0 && index < itemCount) {
+ QAction before = getItems()[index].getQAction();
+ action = getQToolBar().insertWidget(before, widget);
+ } else {
+ action = getQToolBar().addWidget(widget);
+ }
+ return action;
+ }
+
+ QWidget removeAction(QAction action) {
+ QWidget widget = null;
+ if (getQToolBar() != null) {
+ widget = getQToolBar().widgetForAction(action);
+ getQToolBar().removeAction(action);
+ }
+ return widget;
+ }
+
+ static int checkStyle(int style) {
+ /*
+ * On Windows, only flat tool bars can be traversed.
+ */
+ if ((style & SWT.FLAT) == 0) {
+ style |= SWT.NO_FOCUS;
+ }
+
+ /*
+ * A vertical tool bar cannot wrap because TB_SETROWS fails when the
+ * toolbar has TBSTYLE_WRAPABLE.
+ */
+ if ((style & SWT.VERTICAL) != 0) {
+ style &= ~SWT.WRAP;
+ }
+
+ return style;
+ }
+
+ @Override
+ protected void checkSubclass() {
+ if (!isValidSubclass()) {
+ error(SWT.ERROR_INVALID_SUBCLASS);
+ }
+ }
+
+ @Override
+ public Point computeSize(int wHint, int hHint, boolean changed) {
+ checkWidget();
+ Point size = super.computeSize(wHint, hHint, changed);
+ int width = size.x;
+ int height = size.y;
+
+ if (width == 0) {
+ width = DEFAULT_WIDTH;
+ }
+ if (height == 0) {
+ height = DEFAULT_HEIGHT;
+ }
+ if (wHint != SWT.DEFAULT) {
+ width = wHint;
+ }
+ if (hHint != SWT.DEFAULT) {
+ height = hHint;
+ }
+ Rectangle trim = computeTrim(0, 0, width, height);
+ width = trim.width;
+ height = trim.height;
+ return new Point(width, height);
+ }
+
+ /**
+ * 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();
+ List<QAction> list = getQWidget().actions();
+ int count = list.size();
+ if (!(0 <= index && index < count)) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+ Widget widget = display.findControl(list.get(index));
+ if (widget == null || !ToolItem.class.isInstance(widget)) {
+ error(SWT.ERROR_CANNOT_GET_ITEM);
+ }
+ return (ToolItem) widget;
+ }
+
+ /**
+ * 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 _getItemCount();
+ }
+
+ int _getItemCount() {
+ return getQWidget().actions().size();
+ }
+
+ /**
+ * 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();
+ List<QAction> list = getQWidget().actions();
+ int count = list.size();
+ if (count == 0) {
+ return new ToolItem[0];
+ }
+ ToolItem[] children = new ToolItem[count];
+ int items = 0;
+ for (QAction action : list) {
+ if (action != null) {
+ Widget widget = display.findControl(action);
+ if (widget != null && widget != this) {
+ if (widget instanceof ToolItem) {
+ children[items++] = (ToolItem) widget;
+ }
+ }
+ }
+ }
+ if (items == count) {
+ return children;
+ }
+ ToolItem[] newChildren = new ToolItem[items];
+ System.arraycopy(children, 0, newChildren, 0, items);
+ return newChildren;
+ }
+
+ /**
+ * 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();
+ if ((style & SWT.VERTICAL) != 0) {
+ return _getItemCount();
+ }
+ return 1;
+ }
+
+ /**
+ * 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);
+ }
+ return getQToolBar().actions().indexOf(item.getQAction());
+ }
+
+ @Override
+ boolean mnemonicHit(char ch) {
+ //TODO
+ // int key = Display.wcsToMbcs(ch);
+ // int[] id = new int[1];
+ // if (OS.SendMessage(handle, OS.TB_MAPACCELERATOR, key, id) == 0) {
+ // return false;
+ // }
+ // if ((style & SWT.FLAT) != 0 && !setTabGroupFocus())
+ // return false;
+ // int index = (int) /* 64 */OS.SendMessage(handle, OS.TB_COMMANDTOINDEX, id[0], 0);
+ // if (index == -1)
+ // return false;
+ // OS.SendMessage(handle, OS.TB_SETHOTITEM, index, 0);
+ // items[id[0]].click(false);
+ return true;
+ }
+
+ @Override
+ boolean mnemonicMatch(char ch) {
+ //TODO
+ // int key = Display.wcsToMbcs(ch);
+ // int[] id = new int[1];
+ // if (OS.SendMessage(handle, OS.TB_MAPACCELERATOR, key, id) == 0) {
+ // return false;
+ // }
+ // /*
+ // * Feature in Windows. TB_MAPACCELERATOR matches either the mnemonic
+ // * character or the first character in a tool item. This behavior is
+ // * undocumented and unwanted. The fix is to ensure that the tool item
+ // * contains a mnemonic when TB_MAPACCELERATOR returns true.
+ // */
+ // int index = (int) /* 64 */OS.SendMessage(handle, OS.TB_COMMANDTOINDEX, id[0], 0);
+ // if (index == -1)
+ // return false;
+ // return findMnemonic(items[id[0]].text) != '\0';
+ return true;
+ }
+
+ @Override
+ void releaseChildren(boolean destroy) {
+ ToolItem[] items = getItems();
+ for (int i = 0; i < items.length; i++) {
+ ToolItem item = items[i];
+ if (item != null && !item.isDisposed()) {
+ item.release(false);
+ }
+ }
+ super.releaseChildren(destroy);
+ }
+
+ @Override
+ void removeControl(Control control) {
+ super.removeControl(control);
+ for (ToolItem item : getItems()) {
+ if (item != null && item.hasControl(control)) {
+ item.setControl(null);
+ }
+ }
+ }
+
+ @Override
+ public boolean setParent(Composite parent) {
+ checkWidget();
+ if (!super.setParent(parent)) {
+ return false;
+ }
+ getQToolBar().setParent(parent.getQWidget());
+ return true;
+ }
+
+ @Override
+ boolean setTabItemFocus() {
+ int index = 0;
+ ToolItem[] items = getItems();
+ while (index < items.length) {
+ ToolItem item = items[index];
+ if (item != null && (item.style & SWT.SEPARATOR) == 0) {
+ if (item.getEnabled()) {
+ break;
+ }
+ }
+ index++;
+ }
+ if (index == items.length) {
+ return false;
+ }
+ return super.setTabItemFocus();
+ }
+
+ @Override
+ public String toString() {
+ String s = getName() + "{items: #" + getItemCount() + ":"; //$NON-NLS-1$ //$NON-NLS-2$
+ for (ToolItem item : getItems()) {
+ s += item + " " + getQToolBar().widgetForAction(item.getQAction()) + ", "; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return s + "}"; //$NON-NLS-1$
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ToolItem.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ToolItem.java
new file mode 100644
index 0000000000..64f62f9676
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ToolItem.java
@@ -0,0 +1,981 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.core.QRect;
+import com.trolltech.qt.core.Qt.ContextMenuPolicy;
+import com.trolltech.qt.core.Qt.MouseButton;
+import com.trolltech.qt.gui.QAction;
+import com.trolltech.qt.gui.QIcon;
+import com.trolltech.qt.gui.QMouseEvent;
+import com.trolltech.qt.gui.QStyle;
+import com.trolltech.qt.gui.QStyleOptionToolButton;
+import com.trolltech.qt.gui.QToolBar;
+import com.trolltech.qt.gui.QToolButton;
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.qt.gui.QIcon.Mode;
+import com.trolltech.qt.gui.QStyle.ComplexControl;
+import com.trolltech.qt.gui.QToolButton.ToolButtonPopupMode;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.internal.qt.QtSWTConverter;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#toolbar">ToolBar, ToolItem
+ * snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ToolItem extends Item {
+ private ToolBar parent;
+ private Control control;
+ private Image disabledImage, hotImage;
+ private QAction action;
+
+ /**
+ * 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) {
+ this(parent, style, -1);
+ }
+
+ /**
+ * 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;
+ action = createAndAddAction(style, index);
+ connectSignals(action);
+ }
+
+ protected QAction createAndAddAction(int style, int index) {
+ QAction action;
+ int bits = SWT.CHECK | SWT.RADIO | SWT.PUSH | SWT.SEPARATOR | SWT.DROP_DOWN;
+ switch (style & bits) {
+ case SWT.SEPARATOR:
+ action = createAndAddSeparator(index);
+ break;
+ case SWT.DROP_DOWN:
+ action = createAndAddDropdownButton(index);
+ break;
+ case SWT.RADIO:
+ // if ( parent.actionGroup == null ) {
+ // parent.actionGroup = new QActionGroup( parent.getQtControl()
+ // );
+ // if ( ( parent.style & SWT.NO_RADIO_GROUP ) != 0 ) {
+ // parent.actionGroup.setExclusive( false );
+ // }
+ // }
+ // parent.actionGroup.addAction( action );
+ case SWT.CHECK:
+ action = createAndAddCheckableAction(index);
+ break;
+ case SWT.PUSH:
+ default:
+ action = createAndAddAction(index);
+ break;
+ }
+
+ display.addControl(action, this);
+
+ QWidget toolWidget = getQToolBar().widgetForAction(action);
+ toolWidget.setContextMenuPolicy(ContextMenuPolicy.NoContextMenu);
+ display.addControl(toolWidget, this);
+
+ return action;
+ }
+
+ private QAction createAndAddSeparator(int index) {
+ QAction action = createAction();
+ action.setSeparator(true);
+ addToToolbar(action, index);
+ return action;
+ }
+
+ private void addToToolbar(QAction action, int index) {
+ parent.addAction(action, index);
+ }
+
+ private QAction createAction() {
+ return new QAction(parent.getQWidget());
+ }
+
+ private QAction createAndAddAction(int index) {
+ QAction action = createAction();
+ addToToolbar(action, index);
+ return action;
+ }
+
+ private QAction createAndAddCheckableAction(int index) {
+ QAction action = createAction();
+ action.setCheckable(true);
+ addToToolbar(action, index);
+ return action;
+ }
+
+ private QAction createAndAddDropdownButton(int index) {
+ MyToolButton button = new MyToolButton(parent.getQWidget());
+ button.setPopupMode(ToolButtonPopupMode.MenuButtonPopup);
+ QAction action = parent.addWidget(button, index);
+ button.setDefaultAction(action);
+ return action;
+ }
+
+ QAction getQAction() {
+ return action;
+ }
+
+ QWidget getToolbarWidget() {
+ return getQToolBar().widgetForAction(action);
+ }
+
+ QToolBar getQToolBar() {
+ return parent.getQToolBar();
+ }
+
+ protected void connectSignals(QAction action) {
+ action.triggered.connect(this, "sendTriggeredEvent()"); //$NON-NLS-1$
+ action.hovered.connect(this, "sendHoveredEvent()"); //$NON-NLS-1$
+ }
+
+ protected void sendTriggeredEvent() {
+ Event event = new Event();
+ sendEvent(SWT.Selection, event);
+ }
+
+ protected void sendHoveredEvent() {
+ Event event = new Event();
+ sendEvent(SWT.Arm, event);
+ }
+
+ protected void sendShowDropDownEvent() {
+ Event event = new Event();
+ event.detail = SWT.ARROW;
+
+ Rectangle rect = getBounds();
+ event.x = rect.x;
+ event.y = rect.y + rect.height;
+
+ sendEvent(SWT.Selection, event);
+ }
+
+ /**
+ * Adds the listener to the collection of listeners who will be notified
+ * when the control is selected by the user, 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 when the control is
+ * selected by the user,
+ *
+ * @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);
+ }
+
+ @Override
+ protected void checkSubclass() {
+ if (!isValidSubclass()) {
+ error(SWT.ERROR_INVALID_SUBCLASS);
+ }
+ }
+
+ void click(boolean dropDown) {
+ if (dropDown) {
+ sendShowDropDownEvent();
+ } else {
+ getQAction().trigger();
+ }
+ }
+
+ @Override
+ void destroyWidget() {
+ QWidget toolWidget = parent.removeAction(action);
+ if (toolWidget != null) {
+ toolWidget.disconnect();
+ display.removeControl(toolWidget);
+ }
+ super.destroyWidget();
+ }
+
+ /**
+ * 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();
+ return QtSWTConverter.convert(getQToolBar().actionGeometry(getQAction()));
+ }
+
+ /**
+ * 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;
+ }
+
+ boolean hasControl(Control control) {
+ return this.control == 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 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();
+ return getQAction().isChecked();
+ }
+
+ /**
+ * 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 getQAction().toolTip();
+ }
+
+ /**
+ * 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 getQToolBar().actionGeometry(getQAction()).width();
+ }
+
+ /**
+ * 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();
+ }
+
+ @Override
+ void releaseWidget() {
+ super.releaseWidget();
+ control = null;
+ disabledImage = null;
+ hotImage = null;
+ }
+
+ @Override
+ void releaseQWidget() {
+ super.releaseQWidget();
+ parent.removeAction(action);
+ action = null;
+ parent = null;
+ }
+
+ /**
+ * Removes the listener from the collection of listeners who will be
+ * notified when the control is selected by the user.
+ *
+ * @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 resizeControl() {
+ if (control != null && !control.isDisposed()) {
+ /*
+ * Set the size and location of the control separately to minimize
+ * flashing in the case where the control does not resize to the
+ * size that was requested. This case can occur when the control is
+ * a combo box.
+ */
+ Rectangle itemRect = getBounds();
+ control.setSize(itemRect.width, itemRect.height);
+ Rectangle rect = control.getBounds();
+ rect.x = itemRect.x + (itemRect.width - rect.width) / 2;
+ rect.y = itemRect.y + (itemRect.height - rect.height) / 2;
+ control.setLocation(rect.x, rect.y);
+ }
+ }
+
+ void selectRadio() {
+ int index = 0;
+ ToolItem[] items = parent.getItems();
+ while (index < items.length && items[index] != this) {
+ index++;
+ }
+ int i = index - 1;
+ while (i >= 0 && items[i].setRadioSelection(false)) {
+ --i;
+ }
+ int j = index + 1;
+ while (j < items.length && items[j].setRadioSelection(false)) {
+ j++;
+ }
+ setSelection(true);
+ }
+
+ /**
+ * 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;
+ }
+ this.control = control;
+ QAction newAction = getQToolBar().insertWidget(getQAction(), control.getQWidget());
+ getQToolBar().removeAction(getQAction());
+ newAction.setEnabled(action.isEnabled());
+ newAction.setText(action.text());
+ newAction.setToolTip(action.toolTip());
+ newAction.setChecked(action.isChecked());
+ updateImages();
+ action = newAction;
+ resizeControl();
+ }
+
+ /**
+ * 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 getQAction().isEnabled();
+ }
+
+ /**
+ * 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();
+ getQAction().setEnabled(enabled);
+ }
+
+ /**
+ * Sets the receiver's disabled image to the argument, which may be null
+ * indicating that no disabled image should be displayed.
+ * <p>
+ * The disabled 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();
+ }
+
+ /**
+ * 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();
+ }
+
+ @Override
+ 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();
+ }
+
+ private void updateImages() {
+ if ((style & SWT.SEPARATOR) != 0) {
+ return;
+ }
+
+ if (image == null && disabledImage == null && hotImage == null) {
+ getQAction().setIcon((QIcon) null);
+ return;
+ }
+
+ QIcon icon = new QIcon();
+ if (image != null) {
+ icon.addPixmap(image.getQPixmap());
+ }
+
+ if (disabledImage != null) {
+ icon.addPixmap(disabledImage.getQPixmap(), Mode.Disabled);
+ }
+
+ if (hotImage != null) {
+ icon.addPixmap(hotImage.getQPixmap(), Mode.Selected);
+ }
+ getQAction().setIcon(icon);
+ }
+
+ boolean setRadioSelection(boolean value) {
+ if ((style & SWT.RADIO) == 0) {
+ return false;
+ }
+ if (getSelection() != value) {
+ setSelection(value);
+ postEvent(SWT.Selection);
+ }
+ return true;
+ }
+
+ /**
+ * 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;
+ }
+ getQAction().setChecked(selected);
+ }
+
+ /**
+ * 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>
+ */
+ @Override
+ 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);
+ getQAction().setText(string);
+ }
+
+ /**
+ * Sets the receiver's tool tip text to the argument, which may be null
+ * indicating that the default tool tip for the control will be shown. For a
+ * control that has a default tool tip, such as the Tree control on Windows,
+ * setting the tool tip text to an empty string replaces the default,
+ * causing no tool tip text to be shown.
+ * <p>
+ * The mnemonic indicator (character '&amp;') is not displayed in a tool
+ * tip. To display a single '&amp;' in the tool tip, the character '&amp;'
+ * can be escaped by doubling it in the string.
+ * </p>
+ *
+ * @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();
+ getQAction().setToolTip(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();
+ if ((style & SWT.SEPARATOR) == 0) {
+ return;
+ }
+ if (width < 0) {
+ return;
+ }
+ QWidget widget = getQToolBar().widgetForAction(getQAction());
+ widget.resize(width, widget.height());
+ }
+
+ @Override
+ public String toString() {
+ return getName() + "{text: " + getQAction().text() + ", tooltip: " + getQAction().toolTip() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ /**
+ * Subclassed QToolButton, to override drop down handling. We check for
+ * clicks on the arrow an the right side of the button and show our own
+ * drop-down menu, ignoring the default menu.
+ */
+ private final class MyToolButton extends QToolButton {
+ public MyToolButton(QWidget parent) {
+ super(parent);
+ }
+
+ @Override
+ protected void mousePressEvent(QMouseEvent e) {
+ if (MouseButton.LeftButton.equals(e.button()) && ToolButtonPopupMode.MenuButtonPopup.equals(popupMode())) {
+ QStyleOptionToolButton opt = new QStyleOptionToolButton();
+ initStyleOption(opt);
+ QRect popupr = style().subControlRect(ComplexControl.CC_ToolButton, opt,
+ QStyle.SubControl.SC_ToolButtonMenu, this);
+ if (popupr.isValid() && popupr.contains(e.pos())) {
+ sendShowDropDownEvent();
+ return;
+ }
+ }
+ super.mousePressEvent(e);
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ToolTip.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ToolTip.java
new file mode 100644
index 0000000000..f79ffbbad4
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/ToolTip.java
@@ -0,0 +1,512 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Instances of this class represent popup windows that are used to inform or
+ * warn the user.
+ * <p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>BALLOON, ICON_ERROR, ICON_INFORMATION, ICON_WARNING</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Selection</dd>
+ * </dl>
+ * </p>
+ * <p>
+ * Note: Only one of the styles ICON_ERROR, ICON_INFORMATION, and ICON_WARNING
+ * may be specified.
+ * </p>
+ * <p>
+ * IMPORTANT: This class is intended to be subclassed <em>only</em> within the
+ * SWT implementation.
+ * </p>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#tooltips">Tool Tips
+ * snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ *
+ * @since 3.2
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public class ToolTip extends Widget {
+ Shell parent;
+ TrayItem item;
+ String text = ""; //$NON-NLS-1$
+ String message = ""; //$NON-NLS-1$
+ int id, x, y;
+ boolean autoHide = true, hasLocation, visible;
+ static final int TIMER_ID = 100;
+
+ /**
+ * 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#ICON_ERROR
+ * @see SWT#ICON_INFORMATION
+ * @see SWT#ICON_WARNING
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+ public ToolTip(Shell parent, int style) {
+ super(parent, checkStyle(style));
+ this.parent = parent;
+ checkAndUpdateOrientation(parent);
+ // parent.createToolTip(this);
+ }
+
+ static int checkStyle(int style) {
+ int mask = SWT.ICON_ERROR | SWT.ICON_INFORMATION | SWT.ICON_WARNING;
+ if ((style & mask) == 0) {
+ return style;
+ }
+ return checkBits(style, SWT.ICON_INFORMATION, SWT.ICON_WARNING, SWT.ICON_ERROR, 0, 0, 0);
+ }
+
+ /**
+ * Adds the listener to the collection of listeners who will be notified
+ * when the receiver is selected by the user, by sending it one of the
+ * messages defined in the <code>SelectionListener</code> interface.
+ * <p>
+ * <code>widgetSelected</code> is called when the receiver is selected.
+ * <code>widgetDefaultSelected</code> is not called.
+ * </p>
+ *
+ * @param listener
+ * the listener which should be notified when the receiver is
+ * selected by the user
+ *
+ * @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);
+ }
+
+ @Override
+ void destroyWidget() {
+ if (parent != null) {
+ // parent.destroyToolTip( this );
+ }
+ releaseQWidget();
+ }
+
+ /**
+ * Returns <code>true</code> if the receiver is automatically hidden by the
+ * platform, and <code>false</code> otherwise.
+ *
+ * @return the receiver's auto hide 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 getAutoHide() {
+ checkWidget();
+ return autoHide;
+ }
+
+ /**
+ * Returns the receiver's message, which will be an empty string if it has
+ * never been set.
+ *
+ * @return the receiver's message
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if 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 getMessage() {
+ checkWidget();
+ return message;
+ }
+
+ /**
+ * Returns the receiver's parent, which must be a <code>Shell</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 Shell getParent() {
+ checkWidget();
+ return parent;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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 (item != null) {
+ return visible;
+ }
+ return false;
+ }
+
+ /**
+ * 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();
+ if (item != null) {
+ return getVisible() && item.getVisible();
+ }
+ return getVisible();
+ }
+
+ @Override
+ void releaseQWidget() {
+ super.releaseQWidget();
+ parent = null;
+ item = null;
+ id = -1;
+ }
+
+ @Override
+ void releaseWidget() {
+ super.releaseWidget();
+ if (item == null) {
+ if (autoHide) {
+ // TODO
+ }
+ }
+ if (item != null && item.toolTip == this) {
+ item.toolTip = null;
+ }
+ item = null;
+ text = message = null;
+ }
+
+ /**
+ * Removes the listener from the collection of listeners who will be
+ * notified when the receiver is selected by the user.
+ *
+ * @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);
+ }
+
+ /**
+ * Makes the receiver hide automatically when <code>true</code>, and remain
+ * visible when <code>false</code>.
+ *
+ * @param autoHide
+ * the auto hide 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
+ * @see #setVisible
+ */
+ public void setAutoHide(boolean autoHide) {
+ checkWidget();
+ this.autoHide = autoHide;
+ // TODO - update when visible
+ }
+
+ /**
+ * Sets the location of the receiver, which must be a tooltip, 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>
+ *
+ * @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();
+ this.x = x;
+ this.y = y;
+ hasLocation = true;
+ // TODO - update when visible
+ }
+
+ /**
+ * Sets the location of the receiver, which must be a tooltip, 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 tooltips.
+ * </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>
+ */
+ public void setLocation(Point location) {
+ checkWidget();
+ if (location == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ setLocation(location.x, location.y);
+ }
+
+ /**
+ * Sets the receiver's message.
+ *
+ * @param string
+ * the new message
+ *
+ * @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 setMessage(String string) {
+ checkWidget();
+ if (string == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ message = string;
+ // TODO - update when visible
+ }
+
+ /**
+ * Sets the receiver's text.
+ *
+ * @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);
+ }
+ text = string;
+ // TODO - update when visible
+ }
+
+ /**
+ * 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 == getVisible()) {
+ return;
+ // TODO
+ }
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Tracker.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Tracker.java
new file mode 100644
index 0000000000..a055510abe
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Tracker.java
@@ -0,0 +1,859 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#tracker">Tracker
+ * snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class Tracker extends Widget {
+ Control parent;
+ boolean tracking, cancelled, stippled;
+ Rectangle[] rectangles = new Rectangle[0], proportions = rectangles;
+ Rectangle bounds;
+ int /* long */resizeCursor;
+ Cursor clientCursor;
+ int cursorOrientation = SWT.NONE;
+ boolean inEvent = false;
+ int /* long */hwndTransparent, hwndOpaque, oldTransparentProc, oldOpaqueProc;
+ int oldX, oldY;
+
+ /*
+ * 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() {
+ if (bounds == null) {
+ return null;
+ }
+ int newX = bounds.x + bounds.width / 2;
+ int newY = bounds.y;
+ // POINT pt = new POINT();
+ // pt.x = newX;
+ // pt.y = newY;
+ // /*
+ // * Convert to screen coordinates iff needed
+ // */
+ // if (parent != null) {
+ // //OS.ClientToScreen(parent.handle, pt);
+ // }
+ // OS.SetCursorPos(pt.x, pt.y);
+ //TODO
+ return new Point(newX, newY);
+ }
+
+ Point adjustResizeCursor() {
+ if (bounds == null) {
+ return null;
+ }
+ 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;
+ }
+
+ // POINT pt = new POINT();
+ // pt.x = newX;
+ // pt.y = newY;
+ // /*
+ // * Convert to screen coordinates iff needed
+ // */
+ // if (parent != null) {
+ // //OS.ClientToScreen(parent.handle, pt);
+ // }
+ // OS.SetCursorPos(pt.x, pt.y);
+ //
+ // /*
+ // * If the client has not provided a custom cursor then determine the
+ // * appropriate resize cursor.
+ // */
+ // if (clientCursor == null) {
+ // int /* long */newCursor = 0;
+ // switch (cursorOrientation) {
+ // case SWT.UP:
+ // newCursor = OS.LoadCursor(0, OS.IDC_SIZENS);
+ // break;
+ // case SWT.DOWN:
+ // newCursor = OS.LoadCursor(0, OS.IDC_SIZENS);
+ // break;
+ // case SWT.LEFT:
+ // newCursor = OS.LoadCursor(0, OS.IDC_SIZEWE);
+ // break;
+ // case SWT.RIGHT:
+ // newCursor = OS.LoadCursor(0, OS.IDC_SIZEWE);
+ // break;
+ // case SWT.LEFT | SWT.UP:
+ // newCursor = OS.LoadCursor(0, OS.IDC_SIZENWSE);
+ // break;
+ // case SWT.RIGHT | SWT.DOWN:
+ // newCursor = OS.LoadCursor(0, OS.IDC_SIZENWSE);
+ // break;
+ // case SWT.LEFT | SWT.DOWN:
+ // newCursor = OS.LoadCursor(0, OS.IDC_SIZENESW);
+ // break;
+ // case SWT.RIGHT | SWT.UP:
+ // newCursor = OS.LoadCursor(0, OS.IDC_SIZENESW);
+ // break;
+ // default:
+ // newCursor = OS.LoadCursor(0, OS.IDC_SIZEALL);
+ // break;
+ // }
+ // OS.SetCursor(newCursor);
+ // if (resizeCursor != 0) {
+ // OS.DestroyCursor(resizeCursor);
+ // }
+ // resizeCursor = newCursor;
+ // }
+ //TODO
+ 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() {
+ if (rectangles.length == 0) {
+ return null;
+ }
+ 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();
+ if (bounds != null) {
+ 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(Rectangle[] rects, boolean stippled) {
+ // if (parent == null && OS.WIN32_VERSION >= OS.VERSION(6, 0)) {
+ // RECT rect1 = new RECT();
+ // int bandWidth = stippled ? 3 : 1;
+ // for (int i = 0; i < rects.length; i++) {
+ // Rectangle rect = rects[i];
+ // rect1.left = rect.x - bandWidth;
+ // rect1.top = rect.y - bandWidth;
+ // rect1.right = rect.x + rect.width + bandWidth * 2;
+ // rect1.bottom = rect.y + rect.height + bandWidth * 2;
+ // OS.RedrawWindow(hwndOpaque, rect1, 0, OS.RDW_INVALIDATE);
+ // }
+ // return;
+ // }
+ // int bandWidth = 1;
+ // int /* long */hwndTrack = OS.GetDesktopWindow();
+ // if (parent != null) {
+ // //hwndTrack = parent.handle;
+ // }
+ // int /* long */hDC = OS.GetDCEx(hwndTrack, 0, OS.DCX_CACHE);
+ // int /* long */hBitmap = 0, hBrush = 0, oldBrush = 0;
+ // if (stippled) {
+ // bandWidth = 3;
+ // byte[] bits = { -86, 0, 85, 0, -86, 0, 85, 0, -86, 0, 85, 0, -86, 0, 85, 0 };
+ // hBitmap = OS.CreateBitmap(8, 8, 1, 1, bits);
+ // hBrush = OS.CreatePatternBrush(hBitmap);
+ // oldBrush = OS.SelectObject(hDC, hBrush);
+ // }
+ // for (int i = 0; i < rects.length; i++) {
+ // Rectangle rect = rects[i];
+ // OS.PatBlt(hDC, rect.x, rect.y, rect.width, bandWidth, OS.PATINVERT);
+ // OS.PatBlt(hDC, rect.x, rect.y + bandWidth, bandWidth, rect.height - bandWidth * 2, OS.PATINVERT);
+ // OS.PatBlt(hDC, rect.x + rect.width - bandWidth, rect.y + bandWidth, bandWidth, rect.height - bandWidth * 2,
+ // OS.PATINVERT);
+ // OS.PatBlt(hDC, rect.x, rect.y + rect.height - bandWidth, rect.width, bandWidth, OS.PATINVERT);
+ // }
+ // if (stippled) {
+ // OS.SelectObject(hDC, oldBrush);
+ // OS.DeleteObject(hBrush);
+ // OS.DeleteObject(hBitmap);
+ // }
+ // OS.ReleaseDC(hwndTrack, hDC);
+ }
+
+ /**
+ * 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();
+ Rectangle[] result = new Rectangle[rectangles.length];
+ for (int i = 0; i < rectangles.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 moveRectangles(int xChange, int yChange) {
+ if (bounds == null) {
+ return;
+ }
+ 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();
+ 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;
+ }
+
+ /*
+ * If this tracker is being created without a mouse drag then we need to
+ * create a transparent window that fills the screen in order to get all
+ * mouse/keyboard events that occur outside of our visible windows (ie.-
+ * over the desktop).
+ */
+ // TODO
+ tracking = false;
+ return !cancelled;
+ }
+
+ @Override
+ void releaseWidget() {
+ super.releaseWidget();
+ parent = null;
+ rectangles = proportions = null;
+ bounds = 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.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 (bounds == null) {
+ return;
+ }
+ /*
+ * 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 = newCursor;
+ // TODO
+ // if (newCursor != null) {
+ // if (inEvent) {
+ // OS.SetCursor(clientCursor.handle);
+ // }
+ // }
+ }
+
+ /**
+ * 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);
+ }
+ this.rectangles = new Rectangle[rectangles.length];
+ for (int i = 0; i < rectangles.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;
+ }
+
+ void update() {
+ if (parent == null) {
+ return;
+ }
+ if (parent != null) {
+ if (parent.isDisposed()) {
+ return;
+ }
+ Shell shell = parent.getShell();
+ shell._update();
+ } else {
+ display.update();
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TrayItem.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TrayItem.java
new file mode 100644
index 0000000000..cdee0a48fe
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TrayItem.java
@@ -0,0 +1,536 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.MenuDetectListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Instances of this class represent icons that can be placed on the system tray
+ * or task bar status area.
+ * <p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>(none)</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>DefaultSelection, MenuDetect, Selection</dd>
+ * </dl>
+ * </p>
+ * <p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#tray">Tray, TrayItem
+ * snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ *
+ * @since 3.0
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class TrayItem extends Item {
+ Tray parent;
+ int id;
+ Image image2;
+ ToolTip toolTip;
+ String toolTipText;
+ boolean visible = true;
+
+ /**
+ * Constructs a new instance of this class given its parent (which must be a
+ * <code>Tray</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 TrayItem(Tray parent, int style) {
+ super(parent, style);
+ this.parent = parent;
+ parent.createItem(this, parent.getItemCount());
+ createWidget();
+ }
+
+ /**
+ * Adds the listener to the collection of listeners who will be notified
+ * when the receiver is selected by the user, by sending it one of the
+ * messages defined in the <code>SelectionListener</code> interface.
+ * <p>
+ * <code>widgetSelected</code> is called when the receiver is selected
+ * <code>widgetDefaultSelected</code> is called when the receiver is
+ * double-clicked
+ * </p>
+ *
+ * @param listener
+ * the listener which should be notified when the receiver is
+ * selected by the user
+ *
+ * @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 platform-specific context menu trigger has occurred, by sending
+ * it one of the messages defined in the <code>MenuDetectListener</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 MenuDetectListener
+ * @see #removeMenuDetectListener
+ *
+ * @since 3.3
+ */
+ public void addMenuDetectListener(MenuDetectListener listener) {
+ checkWidget();
+ if (listener == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ TypedListener typedListener = new TypedListener(listener);
+ addListener(SWT.MenuDetect, typedListener);
+ }
+
+ @Override
+ protected void checkSubclass() {
+ if (!isValidSubclass()) {
+ error(SWT.ERROR_INVALID_SUBCLASS);
+ }
+ }
+
+ void createWidget() {
+ // TODO
+ }
+
+ @Override
+ void destroyWidget() {
+ parent.destroyItem(this);
+ releaseQWidget();
+ }
+
+ /**
+ * Returns the receiver's parent, which must be a <code>Tray</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>
+ *
+ * @since 3.2
+ */
+ public Tray getParent() {
+ checkWidget();
+ return parent;
+ }
+
+ /**
+ * Returns the receiver's tool tip, 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 ToolTip getToolTip() {
+ checkWidget();
+ return toolTip;
+ }
+
+ /**
+ * 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.
+ *
+ * @return the receiver's visibility
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if 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 visible;
+ }
+
+ void recreate() {
+ createWidget();
+ if (!visible) {
+ setVisible(false);
+ }
+ if (text.length() != 0) {
+ setText(text);
+ }
+ if (image != null) {
+ setImage(image);
+ }
+ if (toolTipText != null) {
+ setToolTipText(toolTipText);
+ }
+ }
+
+ @Override
+ void releaseQWidget() {
+ super.releaseQWidget();
+ parent = null;
+ }
+
+ @Override
+ void releaseWidget() {
+ super.releaseWidget();
+ if (toolTip != null) {
+ toolTip.item = null;
+ }
+ toolTip = null;
+ if (image2 != null) {
+ image2.dispose();
+ }
+ image2 = null;
+ toolTipText = null;
+ // NOTIFYICONDATA iconData = OS.IsUnicode ? (NOTIFYICONDATA) new NOTIFYICONDATAW() : new NOTIFYICONDATAA();
+ // iconData.cbSize = NOTIFYICONDATA.sizeof;
+ // iconData.uID = id;
+ // iconData.hWnd = display.hwndMessage;
+ // OS.Shell_NotifyIcon(OS.NIM_DELETE, iconData);
+ }
+
+ /**
+ * Removes the listener from the collection of listeners who will be
+ * notified when the receiver is selected by the user.
+ *
+ * @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 platform-specific context menu trigger has occurred.
+ *
+ * @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 MenuDetectListener
+ * @see #addMenuDetectListener
+ *
+ * @since 3.3
+ */
+ public void removeMenuDetectListener(MenuDetectListener listener) {
+ checkWidget();
+ if (listener == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (eventTable == null) {
+ return;
+ }
+ eventTable.unhook(SWT.MenuDetect, listener);
+ }
+
+ /**
+ * Sets the receiver's image.
+ *
+ * @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>
+ */
+ @Override
+ public void setImage(Image image) {
+ checkWidget();
+ if (image != null && image.isDisposed()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ super.setImage(image);
+ // if (image2 != null)
+ // image2.dispose();
+ // image2 = null;
+ // QImage hIcon = null;
+ // Image icon = image;
+ // if (icon != null) {
+ // switch (icon.type) {
+ // case SWT.BITMAP:
+ // image2 = Display.createIcon(image);
+ // hIcon = image2.getQImage();
+ // break;
+ // case SWT.ICON:
+ // hIcon = icon.getQImage();
+ // break;
+ // }
+ // }
+ //getQTray().setIcon( image.getQIcon() );
+ }
+
+ /**
+ * Sets the receiver's tool tip to the argument, which may be null
+ * indicating that no tool tip should be shown.
+ *
+ * @param toolTip
+ * the new tool tip (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 setToolTip(ToolTip toolTip) {
+ checkWidget();
+ ToolTip oldTip = this.toolTip, newTip = toolTip;
+ if (oldTip != null) {
+ oldTip.item = null;
+ }
+ this.toolTip = newTip;
+ if (newTip != null) {
+ newTip.item = this;
+ }
+ }
+
+ /**
+ * Sets the receiver's tool tip text to the argument, which may be null
+ * indicating that the default tool tip for the control will be shown. For a
+ * control that has a default tool tip, such as the Tree control on Windows,
+ * setting the tool tip text to an empty string replaces the default,
+ * causing no tool tip text to be shown.
+ * <p>
+ * The mnemonic indicator (character '&amp;') is not displayed in a tool
+ * tip. To display a single '&amp;' in the tool tip, the character '&amp;'
+ * can be escaped by doubling it in the string.
+ * </p>
+ *
+ * @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;
+ // NOTIFYICONDATA iconData = OS.IsUnicode ? (NOTIFYICONDATA) new NOTIFYICONDATAW() : new NOTIFYICONDATAA();
+ // TCHAR buffer = new TCHAR(0, toolTipText == null ? "" : toolTipText, true);
+ // /*
+ // * Note that the size of the szTip field is different in version 5.0 of
+ // * shell32.dll.
+ // */
+ // int length = 64; //OS.SHELL32_MAJOR < 5 ? 64 : 128;
+ // if (OS.IsUnicode) {
+ // char[] szTip = ((NOTIFYICONDATAW) iconData).szTip;
+ // length = Math.min(length - 1, buffer.length());
+ // System.arraycopy(buffer.chars, 0, szTip, 0, length);
+ // } else {
+ // byte[] szTip = ((NOTIFYICONDATAA) iconData).szTip;
+ // length = Math.min(length - 1, buffer.length());
+ // System.arraycopy(buffer.bytes, 0, szTip, 0, length);
+ // }
+ // iconData.cbSize = NOTIFYICONDATA.sizeof;
+ // iconData.uID = id;
+ // // iconData.hWnd = display.hwndMessage;
+ // // iconData.uFlags = OS.NIF_TIP;
+ // // OS.Shell_NotifyIcon(OS.NIM_MODIFY, iconData);
+ }
+
+ /**
+ * Makes the receiver visible if the argument is <code>true</code>, and
+ * makes it invisible otherwise.
+ *
+ * @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 (this.visible == visible) {
+ return;
+ }
+ if (visible) {
+ /*
+ * It is possible (but unlikely), that application code could have
+ * disposed the widget in the show event. If this happens, just
+ * return.
+ */
+ sendEvent(SWT.Show);
+ if (isDisposed()) {
+ return;
+ }
+ }
+ this.visible = visible;
+ // TODO
+ if (!visible) {
+ sendEvent(SWT.Hide);
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Tree.java
new file mode 100644
index 0000000000..c9a145b5a6
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Tree.java
@@ -0,0 +1,1913 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.trolltech.qt.core.QModelIndex;
+import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.core.Qt.DropActions;
+import com.trolltech.qt.core.Qt.ScrollBarPolicy;
+import com.trolltech.qt.core.Qt.SortOrder;
+import com.trolltech.qt.gui.QAbstractItemDelegate;
+import com.trolltech.qt.gui.QDragEnterEvent;
+import com.trolltech.qt.gui.QDragLeaveEvent;
+import com.trolltech.qt.gui.QDragMoveEvent;
+import com.trolltech.qt.gui.QDropEvent;
+import com.trolltech.qt.gui.QHeaderView;
+import com.trolltech.qt.gui.QPainter;
+import com.trolltech.qt.gui.QStyleOptionViewItem;
+import com.trolltech.qt.gui.QTreeWidget;
+import com.trolltech.qt.gui.QTreeWidgetItem;
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.qt.gui.QAbstractItemView.DragDropMode;
+import com.trolltech.qt.gui.QAbstractItemView.ScrollHint;
+import com.trolltech.qt.gui.QAbstractItemView.SelectionBehavior;
+import com.trolltech.qt.gui.QAbstractItemView.SelectionMode;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.events.TreeListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * 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 normally make sense to add <code>Control</code> children to it, or
+ * set a layout on it, unless implementing something like a cell editor.
+ * </p>
+ * <p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>SINGLE, MULTI, CHECK, FULL_SELECTION, VIRTUAL, NO_SCROLL</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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#tree">Tree, TreeItem,
+ * TreeColumn snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example:
+ * ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class Tree extends Composite {
+ private List<TreeItem> items;
+ private List<TreeColumn> columns;
+ TreeColumn sortColumn;
+ int sortDirection;
+ boolean customDraw;
+ private boolean linesVisible;
+ private static final int GRID_WIDTH = 1;
+ private TreeItemDelegate itemDelegate;
+
+ /**
+ * 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#VIRTUAL
+ * @see SWT#NO_SCROLL
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+ public Tree(Composite parent, int style) {
+ super(parent, checkStyle(style));
+ }
+
+ @Override
+ protected void connectSignals() {
+ QTreeWidget tree = getQTreeWidget();
+
+ tree.itemExpanded.connect(this, "qtTreeItemExpandedEvent(QTreeWidgetItem)"); //$NON-NLS-1$
+ tree.itemCollapsed.connect(this, "qtTreeItemCollapsedEvent(QTreeWidgetItem)"); //$NON-NLS-1$
+ tree.itemDoubleClicked.connect(this, "qtTreeItemDoubleClickedEvent(QTreeWidgetItem,Integer)"); //$NON-NLS-1$
+ tree.itemSelectionChanged.connect(this, "qtTreeSelectionChanged()"); //$NON-NLS-1$
+ }
+
+ @Override
+ QWidget createQWidget(int style) {
+ state &= ~(CANVAS | THEME_BACKGROUND);
+ items = new ArrayList<TreeItem>(4);
+ columns = new ArrayList<TreeColumn>(4);
+
+ QTreeWidget tree = new MyQTreeWidget();
+ tree.setHeaderHidden(true);
+
+ if ((style & SWT.NO_SCROLL) != 0) {
+ tree.setHorizontalScrollBarPolicy(ScrollBarPolicy.ScrollBarAlwaysOff);
+ tree.setVerticalScrollBarPolicy(ScrollBarPolicy.ScrollBarAlwaysOff);
+ }
+
+ // default value is singleSelection
+ if ((style & SWT.MULTI) != 0) {
+ tree.setSelectionMode(SelectionMode.ExtendedSelection);
+ } else {
+ tree.setSelectionMode(SelectionMode.SingleSelection);
+ }
+
+ if ((style & SWT.FULL_SELECTION) != 0) {
+ tree.setSelectionBehavior(SelectionBehavior.SelectRows);
+ } else {
+ tree.setSelectionBehavior(SelectionBehavior.SelectItems);
+ }
+
+ QAbstractItemDelegate originalItemDelegate = tree.itemDelegate();
+ itemDelegate = new TreeItemDelegate(originalItemDelegate);
+ tree.setItemDelegate(itemDelegate);
+
+ setQMasterWidget(tree);
+ return tree.viewport();
+ }
+
+ QTreeWidget getQTreeWidget() {
+ return (QTreeWidget) getQMasterWidget();
+ }
+
+ @Override
+ protected void checkAndUpdateBorder() {
+ checkAndUpdateBorder(getQMasterWidget());
+ super.checkAndUpdateBorder();
+ }
+
+ @Override
+ protected Color getDefaultBackgroundColor() {
+ return display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
+ }
+
+ static int checkStyle(int style) {
+ /*
+ * Feature in Windows. Even when WS_HSCROLL or WS_VSCROLL is not
+ * specified, Windows creates trees and tables with scroll bars. The fix
+ * is to set H_SCROLL and V_SCROLL.
+ *
+ * NOTE: This code appears on all platforms so that applications have
+ * consistent scroll bar behavior.
+ */
+ if ((style & SWT.NO_SCROLL) == 0) {
+ style |= SWT.H_SCROLL | SWT.V_SCROLL;
+ }
+ /*
+ * Note: Windows only supports TVS_NOSCROLL and TVS_NOHSCROLL.
+ */
+ if ((style & SWT.H_SCROLL) != 0 && (style & SWT.V_SCROLL) == 0) {
+ style |= SWT.V_SCROLL;
+ }
+ return checkBits(style, SWT.SINGLE, SWT.MULTI, 0, 0, 0, 0);
+ }
+
+ @Override
+ public void setDragEnabled(boolean enabled) {
+ getQTreeWidget().setDragEnabled(enabled);
+ }
+
+ @Override
+ public void setAcceptDrops(boolean accept) {
+ super.setAcceptDrops(accept);
+ getQTreeWidget().setDragDropMode(DragDropMode.DragDrop);
+ getQTreeWidget().setDropIndicatorShown(true);
+ }
+
+ public void highlightItem(TreeItem item) {
+ System.out.println("highlightItem: " + item);
+ if (item != null) {
+ getQTreeWidget().setCurrentItem(item.getQItem());
+ } else {
+ getQTreeWidget().setCurrentItem(null);
+ }
+ }
+
+ /**
+ * Adds the listener to the collection of listeners who will be notified
+ * when the user changes the receiver's selection, 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 the <code>SWT.CHECK</code> style 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 when the user changes
+ * the receiver's selection
+ *
+ * @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);
+ }
+
+ @Override
+ 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();
+ if (_getItemCount() == 0) {
+ return;
+ }
+ validateItemIndex(index);
+ items.get(index).clear(0, all);
+ }
+
+ private void validateItemIndex(int index) {
+ if (index < 0 || index >= _getItemCount()) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+ }
+
+ /**
+ * 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();
+ for (TreeItem item : items) {
+ item.clear(0, all);
+ }
+ }
+
+ void addColumn(TreeColumn column, int index) {
+ int columnCount = columns.size();
+ if (!(0 <= index && index <= columnCount)) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+
+ if (index == columnCount) {
+ columns.add(column);
+ } else {
+ columns.add(index, column);
+ }
+ // QHeaderView header = getQTreeWidget().header();
+ // if (index >= columnCount) {
+ // header.addAction(column.getQAction());
+ // } else {
+ // QAction before = header.actions().get(index);
+ // header.insertAction(before, column.getQAction());
+ // }
+ }
+
+ void removeColumn(TreeColumn treeColumn) {
+ columns.remove(treeColumn);
+ //getQTreeWidget().headerItem().removeAction(treeColumn.getQAction());
+ }
+
+ void addItem(TreeItem item, int index) {
+ if (index >= 0 && index < _getItemCount()) {
+ items.add(index, item);
+ getQTreeWidget().insertTopLevelItem(index, item.getQItem());
+ } else {
+ items.add(item);
+ getQTreeWidget().addTopLevelItem(item.getQItem());
+ }
+ }
+
+ void removeItem(TreeItem item) {
+ items.remove(item);
+ getQTreeWidget().invisibleRootItem().removeChild(item.getQItem());
+ }
+
+ /**
+ * Deselects an item in the receiver. If the item was already deselected, it
+ * remains deselected.
+ *
+ * @param item
+ * the item to be deselected
+ *
+ * @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.4
+ */
+ public void deselect(TreeItem item) {
+ checkWidget();
+ if (item == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (item.isDisposed()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+
+ item.getQItem().setSelected(false);
+ }
+
+ /**
+ * 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();
+ getQTreeWidget().clearSelection();
+ }
+
+ /**
+ * 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();
+ return GRID_WIDTH;
+ }
+
+ /**
+ * 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();
+ return getQTreeWidget().header().height();
+ }
+
+ /**
+ * 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();
+ return !getQTreeWidget().isHeaderHidden();
+ }
+
+ /**
+ * 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 < columns.size())) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+ return columns.get(index);
+ }
+
+ /**
+ * 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 _getColumnCount();
+ }
+
+ int _getColumnCount() {
+ return columns.size();
+ }
+
+ /**
+ * 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();
+ if (_getColumnCount() == 0) {
+ return new int[0];
+ }
+ int[] order = new int[_getColumnCount()];
+ QHeaderView header = getQTreeWidget().header();
+ for (int i = 0; i < order.length; i++) {
+ order[i] = header.visualIndex(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[] result = new TreeColumn[_getColumnCount()];
+ int i = 0;
+ for (TreeColumn col : columns) {
+ result[i] = col;
+ 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>
+ *
+ * @since 3.1
+ */
+ public TreeItem getItem(int index) {
+ checkWidget();
+ if (index < 0 || index >= items.size()) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+ return items.get(index);
+ }
+
+ /**
+ * 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);
+ }
+ return _getItem(point);
+ }
+
+ private TreeItem _getItem(Point point) {
+ QTreeWidgetItem qItem = getQTreeWidget().itemAt(point.x, point.y);
+ for (TreeItem item : items) {
+ if (item.getQItem() == qItem) {
+ return item;
+ }
+ TreeItem ti = item.getItem(qItem);
+ if (ti != null) {
+ return ti;
+ }
+ }
+ return null;
+
+ }
+
+ /**
+ * 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 items.size();
+ }
+
+ int _getItemCount() {
+ return items.size();
+ }
+
+ /**
+ * 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();
+ int itemHeight = 0;
+ if (items.size() > 0) {
+ itemHeight = getQTreeWidget().sizeHintForRow(0);
+ } else {
+ // add dummy node and get the height
+ getQTreeWidget().addTopLevelItem(new QTreeWidgetItem());
+ itemHeight = getQTreeWidget().sizeHintForRow(0);
+ getQTreeWidget().clear();
+ }
+ return itemHeight;
+ }
+
+ /**
+ * 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[] arr = new TreeItem[_getItemCount()];
+ int i = 0;
+ for (TreeItem item : items) {
+ arr[i] = item;
+ i++;
+ }
+ return arr;
+ }
+
+ /**
+ * Returns <code>true</code> if the receiver's lines are visible, and
+ * <code>false</code> otherwise. Note that some platforms draw grid lines
+ * while others may draw alternating row colors.
+ * <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();
+ return linesVisible;
+ }
+
+ /**
+ * 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();
+ List<QTreeWidgetItem> selectedQItems = getQTreeWidget().selectedItems();
+ if (selectedQItems.isEmpty()) {
+ return new TreeItem[0];
+ }
+
+ TreeItem[] items = new TreeItem[selectedQItems.size()];
+ int i = 0;
+ for (QTreeWidgetItem item : selectedQItems) {
+ Widget widget = display.findControl(item);
+ if (widget instanceof TreeItem) {
+ items[i] = (TreeItem) widget;
+ }
+ i++;
+ }
+ return items;
+ }
+
+ /**
+ * 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();
+ return getQTreeWidget().selectedItems().size();
+ }
+
+ /**
+ * 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();
+ return sortColumn;
+ }
+
+ /**
+ * 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();
+ return sortDirection;
+ }
+
+ /**
+ * 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();
+ return _getItem(new Point(1, 1));
+ }
+
+ /**
+ * 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 column 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);
+ }
+ if (column.isDisposed()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ return columns.indexOf(column);
+ }
+
+ /**
+ * 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>
+ *
+ * @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);
+ }
+ return items.indexOf(item);
+ }
+
+ @Override
+ void releaseChildren(boolean destroy) {
+ if (items != null) {
+ for (TreeItem item : items) {
+ if (item != null && !item.isDisposed()) {
+ item.release(false);
+ }
+ }
+ items = null;
+ }
+ if (columns != null) {
+ for (TreeColumn column : columns) {
+ if (column != null && !column.isDisposed()) {
+ column.release(false);
+ }
+ }
+ columns = null;
+ }
+ super.releaseChildren(destroy);
+ }
+
+ @Override
+ void releaseWidget() {
+ super.releaseWidget();
+ customDraw = false;
+ }
+
+ /**
+ * 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();
+ List<TreeItem> copyOfItems = new ArrayList<TreeItem>(items);
+ for (TreeItem item : copyOfItems) {
+ item.dispose();
+ }
+ items.clear();
+ }
+
+ /**
+ * Removes the listener from the collection of listeners who will be
+ * notified when the user changes the receiver's selection.
+ *
+ * @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);
+ }
+
+ /**
+ * 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();
+ //TODO d'n'd
+ }
+
+ /**
+ * 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();
+ count = Math.max(0, count);
+ int itemCount = _getItemCount();
+ if (count == itemCount) {
+ return;
+ }
+ boolean isVirtual = (style & SWT.VIRTUAL) != 0;
+ if (!isVirtual) {
+ setRedraw(false);
+ }
+
+ if (count < itemCount) {
+ for (int i = itemCount - 1; i >= count; i--) {
+ removeItem(items.get(i));
+ }
+ return;
+ }
+ if (isVirtual) {
+ //TODO
+ } else {
+ for (int i = itemCount; i < count; i++) {
+ new TreeItem(this, SWT.NONE, i);
+ }
+ }
+ if (!isVirtual) {
+ setRedraw(true);
+ }
+ }
+
+ /**
+ * Sets the height of the area which would be used to display <em>one</em>
+ * of the items in the tree.
+ *
+ * @param itemHeight
+ * 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);
+ }
+ itemDelegate.setHeight(itemHeight);
+ update();
+ }
+
+ /**
+ * Marks the receiver's lines as visible if the argument is
+ * <code>true</code>, and marks it invisible otherwise. Note that some
+ * platforms draw grid lines while others may draw alternating row colors.
+ * <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();
+ if (linesVisible == show) {
+ return;
+ }
+ linesVisible = show;
+ getQTreeWidget().setAlternatingRowColors(show);
+ }
+
+ /**
+ * Selects an item in the receiver. If the item was already selected, it
+ * remains selected.
+ *
+ * @param item
+ * the item to be selected
+ *
+ * @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.4
+ */
+ public void select(TreeItem item) {
+ checkWidget();
+ if (item == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (item.isDisposed()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ item.getQItem().setSelected(true);
+ }
+
+ /**
+ * 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();
+ getQTreeWidget().selectAll();
+ }
+
+ /**
+ * 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);
+ }
+ int columnCount = _getColumnCount();
+ if (columnCount == 0) {
+ if (order.length != 0) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ return;
+ }
+ if (order.length != columnCount) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ QHeaderView header = getQTreeWidget().header();
+ for (int i = 0; i < columnCount; i++) {
+ int visualIndex = header.visualIndex(i);
+ header.moveSection(visualIndex, order[i]);
+ }
+ }
+
+ /**
+ * 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();
+ getQTreeWidget().setHeaderHidden(!show);
+ }
+
+ /**
+ * 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;
+ }
+ getQTreeWidget().clearSelection();
+ for (TreeItem item : items) {
+ QTreeWidgetItem treeWidgetItem = item.getQItem();
+ showItem(treeWidgetItem);
+ treeWidgetItem.setSelected(true);
+ }
+ }
+
+ private void showItem(QTreeWidgetItem item) {
+ if (item.parent() != null) {
+ if (!item.parent().isExpanded()) {
+ item.parent().setExpanded(true);
+ }
+ showItem(item.parent());
+ }
+ }
+
+ /**
+ * 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();
+ if (column != null && column.isDisposed()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ sortColumn = column;
+ getQTreeWidget().sortByColumn(indexOf(column), getQSortOrder());
+ }
+
+ /**
+ * 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;
+ }
+ sortDirection = direction;
+ if (sortColumn != null && !sortColumn.isDisposed()) {
+ getQTreeWidget().sortByColumn(indexOf(sortColumn), getQSortOrder());
+ }
+ }
+
+ /**
+ * @return
+ */
+ private SortOrder getQSortOrder() {
+ if ((sortDirection & SWT.UP) != 0) {
+ return SortOrder.AscendingOrder;
+ }
+ return SortOrder.DescendingOrder;
+ }
+
+ /**
+ * 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);
+ }
+ _showItem(item, ScrollHint.PositionAtTop);
+ }
+
+ /**
+ * 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;
+ }
+ getQTreeWidget().scrollToItem(getQTreeWidget().headerItem().child(index), ScrollHint.EnsureVisible);
+ }
+
+ /**
+ * 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);
+ }
+ _showItem(item, ScrollHint.EnsureVisible);
+ }
+
+ private void _showItem(TreeItem item, ScrollHint hint) {
+ getQTreeWidget().scrollToItem(item.getQItem(), hint);
+ }
+
+ /**
+ * 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();
+ List<QTreeWidgetItem> selection = getQTreeWidget().selectedItems();
+ if (selection != null && selection.size() > 0) {
+ getQTreeWidget().scrollToItem(selection.get(0), ScrollHint.EnsureVisible);
+ }
+ }
+
+ boolean sendTreeEvent(int eventType, QTreeWidgetItem item) {
+ Event event = new Event();
+ event.item = display.findControl(item);
+ sendEvent(eventType, event, true);
+ return !event.doit;
+ }
+
+ public boolean qtTreeItemCollapsedEvent(QTreeWidgetItem item) {
+ return sendTreeEvent(SWT.Collapse, item);
+ }
+
+ public boolean qtTreeItemExpandedEvent(QTreeWidgetItem item) {
+ return sendTreeEvent(SWT.Expand, item);
+ }
+
+ public void qtTreeItemDoubleClickedEvent(QTreeWidgetItem item, Integer column) {
+ sendEvent(SWT.DefaultSelection);
+ }
+
+ private final class TreeItemDelegate extends QAbstractItemDelegate {
+ private final QAbstractItemDelegate wrappedDelegate;
+ private int height = -1;
+
+ TreeItemDelegate(QAbstractItemDelegate wrappedDelegate) {
+ this.wrappedDelegate = wrappedDelegate;
+
+ }
+
+ public void setHeight(int height) {
+ this.height = height;
+ }
+
+ @Override
+ public void paint(QPainter painter, QStyleOptionViewItem item, QModelIndex index) {
+ wrappedDelegate.paint(painter, item, index);
+ }
+
+ @Override
+ public QSize sizeHint(QStyleOptionViewItem item, QModelIndex index) {
+ QSize size = wrappedDelegate.sizeHint(item, index);
+ if (height != -1) {
+ size.setHeight(height);
+ }
+ return size;
+ }
+
+ }
+
+ public boolean qtTreeSelectionChanged() {
+ List<QTreeWidgetItem> selectedItems = getQTreeWidget().selectedItems();
+ if (selectedItems.size() > 1) {
+ System.out.println("more than one item selected in tree, selecting first"); //$NON-NLS-1$
+ }
+ if (selectedItems.size() == 0) {
+ return sendTreeEvent(SWT.Selection, null);
+ } else {
+ // TODO what if more than one element is selected
+ return sendTreeEvent(SWT.Selection, selectedItems.get(0));
+ }
+ }
+
+ private final class MyQTreeWidget extends QTreeWidget {
+
+ @Override
+ protected void startDrag(DropActions supportedActions) {
+ // System.out.println("MyQTreeWidget.startDrag: " + supportedActions);
+ }
+
+ @Override
+ protected void dropEvent(QDropEvent event) {
+ sendDropEvent(event);
+ }
+
+ @Override
+ protected void dragMoveEvent(QDragMoveEvent event) {
+ sendDragMoveEvent(event);
+ }
+
+ @Override
+ protected void dragEnterEvent(QDragEnterEvent event) {
+ sendDragEnterEvent(event);
+ }
+
+ @Override
+ protected void dragLeaveEvent(QDragLeaveEvent event) {
+ sendDragLeaveEvent(event);
+ }
+
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TreeColumn.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TreeColumn.java
new file mode 100644
index 0000000000..1693962077
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TreeColumn.java
@@ -0,0 +1,714 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import com.trolltech.qt.core.Qt.AlignmentFlag;
+import com.trolltech.qt.gui.QHeaderView;
+import com.trolltech.qt.gui.QIcon;
+import com.trolltech.qt.gui.QTreeWidget;
+import com.trolltech.qt.gui.QTreeWidgetItem;
+import com.trolltech.qt.gui.QHeaderView.ResizeMode;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#tree">Tree, TreeItem,
+ * TreeColumn snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ *
+ * @since 3.1
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class TreeColumn extends Item {
+ Tree parent;
+ private boolean resizable, moveable;
+
+ /**
+ * 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) {
+ super(parent, checkStyle(style));
+ resizable = true;
+ this.parent = parent;
+ createQAction(parent, style, parent.getColumnCount());
+ }
+
+ /**
+ * 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>
+ * <p>
+ * Note that due to a restriction on some platforms, the first column is
+ * always left aligned.
+ * </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;
+ createQAction(parent, style, index);
+ }
+
+ private void adjustColumnCount() {
+ int columnCount = parent.getColumnCount();
+ if (getQTreeWidget().columnCount() <= columnCount) {
+ getQTreeWidget().setColumnCount(columnCount + 1);
+ }
+ }
+
+ protected void createQAction(Tree parent, int style, int index) {
+ adjustColumnCount();
+ parent.addColumn(this, index);
+ getQHeaderItem().setText(index, ""); //$NON-NLS-1$
+ }
+
+ @Override
+ void releaseQWidget() {
+ //display.removeControl(action);
+ super.releaseQWidget();
+ }
+
+ QTreeWidget getQTreeWidget() {
+ return parent.getQTreeWidget();
+ }
+
+ QTreeWidgetItem getQHeaderItem() {
+ return getQTreeWidget().headerItem();
+ }
+
+ QHeaderView getQHeaderView() {
+ return getQTreeWidget().header();
+ }
+
+ /**
+ * 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 the user, 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 when the control is
+ * selected by the user
+ *
+ * @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);
+ }
+
+ @Override
+ protected void checkSubclass() {
+ if (!isValidSubclass()) {
+ error(SWT.ERROR_INVALID_SUBCLASS);
+ }
+ }
+
+ @Override
+ void destroyWidget() {
+ parent.removeColumn(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;
+ }
+
+ /**
+ * 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;
+ }
+
+ @Override
+ 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 index = parent.indexOf(this);
+ if (index == -1) {
+ return ""; //$NON-NLS-1$
+ }
+ return getQHeaderItem().toolTip(index);
+ }
+
+ /**
+ * 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();
+ int index = parent.indexOf(this);
+ if (index == -1) {
+ return 0;
+ }
+ return getQTreeWidget().header().sectionSize(index);
+ }
+
+ /**
+ * 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;
+ }
+ getQTreeWidget().resizeColumnToContents(index);
+ }
+
+ @Override
+ void releaseParent() {
+ super.releaseParent();
+ if (parent.sortColumn == this) {
+ parent.sortColumn = 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 by the user.
+ *
+ * @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>.
+ * <p>
+ * Note that due to a restriction on some platforms, the first column is
+ * always left aligned.
+ * </p>
+ *
+ * @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);
+
+ getQTreeWidget().headerItem().setTextAlignment(index, convertAlignment(style));
+ }
+
+ private int convertAlignment(int style) {
+ if ((style & SWT.CENTER) != 0) {
+ return AlignmentFlag.AlignCenter.value();
+ } else if ((style & SWT.RIGHT) != 0) {
+ return AlignmentFlag.AlignRight.value();
+ }
+ return AlignmentFlag.AlignLeft.value();
+ }
+
+ @Override
+ public void setImage(Image image) {
+ checkWidget();
+ if (image != null && image.isDisposed()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ super.setImage(image);
+ if (parent.sortColumn != this || parent.sortDirection != SWT.NONE) {
+ setImage(image, false, false);
+ }
+ }
+
+ void setImage(Image image, boolean sort, boolean right) {
+ int index = parent.indexOf(this);
+ if (index == -1) {
+ return;
+ }
+ if (image != null) {
+ QIcon icon = new QIcon();
+ icon.addPixmap(image.getQPixmap());
+ getQHeaderItem().setIcon(index, icon);
+ } else {
+ getQHeaderItem().setIcon(index, (QIcon) null);
+ }
+ }
+
+ /**
+ * 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;
+ getQHeaderView().setResizeMode(parent.indexOf(this), resizable ? ResizeMode.Interactive : ResizeMode.Fixed);
+ }
+
+ @Override
+ public void setText(String string) {
+ checkWidget();
+ if (string == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (string.equals(text)) {
+ return;
+ }
+ int index = parent.indexOf(this);
+ if (index == -1) {
+ return;
+ }
+ super.setText(string);
+ getQHeaderItem().setText(index, string);
+ }
+
+ /**
+ * Sets the receiver's tool tip text to the argument, which may be null
+ * indicating that the default tool tip for the control will be shown. For a
+ * control that has a default tool tip, such as the Tree control on Windows,
+ * setting the tool tip text to an empty string replaces the default,
+ * causing no tool tip text to be shown.
+ * <p>
+ * The mnemonic indicator (character '&amp;') is not displayed in a tool
+ * tip. To display a single '&amp;' in the tool tip, the character '&amp;'
+ * can be escaped by doubling it in the string.
+ * </p>
+ *
+ * @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 index = parent.indexOf(this);
+ if (index == -1) {
+ return;
+ }
+ getQHeaderItem().setToolTip(index, string);
+ }
+
+ /**
+ * 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();
+ if (width < 0) {
+ return;
+ }
+ int index = parent.indexOf(this);
+ if (index == -1) {
+ return;
+ }
+ getQTreeWidget().setColumnWidth(index, width);
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TreeItem.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TreeItem.java
new file mode 100644
index 0000000000..7ecd774bf9
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/TreeItem.java
@@ -0,0 +1,1573 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.trolltech.qt.gui.QBrush;
+import com.trolltech.qt.gui.QIcon;
+import com.trolltech.qt.gui.QTreeWidget;
+import com.trolltech.qt.gui.QTreeWidgetItem;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.internal.qt.QtSWTConverter;
+
+/**
+ * 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>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#tree">Tree, TreeItem,
+ * TreeColumn snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public class TreeItem extends Item {
+ private QTreeWidgetItem item;
+ private List<TreeItem> items;
+ private Tree parent;
+ private TreeItem parentItem;
+ private String[] strings;
+ private Image[] images;
+ private Font font;
+ private Font[] cellFont;
+ boolean cached;
+ private Color background;
+ private Color foreground;
+ private int[] cellBackground, cellForeground;
+ private boolean grayed;
+
+ /**
+ * 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(parent, null, style, -1);
+ }
+
+ /**
+ * 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(parent, null, style, index);
+ }
+
+ /**
+ * 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, -1);
+ }
+
+ /**
+ * 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);
+ }
+
+ TreeItem(Tree parent, TreeItem parentItem, int style, int index) {
+ super(parent, style);
+ this.parent = parent;
+ item = new QTreeWidgetItem();
+ items = new ArrayList<TreeItem>(4);
+ if (parentItem != null) {
+ this.parentItem = parentItem;
+ parentItem.addItem(this, index);
+ } else {
+ parent.addItem(this, index);
+ }
+ display.addControl(item, this);
+ }
+
+ void addItem(TreeItem item, int index) {
+ if (index >= 0 && index < items.size()) {
+ items.add(index, item);
+ this.item.insertChild(index, item.getQItem());
+ } else {
+ items.add(item);
+ this.item.addChild(item.getQItem());
+ }
+ }
+
+ void removeItem(TreeItem item) {
+ items.remove(item);
+ getQItem().removeChild(item.getQItem());
+ }
+
+ TreeItem getItem(QTreeWidgetItem qItem) {
+ for (TreeItem item : items) {
+ if (item.item == qItem) {
+ return item;
+ }
+ TreeItem ti = item.getItem(qItem);
+ if (ti != null) {
+ return ti;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ void releaseQWidget() {
+ super.releaseQWidget();
+ item = null;
+ }
+
+ QTreeWidgetItem getQItem() {
+ return item;
+ }
+
+ QTreeWidget getQTreeWidget() {
+ return parent.getQTreeWidget();
+ }
+
+ static TreeItem checkNull(TreeItem item) {
+ if (item == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ return item;
+ }
+
+ @Override
+ protected void checkSubclass() {
+ if (!isValidSubclass()) {
+ error(SWT.ERROR_INVALID_SUBCLASS);
+ }
+ }
+
+ void clear() {
+ for (int i = 0; i < parent.getColumnCount(); i++) {
+ item.setText(i, null);
+ item.setIcon(i, (QIcon) null);
+ item.setWhatsThis(i, null);
+ item.setFont(i, null);
+ }
+ text = ""; //$NON-NLS-1$
+ image = null;
+ strings = null;
+ images = null;
+ if ((parent.style & SWT.CHECK) != 0) {
+ //
+ }
+ background = foreground = null;
+ font = null;
+ cellBackground = cellForeground = null;
+ 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();
+ validateItemIndex(index);
+ if (index == 0) {
+ clear();
+ return;
+ }
+ TreeItem item = items.get(index);
+ item.clear(0, all);
+ }
+
+ private void validateItemIndex(int index) {
+ if (index < 0 || index >= items.size()) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+ }
+
+ /**
+ * 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();
+ clear();
+ for (TreeItem item : items) {
+ item.clearAll(all);
+ }
+ }
+
+ @Override
+ void destroyWidget() {
+ if (parentItem != null) {
+ parentItem.removeItem(this);
+ } else {
+ parent.removeItem(this);
+ }
+ super.destroyWidget();
+ item = null;
+ }
+
+ /**
+ * 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 (background == null) {
+ return parent.getBackground();
+ }
+ return 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.1
+ */
+ public Color getBackground(int index) {
+ checkWidget();
+ int count = Math.max(1, parent.getColumnCount());
+ if (0 > index || index > count - 1) {
+ return getBackground();
+ }
+ int pixel = cellBackground != null ? cellBackground[index] : -1;
+ return pixel == -1 ? getBackground() : Color.qt_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>
+ */
+ public Rectangle getBounds() {
+ checkWidget();
+ return QtSWTConverter.convert(getQTreeWidget().visualItemRect(item));
+ }
+
+ /**
+ * 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();
+ int count = Math.max(1, item.columnCount());
+ if (0 > index || index > count - 1) {
+ return new Rectangle(0, 0, 0, 0);
+ }
+
+ return QtSWTConverter.convert(getQTreeWidget().visualItemRect(item.child(index)));
+ }
+
+ /**
+ * 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.style & SWT.CHECK) == 0) {
+ return false;
+ }
+ return item.isSelected();
+ }
+
+ /**
+ * 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 item.isExpanded();
+ }
+
+ /**
+ * 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();
+ return font != null ? font : 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();
+ int count = Math.max(1, parent.getColumnCount());
+ if (0 > index || index > count - 1) {
+ return getFont();
+ }
+ if (cellFont == null || cellFont[index] == null) {
+ return getFont();
+ }
+ return cellFont[index];
+ }
+
+ /**
+ * 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 (foreground == null) {
+ return parent.getForeground();
+ }
+ return 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.1
+ */
+ public Color getForeground(int index) {
+ checkWidget();
+ int count = Math.max(1, parent.getColumnCount());
+ if (0 > index || index > count - 1) {
+ return getForeground();
+ }
+ int pixel = cellForeground != null ? cellForeground[index] : -1;
+ return pixel == -1 ? getForeground() : Color.qt_new(display, pixel);
+ }
+
+ /**
+ * 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.style & SWT.CHECK) == 0) {
+ return false;
+ }
+ return grayed;
+ }
+
+ /**
+ * 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 >= items.size()) {
+ error(SWT.ERROR_INVALID_RANGE);
+ }
+ return items.get(index);
+ }
+
+ /**
+ * 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();
+ return items.size();
+ }
+
+ /**
+ * 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();
+ return items.toArray(new TreeItem[items.size()]);
+ }
+
+ @Override
+ public Image getImage() {
+ checkWidget();
+ 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 (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();
+ //TODO image only ?
+ return QtSWTConverter.convert(getQTreeWidget().visualItemRect(getQItem().child(index)));
+ }
+
+ /**
+ * 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();
+ return parentItem;
+ }
+
+ /**
+ * 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 (index == 0) {
+ return getText();
+ }
+ if (strings != null) {
+ if (0 <= index && index < strings.length) {
+ String string = strings[index];
+ return string != null ? string : ""; //$NON-NLS-1$
+ }
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns a rectangle describing the size and location relative to its
+ * parent of the text at a column in the tree.
+ *
+ * @param index
+ * the index that specifies the column
+ * @return the receiver's bounding text 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.3
+ */
+ public Rectangle getTextBounds(int index) {
+ checkWidget();
+ //TODO text only ?
+ return QtSWTConverter.convert(getQTreeWidget().visualItemRect(getQItem().child(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 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 int indexOf(TreeItem item) {
+ checkWidget();
+ if (item == null) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ if (item.isDisposed()) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ return items.indexOf(item);
+ }
+
+ @Override
+ void releaseChildren(boolean destroy) {
+ if (destroy) {
+ for (int i = items.size() - 1; i > -1; i--) {
+ items.get(i).dispose();
+ }
+ items.clear();
+ }
+ super.releaseChildren(destroy);
+ }
+
+ @Override
+ void releaseWidget() {
+ super.releaseWidget();
+ strings = null;
+ images = null;
+ cellBackground = cellForeground = null;
+ cellFont = null;
+ display.removeControl(item);
+ }
+
+ /**
+ * 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();
+ QTreeWidgetItem qItem = getQItem();
+ for (TreeItem item : items) {
+ qItem.removeChild(item.getQItem());
+ }
+ items.clear();
+ }
+
+ /**
+ * 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);
+ }
+ Color pixel = null;
+ if (color != null) {
+ parent.customDraw = true;
+ pixel = color;
+ }
+ if (background == pixel) {
+ return;
+ }
+ background = pixel;
+ 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;
+ }
+ int pixel = -1;
+ if (color != null) {
+ parent.customDraw = true;
+ pixel = color.getPixel();
+ }
+ 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;
+ }
+ }
+
+ /**
+ * 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;
+ }
+ getQItem().setSelected(checked);
+ }
+
+ /**
+ * 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();
+ getQItem().setExpanded(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);
+ }
+ Font oldFont = this.font;
+ if (oldFont == font) {
+ return;
+ }
+ this.font = font;
+ if (oldFont != null && oldFont.equals(font)) {
+ return;
+ }
+ if (font != null) {
+ parent.customDraw = true;
+ }
+ if ((parent.style & SWT.VIRTUAL) != 0) {
+ cached = true;
+ }
+ item.setFont(0, font.getQFont());
+ }
+
+ /**
+ * 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;
+ }
+ if (cellFont == null) {
+ if (font == null) {
+ return;
+ }
+ cellFont = new Font[count];
+ }
+ Font oldFont = cellFont[index];
+ if (oldFont == font) {
+ return;
+ }
+ cellFont[index] = font;
+ if (oldFont != null && oldFont.equals(font)) {
+ return;
+ }
+ if (font != null) {
+ parent.customDraw = true;
+ }
+ if ((parent.style & SWT.VIRTUAL) != 0) {
+ cached = true;
+ }
+ if (font == null) {
+ item.setFont(index, null);
+ } else {
+ item.setFont(index, font.getQFont());
+ }
+ }
+
+ /**
+ * 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);
+ }
+ this.foreground = color;
+ item.setForeground(0, new QBrush(color.getColor()));
+ }
+
+ /**
+ * 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;
+ }
+ int pixel = -1;
+ if (color != null) {
+ parent.customDraw = true;
+ pixel = color.getPixel();
+ }
+ 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;
+ }
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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);
+ }
+ if (index == 0) {
+ if (image != null && image.isIcon()) {
+ if (image.equals(this.image)) {
+ return;
+ }
+ }
+ super.setImage(image);
+ }
+ int count = Math.max(1, parent.getColumnCount());
+ if (0 > index || index > count - 1) {
+ return;
+ }
+ if (images == null && index != 0) {
+ images = new Image[count];
+ images[0] = image;
+ }
+ if (images != null) {
+ if (image != null && image.isIcon()) {
+ if (image.equals(images[index])) {
+ return;
+ }
+ }
+ images[index] = image;
+ }
+ if ((parent.style & SWT.VIRTUAL) != 0) {
+ cached = true;
+ }
+ item.setIcon(index, image != null ? image.getQIcon() : null);
+ }
+
+ @Override
+ 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();
+ count = Math.max(0, count);
+ int itemCount = items.size();
+ if (count == itemCount) {
+ return;
+ }
+
+ if (count < itemCount) {
+ for (int i = itemCount - 1; i >= count; i--) {
+ removeItem(items.get(i));
+ }
+ return;
+ }
+ // if (isVirtual) {
+ // //TODO
+ // } else {
+ for (int i = itemCount; i < count; i++) {
+ new TreeItem(this, SWT.NONE, i);
+ }
+ }
+
+ /**
+ * 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);
+ }
+ if (index == 0) {
+ if (string.equals(text)) {
+ return;
+ }
+ super.setText(string);
+ }
+ int count = Math.max(1, parent.getColumnCount());
+ if (0 > index || index > count - 1) {
+ return;
+ }
+ if (strings == null && index != 0) {
+ strings = new String[count];
+ strings[0] = text;
+ }
+ if (strings != null) {
+ if (string.equals(strings[index])) {
+ return;
+ }
+ strings[index] = string;
+ }
+ if ((parent.style & SWT.VIRTUAL) != 0) {
+ cached = true;
+ }
+ getQItem().setText(index, string);
+ }
+
+ @Override
+ public void setText(String string) {
+ checkWidget();
+ setText(0, string);
+ }
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Widget.java b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Widget.java
new file mode 100644
index 0000000000..cf693513e6
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Widget.java
@@ -0,0 +1,1358 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Portion Copyright (c) 2009-2010 compeople AG (http://www.compeople.de).
+ * 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
+ * Compeople AG - QtJambi/Qt based implementation for Windows/Mac OS X/Linux
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.trolltech.qt.core.QObject;
+import com.trolltech.qt.gui.QContextMenuEvent;
+import com.trolltech.qt.gui.QKeyEvent;
+import com.trolltech.qt.gui.QMouseEvent;
+import com.trolltech.qt.gui.QMoveEvent;
+import com.trolltech.qt.gui.QPaintEvent;
+import com.trolltech.qt.gui.QResizeEvent;
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.qt.gui.QWindowStateChangeEvent;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.GCData;
+import org.eclipse.swt.internal.SWTEventListener;
+
+/**
+ * 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
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further
+ * information</a>
+ */
+
+public abstract class Widget {
+ public static final String QT_SWT_CONTROL_PROPERTY = "__SWT_CONTROL";//$NON-NLS-1$
+ int style, state;
+ Display display;
+ EventTable eventTable;
+ private Map<String, Object> data;
+ private Object mainData;
+
+ /* 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 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 hierarchy */
+ 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;
+
+ /* More global widget state flags */
+ static final int TRACK_MOUSE = 1 << 13;
+ static final int FOREIGN_HANDLE = 1 << 14;
+ static final int DRAG_DETECT = 1 << 15;
+
+ /* Move and resize state flags */
+ static final int MOVE_OCCURRED = 1 << 16;
+ static final int MOVE_DEFERRED = 1 << 17;
+ static final int RESIZE_OCCURRED = 1 << 18;
+ static final int RESIZE_DEFERRED = 1 << 19;
+
+ /* Ignore WM_CHANGEUISTATE */
+ static final int IGNORE_WM_CHANGEUISTATE = 1 << 20;
+
+ /* Default size for widgets */
+ static final int DEFAULT_WIDTH = 64;
+ static final int DEFAULT_HEIGHT = 64;
+
+ /* Check and initialize the Common Controls DLL */
+ static final int MAJOR = 5, MINOR = 80;
+ private QWidget qWidget;
+
+ /**
+ * 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 setQWidget(QWidget qWidget) {
+ this.qWidget = qWidget;
+ }
+
+ public QWidget getQWidget() {
+ return qWidget;
+ }
+
+ protected QWidget getQMasterWidget() {
+ return getQWidget();
+ }
+
+ protected void setStyleSheet(String style) {
+ getQMasterWidget().setStyleSheet(style);
+ updateLayout();
+ }
+
+ protected void updateStyleSheet() {
+ if (null != getQMasterWidget().style()) {
+ getQMasterWidget().setStyle(getQMasterWidget().style());
+ updateLayout();
+ }
+ }
+
+ protected void updateLayout() {
+ // nothing by default
+ }
+
+ void _addListener(int eventType, Listener listener) {
+ if (eventTable == null) {
+ eventTable = new EventTable();
+ }
+ if (eventType == SWT.DragDetect && this instanceof CTabFolder) {
+ System.out.println("adding dnd drag listener");
+ }
+ 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 #getListeners(int)
+ * @see #removeListener(int, Listener)
+ * @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);
+ }
+
+ /**
+ * 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
+ *
+ * refactored: was checkBits
+ */
+ 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;
+ }
+
+ /* refactored: was checkOrientation */
+ void checkAndUpdateOrientation(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);
+ }
+ }
+
+ /**
+ * 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 descendants 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() {
+ releaseQWidget();
+ }
+
+ /**
+ * Disposes of the operating system resources associated with the receiver
+ * and all its descendants. After this method has been invoked, the receiver
+ * and all descendants 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 descendants 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);
+ }
+
+ /**
+ * 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) {
+ return fixMnemonic(string, false);
+ }
+
+ char[] fixMnemonic(String string, boolean spaces) {
+ char[] buffer = new char[string.length() + 1];
+ string.getChars(0, string.length(), buffer, 0);
+ int i = 0, j = 0;
+ while (i < buffer.length) {
+ if (buffer[i] == '&') {
+ if (i + 1 < buffer.length && buffer[i + 1] == '&') {
+ if (spaces) {
+ buffer[j] = ' ';
+ }
+ j++;
+ i++;
+ }
+ i++;
+ } else {
+ buffer[j++] = buffer[i++];
+ }
+ }
+ while (j < buffer.length) {
+ buffer[j++] = 0;
+ }
+ return buffer;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Returns an array 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
+ * @return an array of listeners that will be notified when the event occurs
+ *
+ * @exception SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - 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(int, Listener)
+ * @see #removeListener(int, Listener)
+ * @see #notifyListeners
+ *
+ * @since 3.4
+ */
+ public Listener[] getListeners(int eventType) {
+ checkWidget();
+ if (eventTable == null) {
+ return new Listener[0];
+ }
+ return eventTable.getListeners(eventType);
+ }
+
+ 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;
+ }
+
+ /*
+ * 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();
+ }
+
+ GC new_GC(GCData data) {
+ return null;
+ }
+
+ /**
+ * 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 #getListeners(int)
+ * @see #removeListener(int, Listener)
+ */
+ 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);
+ }
+
+ /*
+ * Releases the widget hierarchy 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 #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();
+ releaseQWidget();
+ }
+ }
+ }
+
+ 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 releaseQWidget() {
+ state |= DISPOSED;
+ display = null;
+ qWidget = null;
+ }
+
+ /*
+ * 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;
+ mainData = 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
+ *
+ * @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 #getListeners(int)
+ * @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
+ *
+ * @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
+ *
+ * @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 button, int x, int y) {
+ Event event = new Event();
+ event.button = button;
+ event.x = x;
+ event.y = y;
+ //setInputState(event, SWT.DragDetect);
+ sendEvent(SWT.DragDetect, event);
+ if (isDisposed()) {
+ return false;
+ }
+ return event.doit;
+ }
+
+ void sendEvent(Event event) {
+ event.display = 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);
+ }
+ }
+
+ /**
+ * 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 mainData;
+ }
+
+ /**
+ * 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);
+ }
+
+ Object value = getDataMap().get(key);
+ if (value == null) {
+ if (getQMasterWidget() != null) {
+ value = getQMasterWidget().property(key);
+ }
+ }
+ return value;
+ }
+
+ private Map<String, Object> getDataMap() {
+ if (data == null) {
+ data = new HashMap<String, Object>(4);
+ }
+ return data;
+ }
+
+ /**
+ * 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();
+ this.mainData = 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);
+ }
+ if ("stylesheet".equals(key)) { //$NON-NLS-1$
+ setStyleSheet((String) value);
+ return;
+ }
+
+ if (value == null) {
+ if (getDataMap().containsKey(key)) {
+ getDataMap().remove(key);
+ } else {
+ if (getQMasterWidget() != null) {
+ getQMasterWidget().setProperty(key, null);
+ updateStyleSheet(); // we have to update the style, cause the property can be referenced in the style
+ }
+ }
+ } else {
+ // we store Strings/Booleans adin the Qt Control, everything
+ // else in the local map
+ if (getQMasterWidget() != null && (value instanceof String || value instanceof Boolean)) {
+ getQMasterWidget().setProperty(key, value);
+ updateStyleSheet(); // we have to update the style, cause the property can be referenced in the style
+ } else {
+ getDataMap().put(key, value);
+ }
+ }
+ }
+
+ 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;
+ }
+
+ /**
+ * Returns a string containing a concise, human-readable description of the
+ * receiver.
+ *
+ * @return a string representation of the receiver
+ */
+ @Override
+ public String toString() {
+ return getName() + " {" + getDescription() + "}"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ private String getDescription() {
+ if (isDisposed()) {
+ return "*Disposed*"; //$NON-NLS-1$
+ }
+ if (!isValidThread()) {
+ return "*Wrong Thread*"; //$NON-NLS-1$
+ }
+ return getNameText();
+ }
+
+ /* Qt Events */
+ public boolean qtCloseEvent() {
+ return false;
+ }
+
+ public boolean qtResizeEvent(QObject source, QResizeEvent resizeEvent) {
+ return false;
+ }
+
+ public boolean qtMoveEvent(QObject source, QMoveEvent moveEvent) {
+ return false;
+ }
+
+ public boolean qtPaintEvent(QObject source, QPaintEvent paintEvent) {
+ return false;
+ }
+
+ public boolean qtKeyPressEvent(QObject source, QKeyEvent qEvent) {
+ return false;
+ }
+
+ public boolean qtKeyReleaseEvent(QObject source, QKeyEvent qEvent) {
+ return false;
+ }
+
+ public boolean qtMouseMoveEvent(QObject source, QMouseEvent mouseEvent) {
+ return false;
+ }
+
+ public boolean qtMouseButtonPressEvent(QObject source, QMouseEvent mouseEvent) {
+ return false;
+ }
+
+ public boolean qtMouseButtonReleaseEvent(QObject source, QMouseEvent mouseEvent) {
+ return false;
+ }
+
+ public boolean qtMouseButtonDblClickEvent(QObject source, QMouseEvent mouseEvent) {
+ return false;
+ }
+
+ public boolean qtMouseEnterEvent(Object source) {
+ return false;
+ }
+
+ public boolean qtMouseLeaveEvent(Object source) {
+ return false;
+ }
+
+ public boolean qtContextMenuEvent(Object source, QContextMenuEvent event) {
+ return false;
+ }
+
+ public boolean qtShowEvent(QObject source) {
+ return false;
+ }
+
+ public boolean qtHideEvent(QObject source) {
+ return false;
+ }
+
+ public void qtFocusInEvent(QObject source) {
+ // nothing
+ }
+
+ public void qtFocusOutEvent(QObject source) {
+ // nothing
+ }
+
+ public boolean qtWindowActivateEvent(QObject source) {
+ return false;
+ }
+
+ public boolean qtWindowDeactivateEvent(QObject obj) {
+ return false;
+ }
+
+ public boolean qtWindowStateChangeEvent(QObject obj, QWindowStateChangeEvent event) {
+ return false;
+ }
+
+}