146
|
1 /*******************************************************************************
|
92
|
2 * Copyright (c) 2000, 2007 IBM Corporation and others.
|
|
3 * All rights reserved. This program and the accompanying materials
|
|
4 * are made available under the terms of the Eclipse Public License v1.0
|
|
5 * which accompanies this distribution, and is available at
|
|
6 * http://www.eclipse.org/legal/epl-v10.html
|
|
7 *
|
|
8 * Contributors:
|
|
9 * IBM Corporation - initial API and implementation
|
108
|
10 * Port to the D programming language:
|
|
11 * Frank Benoit <benoit@tionex.de>
|
92
|
12 *******************************************************************************/
|
|
13 module dwt.dnd.Clipboard;
|
|
14
|
|
15
|
|
16
|
|
17 import dwt.DWT;
|
|
18 import dwt.DWTError;
|
|
19 import dwt.DWTException;
|
|
20 import dwt.internal.Converter;
|
|
21 import dwt.internal.gtk.OS;
|
|
22 import dwt.widgets.Display;
|
|
23 import dwt.dnd.Transfer;
|
|
24 import dwt.dnd.TransferData;
|
|
25 import dwt.dnd.DND;
|
|
26 import dwt.dnd.ClipboardProxy;
|
|
27
|
|
28 import dwt.dwthelper.utils;
|
|
29
|
|
30 import tango.core.Thread;
|
|
31 static import tango.stdc.stringz;
|
|
32 static import tango.stdc.string;
|
|
33
|
|
34 /**
|
|
35 * The <code>Clipboard</code> provides a mechanism for transferring data from one
|
|
36 * application to another or within an application.
|
|
37 *
|
|
38 * <p>IMPORTANT: This class is <em>not</em> intended to be subclassed.</p>
|
|
39 */
|
|
40 public class Clipboard {
|
|
41
|
|
42 private Display display;
|
|
43
|
146
|
44 private static void* GTKCLIPBOARD;
|
|
45 private static void* GTKPRIMARYCLIPBOARD;
|
92
|
46 private static void* TARGET;
|
146
|
47 private static bool static_this_completed = false;
|
|
48 private static void static_this(){
|
|
49 if( !static_this_completed ){
|
|
50 GTKCLIPBOARD = OS.gtk_clipboard_get( cast(void*)OS.GDK_NONE);
|
|
51 auto primary = OS.gdk_atom_intern("PRIMARY".ptr, false);
|
|
52 GTKPRIMARYCLIPBOARD = OS.gtk_clipboard_get(primary);
|
|
53 TARGET = OS.gdk_atom_intern("TARGETS".ptr, false);
|
|
54 static_this_completed = true;
|
|
55 }
|
92
|
56 }
|
|
57
|
|
58 /**
|
|
59 * Constructs a new instance of this class. Creating an instance of a Clipboard
|
|
60 * may cause system resources to be allocated depending on the platform. It is therefore
|
|
61 * mandatory that the Clipboard instance be disposed when no longer required.
|
|
62 *
|
|
63 * @param display the display on which to allocate the clipboard
|
|
64 *
|
|
65 * @exception DWTException <ul>
|
|
66 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
|
|
67 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
|
|
68 * </ul>
|
|
69 *
|
|
70 * @see Clipboard#dispose
|
|
71 * @see Clipboard#checkSubclass
|
|
72 */
|
|
73 public this(Display display) {
|
|
74 checkSubclass ();
|
146
|
75 static_this();
|
92
|
76 if (display is null) {
|
|
77 display = Display.getCurrent();
|
|
78 if (display is null) {
|
|
79 display = Display.getDefault();
|
|
80 }
|
|
81 }
|
|
82 if (display.getThread() !is Thread.getThis()) {
|
|
83 DND.error(DWT.ERROR_THREAD_INVALID_ACCESS);
|
|
84 }
|
|
85 this.display = display;
|
|
86 }
|
|
87
|
|
88 /**
|
|
89 * Checks that this class can be subclassed.
|
|
90 * <p>
|
|
91 * The DWT class library is intended to be subclassed
|
|
92 * only at specific, controlled points. This method enforces this
|
|
93 * rule unless it is overridden.
|
|
94 * </p><p>
|
|
95 * <em>IMPORTANT:</em> By providing an implementation of this
|
|
96 * method that allows a subclass of a class which does not
|
|
97 * normally allow subclassing to be created, the implementer
|
|
98 * agrees to be fully responsible for the fact that any such
|
|
99 * subclass will likely fail between DWT releases and will be
|
|
100 * strongly platform specific. No support is provided for
|
|
101 * user-written classes which are implemented in this fashion.
|
|
102 * </p><p>
|
|
103 * The ability to subclass outside of the allowed DWT classes
|
|
104 * is intended purely to enable those not on the DWT development
|
|
105 * team to implement patches in order to get around specific
|
|
106 * limitations in advance of when those limitations can be
|
|
107 * addressed by the team. Subclassing should not be attempted
|
|
108 * without an intimate and detailed understanding of the hierarchy.
|
|
109 * </p>
|
|
110 *
|
|
111 * @exception DWTException <ul>
|
|
112 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
|
|
113 * </ul>
|
|
114 */
|
|
115 protected void checkSubclass () {
|
238
|
116 String name = this.classinfo.name;
|
|
117 String validName = Clipboard.classinfo.name;
|
92
|
118 if ( validName !=/*eq*/ name ) {
|
|
119 DND.error (DWT.ERROR_INVALID_SUBCLASS);
|
|
120 }
|
|
121 }
|
|
122 /**
|
|
123 * Throws an <code>DWTException</code> if the receiver can not
|
|
124 * be accessed by the caller. This may include both checks on
|
|
125 * the state of the receiver and more generally on the entire
|
|
126 * execution context. This method <em>should</em> be called by
|
|
127 * widget implementors to enforce the standard DWT invariants.
|
|
128 * <p>
|
|
129 * Currently, it is an error to invoke any method (other than
|
|
130 * <code>isDisposed()</code>) on a widget that has had its
|
|
131 * <code>dispose()</code> method called. It is also an error
|
|
132 * to call widget methods from any thread that is different
|
|
133 * from the thread that created the widget.
|
|
134 * </p><p>
|
|
135 * In future releases of DWT, there may be more or fewer error
|
|
136 * checks and exceptions may be thrown for different reasons.
|
|
137 * </p>
|
|
138 *
|
|
139 * @exception DWTException <ul>
|
|
140 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
|
141 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
|
142 * </ul>
|
|
143 */
|
|
144 protected void checkWidget () {
|
|
145 Display display = this.display;
|
|
146 if (display is null) DND.error (DWT.ERROR_WIDGET_DISPOSED);
|
|
147 if (display.getThread() !is Thread.getThis ()) DND.error (DWT.ERROR_THREAD_INVALID_ACCESS);
|
|
148 if (display.isDisposed()) DND.error(DWT.ERROR_WIDGET_DISPOSED);
|
|
149 }
|
|
150
|
|
151 /**
|
|
152 * If this clipboard is currently the owner of the data on the system clipboard,
|
|
153 * clear the contents. If this clipboard is not the owner, then nothing is done.
|
|
154 * Note that there are clipboard assistant applications that take ownership of
|
|
155 * data or make copies of data when it is placed on the clipboard. In these
|
|
156 * cases, it may not be possible to clear the clipboard.
|
|
157 *
|
|
158 * @exception DWTException <ul>
|
|
159 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
|
160 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
|
161 * </ul>
|
|
162 *
|
|
163 * @since 3.1
|
|
164 */
|
|
165 public void clearContents() {
|
|
166 clearContents(DND.CLIPBOARD);
|
|
167 }
|
|
168
|
|
169 /**
|
|
170 * If this clipboard is currently the owner of the data on the specified
|
|
171 * clipboard, clear the contents. If this clipboard is not the owner, then
|
|
172 * nothing is done.
|
|
173 *
|
|
174 * <p>Note that there are clipboard assistant applications that take ownership
|
|
175 * of data or make copies of data when it is placed on the clipboard. In these
|
|
176 * cases, it may not be possible to clear the clipboard.</p>
|
|
177 *
|
|
178 * <p>The clipboards value is either one of the clipboard constants defined in
|
|
179 * class <code>DND</code>, or must be built by <em>bitwise OR</em>'ing together
|
|
180 * (that is, using the <code>int</code> "|" operator) two or more
|
|
181 * of those <code>DND</code> clipboard constants.</p>
|
|
182 *
|
|
183 * @param clipboards to be cleared
|
|
184 *
|
|
185 * @exception DWTException <ul>
|
|
186 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
|
187 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
|
188 * </ul>
|
|
189 *
|
|
190 * @see DND#CLIPBOARD
|
|
191 * @see DND#SELECTION_CLIPBOARD
|
|
192 *
|
|
193 * @since 3.1
|
|
194 */
|
|
195 public void clearContents(int clipboards) {
|
|
196 checkWidget();
|
|
197 ClipboardProxy proxy = ClipboardProxy._getInstance(display);
|
|
198 proxy.clear(this, clipboards);
|
|
199 }
|
|
200
|
|
201 /**
|
|
202 * Disposes of the operating system resources associated with the clipboard.
|
|
203 * The data will still be available on the system clipboard after the dispose
|
|
204 * method is called.
|
|
205 *
|
|
206 * <p>NOTE: On some platforms the data will not be available once the application
|
|
207 * has exited or the display has been disposed.</p>
|
|
208 *
|
|
209 * @exception DWTException <ul>
|
|
210 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
|
|
211 * </ul>
|
|
212 */
|
|
213 public void dispose () {
|
|
214 if (isDisposed()) return;
|
|
215 if (display.getThread() !is Thread.getThis()) DND.error(DWT.ERROR_THREAD_INVALID_ACCESS);
|
|
216 display = null;
|
|
217 }
|
|
218
|
|
219 /**
|
|
220 * Retrieve the data of the specified type currently available on the system
|
|
221 * clipboard. Refer to the specific subclass of <code>Transfer</code> to
|
|
222 * determine the type of object returned.
|
|
223 *
|
|
224 * <p>The following snippet shows text and RTF text being retrieved from the
|
|
225 * clipboard:</p>
|
|
226 *
|
|
227 * <code><pre>
|
|
228 * Clipboard clipboard = new Clipboard(display);
|
|
229 * TextTransfer textTransfer = TextTransfer.getInstance();
|
|
230 * String textData = (String)clipboard.getContents(textTransfer);
|
|
231 * if (textData !is null) System.out.println("Text is "+textData);
|
|
232 * RTFTransfer rtfTransfer = RTFTransfer.getInstance();
|
|
233 * String rtfData = (String)clipboard.getContents(rtfTransfer);
|
|
234 * if (rtfData !is null) System.out.println("RTF Text is "+rtfData);
|
|
235 * clipboard.dispose();
|
|
236 * </code></pre>
|
|
237 *
|
|
238 * @param transfer the transfer agent for the type of data being requested
|
|
239 * @return the data obtained from the clipboard or null if no data of this type is available
|
|
240 *
|
|
241 * @exception DWTException <ul>
|
|
242 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
|
243 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
|
244 * </ul>
|
|
245 * @exception IllegalArgumentException <ul>
|
|
246 * <li>ERROR_NULL_ARGUMENT - if transfer is null</li>
|
|
247 * </ul>
|
|
248 *
|
|
249 * @see Transfer
|
|
250 */
|
|
251 public Object getContents(Transfer transfer) {
|
|
252 return getContents(transfer, DND.CLIPBOARD);
|
|
253 }
|
|
254
|
|
255 /**
|
|
256 * Retrieve the data of the specified type currently available on the specified
|
|
257 * clipboard. Refer to the specific subclass of <code>Transfer</code> to
|
|
258 * determine the type of object returned.
|
|
259 *
|
|
260 * <p>The following snippet shows text and RTF text being retrieved from the
|
|
261 * clipboard:</p>
|
|
262 *
|
|
263 * <code><pre>
|
|
264 * Clipboard clipboard = new Clipboard(display);
|
|
265 * TextTransfer textTransfer = TextTransfer.getInstance();
|
|
266 * String textData = (String)clipboard.getContents(textTransfer);
|
|
267 * if (textData !is null) System.out.println("Text is "+textData);
|
|
268 * RTFTransfer rtfTransfer = RTFTransfer.getInstance();
|
|
269 * String rtfData = (String)clipboard.getContents(rtfTransfer, DND.CLIPBOARD);
|
|
270 * if (rtfData !is null) System.out.println("RTF Text is "+rtfData);
|
|
271 * clipboard.dispose();
|
|
272 * </code></pre>
|
|
273 *
|
|
274 * <p>The clipboards value is either one of the clipboard constants defined in
|
|
275 * class <code>DND</code>, or must be built by <em>bitwise OR</em>'ing together
|
|
276 * (that is, using the <code>int</code> "|" operator) two or more
|
|
277 * of those <code>DND</code> clipboard constants.</p>
|
|
278 *
|
|
279 * @param transfer the transfer agent for the type of data being requested
|
|
280 * @param clipboards on which to look for data
|
|
281 *
|
|
282 * @return the data obtained from the clipboard or null if no data of this type is available
|
|
283 *
|
|
284 * @exception DWTException <ul>
|
|
285 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
|
286 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
|
287 * </ul>
|
|
288 * @exception IllegalArgumentException <ul>
|
|
289 * <li>ERROR_NULL_ARGUMENT - if transfer is null</li>
|
|
290 * </ul>
|
|
291 *
|
|
292 * @see Transfer
|
|
293 * @see DND#CLIPBOARD
|
|
294 * @see DND#SELECTION_CLIPBOARD
|
|
295 *
|
|
296 * @since 3.1
|
|
297 */
|
|
298 public Object getContents(Transfer transfer, int clipboards) {
|
|
299 checkWidget();
|
|
300 if (transfer is null) DND.error(DWT.ERROR_NULL_ARGUMENT);
|
|
301 GtkSelectionData* selection_data;
|
|
302 auto typeIds = transfer.getTypeIds();
|
|
303 for (int i = 0; i < typeIds.length; i++) {
|
|
304 if ((clipboards & DND.CLIPBOARD) !is 0) {
|
|
305 selection_data = gtk_clipboard_wait_for_contents(GTKCLIPBOARD, cast(void*)typeIds[i]);
|
|
306 }
|
|
307 if (selection_data !is null) break;
|
|
308 if ((clipboards & DND.SELECTION_CLIPBOARD) !is 0) {
|
|
309 selection_data = gtk_clipboard_wait_for_contents(GTKPRIMARYCLIPBOARD, cast(void*)typeIds[i]);
|
|
310 }
|
|
311 }
|
|
312 if (selection_data is null) return null;
|
|
313 GtkSelectionData* gtkSelectionData = selection_data;
|
|
314 TransferData tdata = new TransferData();
|
|
315 tdata.type = gtkSelectionData.type;
|
|
316 tdata.pValue = gtkSelectionData.data;
|
|
317 tdata.length = gtkSelectionData.length;
|
|
318 tdata.format = gtkSelectionData.format;
|
|
319 Object result = transfer.nativeToJava(tdata);
|
|
320 OS.gtk_selection_data_free(selection_data);
|
|
321 return result;
|
|
322 }
|
|
323
|
|
324 /**
|
|
325 * Returns <code>true</code> if the clipboard has been disposed,
|
|
326 * and <code>false</code> otherwise.
|
|
327 * <p>
|
|
328 * This method gets the dispose state for the clipboard.
|
|
329 * When a clipboard has been disposed, it is an error to
|
|
330 * invoke any other method using the clipboard.
|
|
331 * </p>
|
|
332 *
|
|
333 * @return <code>true</code> when the widget is disposed and <code>false</code> otherwise
|
|
334 *
|
|
335 * @since 3.0
|
|
336 */
|
|
337 public bool isDisposed () {
|
|
338 return (display is null);
|
|
339 }
|
|
340
|
|
341 /**
|
|
342 * Place data of the specified type on the system clipboard. More than one type
|
|
343 * of data can be placed on the system clipboard at the same time. Setting the
|
|
344 * data clears any previous data from the system clipboard, regardless of type.
|
|
345 *
|
|
346 * <p>NOTE: On some platforms, the data is immediately copied to the system
|
|
347 * clipboard but on other platforms it is provided upon request. As a result,
|
|
348 * if the application modifies the data object it has set on the clipboard, that
|
|
349 * modification may or may not be available when the data is subsequently
|
|
350 * requested.</p>
|
|
351 *
|
|
352 * <p>The following snippet shows text and RTF text being set on the copy/paste
|
|
353 * clipboard:
|
|
354 * </p>
|
|
355 *
|
|
356 * <code><pre>
|
|
357 * Clipboard clipboard = new Clipboard(display);
|
|
358 * String textData = "Hello World";
|
|
359 * String rtfData = "{\\rtf1\\b\\i Hello World}";
|
|
360 * TextTransfer textTransfer = TextTransfer.getInstance();
|
|
361 * RTFTransfer rtfTransfer = RTFTransfer.getInstance();
|
|
362 * Transfer[] transfers = new Transfer[]{textTransfer, rtfTransfer};
|
|
363 * Object[] data = new Object[]{textData, rtfData};
|
|
364 * clipboard.setContents(data, transfers);
|
|
365 * clipboard.dispose();
|
|
366 * </code></pre>
|
|
367 *
|
|
368 * @param data the data to be set in the clipboard
|
|
369 * @param dataTypes the transfer agents that will convert the data to its
|
|
370 * platform specific format; each entry in the data array must have a
|
|
371 * corresponding dataType
|
|
372 *
|
|
373 * @exception IllegalArgumentException <ul>
|
|
374 * <li>ERROR_INVALID_ARGUMENT - if data is null or datatypes is null
|
|
375 * or the length of data is not the same as the length of dataTypes</li>
|
|
376 * </ul>
|
|
377 * @exception DWTException <ul>
|
|
378 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
|
379 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
|
380 * </ul>
|
|
381 * @exception DWTError <ul>
|
|
382 * <li>ERROR_CANNOT_SET_CLIPBOARD - if the clipboard is locked or otherwise unavailable</li>
|
|
383 * </ul>
|
|
384 *
|
|
385 * <p>NOTE: ERROR_CANNOT_SET_CLIPBOARD should be an DWTException, since it is a
|
|
386 * recoverable error, but can not be changed due to backward compatibility.</p>
|
|
387 */
|
|
388 public void setContents(Object[] data, Transfer[] dataTypes) {
|
|
389 setContents(data, dataTypes, DND.CLIPBOARD);
|
|
390 }
|
|
391
|
|
392 /**
|
|
393 * Place data of the specified type on the specified clipboard. More than one
|
|
394 * type of data can be placed on the specified clipboard at the same time.
|
|
395 * Setting the data clears any previous data from the specified
|
|
396 * clipboard, regardless of type.
|
|
397 *
|
|
398 * <p>NOTE: On some platforms, the data is immediately copied to the specified
|
|
399 * clipboard but on other platforms it is provided upon request. As a result,
|
|
400 * if the application modifies the data object it has set on the clipboard, that
|
|
401 * modification may or may not be available when the data is subsequently
|
|
402 * requested.</p>
|
|
403 *
|
|
404 * <p>The clipboards value is either one of the clipboard constants defined in
|
|
405 * class <code>DND</code>, or must be built by <em>bitwise OR</em>'ing together
|
|
406 * (that is, using the <code>int</code> "|" operator) two or more
|
|
407 * of those <code>DND</code> clipboard constants.</p>
|
|
408 *
|
|
409 * <p>The following snippet shows text and RTF text being set on the copy/paste
|
|
410 * clipboard:
|
|
411 * </p>
|
|
412 *
|
|
413 * <code><pre>
|
|
414 * Clipboard clipboard = new Clipboard(display);
|
|
415 * String textData = "Hello World";
|
|
416 * String rtfData = "{\\rtf1\\b\\i Hello World}";
|
|
417 * TextTransfer textTransfer = TextTransfer.getInstance();
|
|
418 * RTFTransfer rtfTransfer = RTFTransfer.getInstance();
|
|
419 * Transfer[] transfers = new Transfer[]{textTransfer, rtfTransfer};
|
|
420 * Object[] data = new Object[]{textData, rtfData};
|
|
421 * clipboard.setContents(data, transfers, DND.CLIPBOARD);
|
|
422 * clipboard.dispose();
|
|
423 * </code></pre>
|
|
424 *
|
|
425 * @param data the data to be set in the clipboard
|
|
426 * @param dataTypes the transfer agents that will convert the data to its
|
|
427 * platform specific format; each entry in the data array must have a
|
|
428 * corresponding dataType
|
|
429 * @param clipboards on which to set the data
|
|
430 *
|
|
431 * @exception IllegalArgumentException <ul>
|
|
432 * <li>ERROR_INVALID_ARGUMENT - if data is null or datatypes is null
|
|
433 * or the length of data is not the same as the length of dataTypes</li>
|
|
434 * </ul>
|
|
435 * @exception DWTException <ul>
|
|
436 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
|
437 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
|
438 * </ul>
|
|
439 * @exception DWTError <ul>
|
|
440 * <li>ERROR_CANNOT_SET_CLIPBOARD - if the clipboard is locked or otherwise unavailable</li>
|
|
441 * </ul>
|
|
442 *
|
|
443 * <p>NOTE: ERROR_CANNOT_SET_CLIPBOARD should be an DWTException, since it is a
|
|
444 * recoverable error, but can not be changed due to backward compatibility.</p>
|
|
445 *
|
|
446 * @see DND#CLIPBOARD
|
|
447 * @see DND#SELECTION_CLIPBOARD
|
|
448 *
|
|
449 * @since 3.1
|
|
450 */
|
|
451 public void setContents(Object[] data, Transfer[] dataTypes, int clipboards) {
|
|
452 checkWidget();
|
|
453 if (data is null || dataTypes is null || data.length !is dataTypes.length || data.length is 0) {
|
|
454 DND.error(DWT.ERROR_INVALID_ARGUMENT);
|
|
455 }
|
|
456 for (int i = 0; i < data.length; i++) {
|
|
457 if (data[i] is null || dataTypes[i] is null || !dataTypes[i].validate(data[i])) {
|
|
458 DND.error(DWT.ERROR_INVALID_ARGUMENT);
|
|
459 }
|
|
460 }
|
|
461 ClipboardProxy proxy = ClipboardProxy._getInstance(display);
|
|
462 if (!proxy.setData(this, data, dataTypes, clipboards)) {
|
|
463 DND.error(DND.ERROR_CANNOT_SET_CLIPBOARD);
|
|
464 }
|
|
465 }
|
|
466
|
|
467 /**
|
|
468 * Returns an array of the data types currently available on the system
|
|
469 * clipboard. Use with Transfer.isSupportedType.
|
|
470 *
|
|
471 * @return array of data types currently available on the system clipboard
|
|
472 *
|
|
473 * @exception DWTException <ul>
|
|
474 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
|
475 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
|
476 * </ul>
|
|
477 *
|
|
478 * @see Transfer#isSupportedType
|
|
479 *
|
|
480 * @since 3.0
|
|
481 */
|
|
482 public TransferData[] getAvailableTypes() {
|
|
483 return getAvailableTypes(DND.CLIPBOARD);
|
|
484 }
|
|
485
|
|
486 /**
|
|
487 * Returns an array of the data types currently available on the specified
|
|
488 * clipboard. Use with Transfer.isSupportedType.
|
|
489 *
|
|
490 * <p>The clipboards value is either one of the clipboard constants defined in
|
|
491 * class <code>DND</code>, or must be built by <em>bitwise OR</em>'ing together
|
|
492 * (that is, using the <code>int</code> "|" operator) two or more
|
|
493 * of those <code>DND</code> clipboard constants.</p>
|
|
494 *
|
|
495 * @param clipboards from which to get the data types
|
|
496 * @return array of data types currently available on the specified clipboard
|
|
497 *
|
|
498 * @exception DWTException <ul>
|
|
499 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
|
500 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
|
501 * </ul>
|
|
502 *
|
|
503 * @see Transfer#isSupportedType
|
|
504 * @see DND#CLIPBOARD
|
|
505 * @see DND#SELECTION_CLIPBOARD
|
|
506 *
|
|
507 * @since 3.1
|
|
508 */
|
|
509 public TransferData[] getAvailableTypes(int clipboards) {
|
|
510 checkWidget();
|
|
511 TransferData[] result = null;
|
|
512 if ((clipboards & DND.CLIPBOARD) !is 0) {
|
|
513 auto types = getAvailableClipboardTypes();
|
|
514 result = new TransferData[types.length];
|
|
515 for (int i = 0; i < types.length; i++) {
|
|
516 result[i] = new TransferData();
|
|
517 result[i].type = types[i];
|
|
518 }
|
|
519 }
|
|
520 if ((clipboards & DND.SELECTION_CLIPBOARD) !is 0) {
|
|
521 auto types = getAvailablePrimaryTypes();
|
|
522 int offset = 0;
|
|
523 if (result !is null) {
|
|
524 TransferData[] newResult = new TransferData[result.length + types.length];
|
|
525 System.arraycopy(result,0, newResult, 0, result.length);
|
|
526 offset = result.length;
|
|
527 result = newResult;
|
|
528 } else {
|
|
529 result = new TransferData[types.length];
|
|
530 }
|
|
531 for (int i = 0; i < types.length; i++) {
|
|
532 result[offset+i] = new TransferData();
|
|
533 result[offset+i].type = types[i];
|
|
534 }
|
|
535 }
|
|
536 return result is null ? new TransferData[0] : result;
|
|
537 }
|
|
538
|
|
539 /**
|
|
540 * Returns a platform specific list of the data types currently available on the
|
|
541 * system clipboard.
|
|
542 *
|
|
543 * <p>Note: <code>getAvailableTypeNames</code> is a utility for writing a Transfer
|
|
544 * sub-class. It should NOT be used within an application because it provides
|
|
545 * platform specific information.</p>
|
|
546 *
|
|
547 * @return a platform specific list of the data types currently available on the
|
|
548 * system clipboard
|
|
549 *
|
|
550 * @exception DWTException <ul>
|
|
551 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
|
552 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
|
553 * </ul>
|
|
554 */
|
238
|
555 public String[] getAvailableTypeNames() {
|
92
|
556 checkWidget();
|
|
557 auto types1 = getAvailableClipboardTypes();
|
|
558 auto types2 = getAvailablePrimaryTypes();
|
238
|
559 String[] result = new String[types1.length + types2.length];
|
92
|
560 int count = 0;
|
|
561 for (int i = 0; i < types1.length; i++) {
|
|
562 auto pName = OS.gdk_atom_name(types1[i]);
|
|
563 if (pName is null) {
|
|
564 continue;
|
|
565 }
|
238
|
566 String buffer = tango.stdc.stringz.fromStringz( pName ).dup;
|
92
|
567 OS.g_free (pName);
|
|
568 result[count++] = "GTKCLIPBOARD "~buffer;
|
|
569 }
|
|
570 for (int i = 0; i < types2.length; i++) {
|
|
571 auto pName = OS.gdk_atom_name(types2[i]);
|
|
572 if (pName is null) {
|
|
573 continue;
|
|
574 }
|
238
|
575 String buffer = tango.stdc.stringz.fromStringz( pName ).dup;
|
92
|
576 OS.g_free (pName);
|
|
577 result[count++] = "GTKPRIMARYCLIPBOARD "~buffer;
|
|
578 }
|
|
579 if (count < result.length){
|
238
|
580 String[] temp = new String[count];
|
92
|
581 System.arraycopy(result, 0, temp, 0, count);
|
|
582 result = temp;
|
|
583 }
|
|
584 return result;
|
|
585 }
|
|
586
|
|
587 private void*[] getAvailablePrimaryTypes() {
|
|
588 void*[] types;
|
|
589 auto selection_data = gtk_clipboard_wait_for_contents(GTKPRIMARYCLIPBOARD, TARGET);
|
|
590 if (selection_data !is null) {
|
|
591 try {
|
|
592 GtkSelectionData* gtkSelectionData = selection_data;
|
|
593 if (gtkSelectionData.length !is 0) {
|
|
594 types = cast(void*[])new int[gtkSelectionData.length * 8 / gtkSelectionData.format];
|
|
595 tango.stdc.string.memmove( cast(void*)types.ptr, gtkSelectionData.data, gtkSelectionData.length );
|
|
596 }
|
|
597 } finally {
|
|
598 OS.gtk_selection_data_free(selection_data);
|
|
599 }
|
|
600 }
|
|
601 return types;
|
|
602 }
|
|
603 private void*[] getAvailableClipboardTypes () {
|
|
604 void*[] types;
|
|
605 auto selection_data = gtk_clipboard_wait_for_contents(GTKCLIPBOARD, TARGET);
|
|
606 if (selection_data !is null) {
|
|
607 try {
|
|
608 GtkSelectionData* gtkSelectionData = selection_data;
|
|
609 if (gtkSelectionData.length !is 0) {
|
|
610 types = cast(void*[])new int[gtkSelectionData.length * 8 / gtkSelectionData.format];
|
|
611 tango.stdc.string.memmove( cast(void*)types, gtkSelectionData.data, gtkSelectionData.length);
|
|
612 }
|
|
613 } finally {
|
|
614 OS.gtk_selection_data_free(selection_data);
|
|
615 }
|
|
616 }
|
|
617 return types;
|
|
618 }
|
|
619
|
|
620 GtkSelectionData* gtk_clipboard_wait_for_contents(void* clipboard, void* target) {
|
238
|
621 String key = "org.eclipse.swt.internal.gtk.dispatchEvent";
|
92
|
622 Display display = this.display;
|
|
623 ArrayWrapperInt arr = new ArrayWrapperInt( [ OS.GDK_PROPERTY_NOTIFY, OS.GDK_SELECTION_CLEAR, OS.GDK_SELECTION_REQUEST, OS.GDK_SELECTION_NOTIFY ] );
|
|
624 display.setData(key, arr );
|
|
625 GtkSelectionData* selection_data = OS.gtk_clipboard_wait_for_contents(clipboard, target);
|
|
626 display.setData(key, null);
|
|
627 return selection_data;
|
|
628 }
|
|
629 }
|