comparison dwt/dnd/Clipboard.d @ 45:d8635bb48c7c

Merge with SWT 3.5
author Jacob Carlborg <doob@me.com>
date Mon, 01 Dec 2008 17:07:00 +0100
parents e831403a80a9
children a7e41c09df9e
comparison
equal deleted inserted replaced
44:ca5e494f2bbf 45:d8635bb48c7c
1 /******************************************************************************* 1 /*******************************************************************************
2 * Copyright (c) 2000, 2007 IBM Corporation and others. 2 * Copyright (c) 2000, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials 3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0 4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at 5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html 6 * http://www.eclipse.org/legal/epl-v10.html
7 * 7 *
8 * Contributors: 8 * Contributors:
9 * IBM Corporation - initial API and implementation 9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/ 10 *******************************************************************************/
11 module dwt.dnd; 11 module dwt.dnd.Clipboard;
12 12
13 13 import dwt.dwthelper.utils;
14 import dwt.*; 14
15 import dwt.widgets.*; 15
16 import dwt.DWT;
17 import dwt.DWTError;
18 import dwt.DWTException;
19 import dwt.internal.cocoa.NSArray;
20 import dwt.internal.cocoa.NSData;
21 import dwt.internal.cocoa.NSMutableArray;
22 import dwt.internal.cocoa.NSObject;
23 import dwt.internal.cocoa.NSPasteboard;
24 import dwt.internal.cocoa.NSString;
25 import dwt.internal.cocoa.NSURL;
16 import dwt.internal.cocoa.OS; 26 import dwt.internal.cocoa.OS;
27 import dwt.widgets.Display;
17 28
18 /** 29 /**
19 * The <code>Clipboard</code> provides a mechanism for transferring data from one 30 * The <code>Clipboard</code> provides a mechanism for transferring data from one
20 * application to another or within an application. 31 * application to another or within an application.
21 * 32 *
22 * <p>IMPORTANT: This class is <em>not</em> intended to be subclassed.</p> 33 * <p>IMPORTANT: This class is <em>not</em> intended to be subclassed.</p>
34 *
35 * @see <a href="http://www.eclipse.org/swt/snippets/#clipboard">Clipboard snippets</a>
36 * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Example: ClipboardExample</a>
37 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
23 */ 38 */
24 public class Clipboard { 39 public class Clipboard {
25 40
26 Display display; 41 Display display;
27 int scrap = 0;
28 42
29 /** 43 /**
30 * Constructs a new instance of this class. Creating an instance of a Clipboard 44 * Constructs a new instance of this class. Creating an instance of a Clipboard
31 * may cause system resources to be allocated depending on the platform. It is therefore 45 * may cause system resources to be allocated depending on the platform. It is therefore
32 * mandatory that the Clipboard instance be disposed when no longer required. 46 * mandatory that the Clipboard instance be disposed when no longer required.
39 * </ul> 53 * </ul>
40 * 54 *
41 * @see Clipboard#dispose 55 * @see Clipboard#dispose
42 * @see Clipboard#checkSubclass 56 * @see Clipboard#checkSubclass
43 */ 57 */
44 public this(Display display) { 58 public Clipboard(Display display) {
45 checkSubclass (); 59 checkSubclass ();
46 if (display is null) { 60 if (display is null) {
47 display = Display.getCurrent(); 61 display = Display.getCurrent();
48 if (display is null) { 62 if (display is null) {
49 display = Display.getDefault(); 63 display = Display.getDefault();
83 * </ul> 97 * </ul>
84 */ 98 */
85 protected void checkSubclass () { 99 protected void checkSubclass () {
86 String name = getClass().getName (); 100 String name = getClass().getName ();
87 String validName = Clipboard.class.getName(); 101 String validName = Clipboard.class.getName();
88 if (!validName.opEquals(name)) { 102 if (!validName.equals(name)) {
89 DND.error (DWT.ERROR_INVALID_SUBCLASS); 103 DND.error (DWT.ERROR_INVALID_SUBCLASS);
90 } 104 }
91 } 105 }
92 /** 106 /**
93 * Throws an <code>DWTException</code> if the receiver can not 107 * Throws an <code>DWTException</code> if the receiver can not
162 * 176 *
163 * @since 3.1 177 * @since 3.1
164 */ 178 */
165 public void clearContents(int clipboards) { 179 public void clearContents(int clipboards) {
166 checkWidget(); 180 checkWidget();
167 if ((clipboards & DND.CLIPBOARD) is 0 || scrap is 0) return; 181 if ((clipboards & DND.CLIPBOARD) is 0) return;
168 int oldScrap = scrap; 182 NSPasteboard pasteboard = NSPasteboard.generalPasteboard();
169 scrap = 0; 183 pasteboard.declareTypes(NSMutableArray.arrayWithCapacity(0), null);
170 int[] currentScrap = new int[1];
171 if (OS.GetCurrentScrap(currentScrap) !is OS.noErr) return;
172 if (currentScrap[0] is oldScrap) {
173 OS.ClearCurrentScrap();
174 }
175 } 184 }
176 185
177 /** 186 /**
178 * Disposes of the operating system resources associated with the clipboard. 187 * Disposes of the operating system resources associated with the clipboard.
179 * The data will still be available on the system clipboard after the dispose 188 * The data will still be available on the system clipboard after the dispose
201 * clipboard:</p> 210 * clipboard:</p>
202 * 211 *
203 * <code><pre> 212 * <code><pre>
204 * Clipboard clipboard = new Clipboard(display); 213 * Clipboard clipboard = new Clipboard(display);
205 * TextTransfer textTransfer = TextTransfer.getInstance(); 214 * TextTransfer textTransfer = TextTransfer.getInstance();
206 * String textData = cast(String)clipboard.getContents(textTransfer); 215 * String textData = (String)clipboard.getContents(textTransfer);
207 * if (textData !is null) System.out.println("Text is "+textData); 216 * if (textData !is null) System.out.println("Text is "+textData);
208 * RTFTransfer rtfTransfer = RTFTransfer.getInstance(); 217 * RTFTransfer rtfTransfer = RTFTransfer.getInstance();
209 * String rtfData = cast(String)clipboard.getContents(rtfTransfer); 218 * String rtfData = (String)clipboard.getContents(rtfTransfer);
210 * if (rtfData !is null) System.out.println("RTF Text is "+rtfData); 219 * if (rtfData !is null) System.out.println("RTF Text is "+rtfData);
211 * clipboard.dispose(); 220 * clipboard.dispose();
212 * </code></pre> 221 * </code></pre>
213 * 222 *
214 * @param transfer the transfer agent for the type of data being requested 223 * @param transfer the transfer agent for the type of data being requested
237 * clipboard:</p> 246 * clipboard:</p>
238 * 247 *
239 * <code><pre> 248 * <code><pre>
240 * Clipboard clipboard = new Clipboard(display); 249 * Clipboard clipboard = new Clipboard(display);
241 * TextTransfer textTransfer = TextTransfer.getInstance(); 250 * TextTransfer textTransfer = TextTransfer.getInstance();
242 * String textData = cast(String)clipboard.getContents(textTransfer); 251 * String textData = (String)clipboard.getContents(textTransfer);
243 * if (textData !is null) System.out.println("Text is "+textData); 252 * if (textData !is null) System.out.println("Text is "+textData);
244 * RTFTransfer rtfTransfer = RTFTransfer.getInstance(); 253 * RTFTransfer rtfTransfer = RTFTransfer.getInstance();
245 * String rtfData = cast(String)clipboard.getContents(rtfTransfer, DND.CLIPBOARD); 254 * String rtfData = (String)clipboard.getContents(rtfTransfer, DND.CLIPBOARD);
246 * if (rtfData !is null) System.out.println("RTF Text is "+rtfData); 255 * if (rtfData !is null) System.out.println("RTF Text is "+rtfData);
247 * clipboard.dispose(); 256 * clipboard.dispose();
248 * </code></pre> 257 * </code></pre>
249 * 258 *
250 * <p>The clipboards value is either one of the clipboard constants defined in 259 * <p>The clipboards value is either one of the clipboard constants defined in
273 */ 282 */
274 public Object getContents(Transfer transfer, int clipboards) { 283 public Object getContents(Transfer transfer, int clipboards) {
275 checkWidget(); 284 checkWidget();
276 if (transfer is null) DND.error(DWT.ERROR_NULL_ARGUMENT); 285 if (transfer is null) DND.error(DWT.ERROR_NULL_ARGUMENT);
277 if ((clipboards & DND.CLIPBOARD) is 0) return null; 286 if ((clipboards & DND.CLIPBOARD) is 0) return null;
278 int[] scrap = new int[1]; 287 NSPasteboard pasteboard = NSPasteboard.generalPasteboard();
279 if (OS.GetCurrentScrap(scrap) !is OS.noErr) return null; 288 String[] typeNames = transfer.getTypeNames();
280 int[] typeIds = transfer.getTypeIds(); 289 NSMutableArray types = NSMutableArray.arrayWithCapacity(typeNames.length);
281 int[] size = new int[1]; 290 for (int i = 0; i < typeNames.length; i++) {
282 // get data from system clipboard 291 types.addObject(NSString.stringWith(typeNames[i]));
283 for (int i=0; i<typeIds.length; i++) { 292 }
284 int type = typeIds[i]; 293 NSString type = pasteboard.availableTypeFromArray(types);
285 size[0] = 0; 294 if (type !is null) {
286 if (OS.GetScrapFlavorSize(scrap[0], type, size) is OS.noErr && size[0] > 0) { 295 TransferData tdata = new TransferData();
287 byte[] buffer = new byte[size[0]]; 296 tdata.type = Transfer.registerType(type.getString());
288 if (OS.GetScrapFlavorData(scrap[0], type, size, buffer) is OS.noErr) { 297 if (type.isEqual(OS.NSStringPboardType) ||
289 TransferData tdata = new TransferData(); 298 type.isEqual(OS.NSRTFPboardType) ||
290 tdata.type = type; 299 type.isEqual(OS.NSHTMLPboardType)) {
291 tdata.data = new byte[1][]; 300 tdata.data = pasteboard.stringForType(type);
292 tdata.data[0] = buffer; 301 } else if (type.isEqual(OS.NSFilenamesPboardType)) {
293 return transfer.nativeToJava(tdata); 302 tdata.data = new NSArray(pasteboard.propertyListForType(type).id);
294 } 303 } else if (type.isEqual(OS.NSURLPboardType)) {
304 tdata.data = NSURL.URLFromPasteboard(pasteboard);
305 } else {
306 tdata.data = pasteboard.dataForType(type);
295 } 307 }
296 } 308 if (tdata.data !is null) {
297 return null; // No data available for this transfer 309 return transfer.nativeToJava(tdata);
310 }
311 }
312 return null;
298 } 313 }
299 314
300 /** 315 /**
301 * Returns <code>true</code> if the clipboard has been disposed, 316 * Returns <code>true</code> if the clipboard has been disposed,
302 * and <code>false</code> otherwise. 317 * and <code>false</code> otherwise.
433 if (data[i] is null || dataTypes[i] is null || !dataTypes[i].validate(data[i])) { 448 if (data[i] is null || dataTypes[i] is null || !dataTypes[i].validate(data[i])) {
434 DND.error(DWT.ERROR_INVALID_ARGUMENT); 449 DND.error(DWT.ERROR_INVALID_ARGUMENT);
435 } 450 }
436 } 451 }
437 if ((clipboards & DND.CLIPBOARD) is 0) return; 452 if ((clipboards & DND.CLIPBOARD) is 0) return;
438 if (OS.ClearCurrentScrap() !is OS.noErr) { 453 NSPasteboard pasteboard = NSPasteboard.generalPasteboard();
454 if (pasteboard is null) {
439 DND.error(DND.ERROR_CANNOT_SET_CLIPBOARD); 455 DND.error(DND.ERROR_CANNOT_SET_CLIPBOARD);
440 } 456 }
441 scrap = 0; 457 pasteboard.declareTypes(NSMutableArray.arrayWithCapacity(0), null);
442 int[] currentScrap = new int[1];
443 if (OS.GetCurrentScrap(currentScrap) !is OS.noErr) {
444 DND.error(DND.ERROR_CANNOT_SET_CLIPBOARD);
445 }
446 scrap = currentScrap[0];
447 // copy data directly over to System clipboard (not deferred)
448 for (int i=0; i<dataTypes.length; i++) { 458 for (int i=0; i<dataTypes.length; i++) {
449 int[] typeIds = dataTypes[i].getTypeIds(); 459 String[] typeNames = dataTypes[i].getTypeNames();
450 for (int j=0; j<typeIds.length; j++) { 460 for (int j=0; j<typeNames.length; j++) {
451 TransferData transferData = new TransferData(); 461 TransferData transferData = new TransferData();
452 transferData.type = typeIds[j]; 462 transferData.type = Transfer.registerType(typeNames[j]);
453 dataTypes[i].javaToNative(data[i], transferData); 463 dataTypes[i].javaToNative(data[i], transferData);
454 if (transferData.result !is OS.noErr) { 464 NSObject tdata = transferData.data;
455 DND.error(DND.ERROR_CANNOT_SET_CLIPBOARD); 465 NSString dataType = NSString.stringWith(typeNames[j]);
456 } 466 pasteboard.addTypes(NSArray.arrayWithObject(dataType), null);
457 //Drag and Drop can handle multiple items in one transfer but the 467 if (dataType.isEqual(OS.NSStringPboardType) ||
458 //Clipboard can not. 468 dataType.isEqual(OS.NSRTFPboardType) ||
459 byte[] datum = transferData.data[0]; 469 dataType.isEqual(OS.NSHTMLPboardType)) {
460 if (OS.PutScrapFlavor(scrap, transferData.type, 0, datum.length, datum) !is OS.noErr){ 470 pasteboard.setString((NSString) tdata, dataType);
461 DND.error(DND.ERROR_CANNOT_SET_CLIPBOARD); 471 } else if (dataType.isEqual(OS.NSURLPboardType)) {
472 NSURL url = (NSURL) tdata;
473 url.writeToPasteboard(pasteboard);
474 } else if (dataType.isEqual(OS.NSFilenamesPboardType)) {
475 pasteboard.setPropertyList((NSArray) tdata, dataType);
476 } else {
477 pasteboard.setData((NSData) tdata, dataType);
462 } 478 }
463 } 479 }
464 } 480 }
465 } 481 }
466 482
506 * 522 *
507 * @since 3.1 523 * @since 3.1
508 */ 524 */
509 public TransferData[] getAvailableTypes(int clipboards) { 525 public TransferData[] getAvailableTypes(int clipboards) {
510 checkWidget(); 526 checkWidget();
511 if ((clipboards & DND.CLIPBOARD) is 0) return new TransferData[0]; 527 if ((clipboards & DND.CLIPBOARD) is 0) return new TransferData[0];
512 int[] types = _getAvailableTypes(); 528 NSPasteboard pasteboard = NSPasteboard.generalPasteboard();
513 TransferData[] result = new TransferData[types.length]; 529 NSArray types = pasteboard.types();
514 for (int i = 0; i < types.length; i++) { 530 int count = (int)/*64*/types.count();
531 TransferData[] result = new TransferData[count];
532 for (int i = 0; i < count; i++) {
515 result[i] = new TransferData(); 533 result[i] = new TransferData();
516 result[i].type = types[i]; 534 result[i].type = Transfer.registerType(new NSString(types.objectAtIndex(i)).getString());
517 } 535 }
518 return result; 536 return result;
519 } 537 }
520 538
521 /** 539 /**
534 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 552 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
535 * </ul> 553 * </ul>
536 */ 554 */
537 public String[] getAvailableTypeNames() { 555 public String[] getAvailableTypeNames() {
538 checkWidget(); 556 checkWidget();
539 int[] types = _getAvailableTypes(); 557 NSPasteboard pasteboard = NSPasteboard.generalPasteboard();
540 String[] names = new String[types.length]; 558 NSArray types = pasteboard.types();
541 for (int i = 0; i < types.length; i++) { 559 int count = (int)/*64*/types.count();
542 int type = types[i]; 560 String[] result = new String[count];
543 StringBuffer sb = new StringBuffer(); 561 for (int i = 0; i < count; i++) {
544 sb.append(cast(wchar)((type & 0xff000000) >> 24)); 562 result[i] = new NSString(types.objectAtIndex(i)).getString();
545 sb.append(cast(wchar)((type & 0x00ff0000) >> 16)); 563 }
546 sb.append(cast(wchar)((type & 0x0000ff00) >> 8)); 564 return result;
547 sb.append(cast(wchar)((type & 0x000000ff) >> 0)); 565 }
548 names[i] = sb.toString(); 566 }
549 }
550 return names;
551 }
552
553 int[] _getAvailableTypes() {
554 int[] types = new int[0];
555 int[] scrap = new int[1];
556 if (OS.GetCurrentScrap(scrap) !is OS.noErr) return types;
557 int[] count = new int[1];
558 if (OS.GetScrapFlavorCount(scrap[0], count) !is OS.noErr || count[0] is 0) return types;
559 int[] info = new int[count[0] * 2];
560 if (OS.GetScrapFlavorInfoList(scrap[0], count, info) !is OS.noErr) return types;
561 types = new int[count[0]];
562 for (int i= 0; i < count [0]; i++) {
563 types[i] = info[i*2];
564 }
565 return types;
566 }
567 }