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