1 /******************************************************************************* 2 * Copyright (c) 2000, 2008 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 10 * Port to the D programming language: 11 * Frank Benoit <benoit@tionex.de> 12 *******************************************************************************/ 13 module org.eclipse.swt.dnd.FileTransfer; 14 15 import org.eclipse.swt.internal.gtk.OS; 16 import org.eclipse.swt.dnd.ByteArrayTransfer; 17 import org.eclipse.swt.dnd.TransferData; 18 import org.eclipse.swt.dnd.DND; 19 import java.lang.all; 20 21 /** 22 * The class <code>FileTransfer</code> provides a platform specific mechanism 23 * for converting a list of files represented as a java <code>String[]</code> to a 24 * platform specific representation of the data and vice versa. 25 * Each <code>String</code> in the array contains the absolute path for a single 26 * file or directory. 27 * 28 * <p>An example of a java <code>String[]</code> containing a list of files is shown 29 * below:</p> 30 * 31 * <code><pre> 32 * File file1 = new File("C:\temp\file1"); 33 * File file2 = new File("C:\temp\file2"); 34 * String[] fileData = new String[2]; 35 * fileData[0] = file1.getAbsolutePath(); 36 * fileData[1] = file2.getAbsolutePath(); 37 * </code></pre> 38 * 39 * @see Transfer 40 */ 41 public class FileTransfer : ByteArrayTransfer { 42 43 private static FileTransfer _instance; 44 private static const String URI_LIST = "text/uri-list"; //$NON-NLS-1$ 45 private static const int URI_LIST_ID; 46 private static const String separator = "\r\n"; 47 48 static this(){ 49 URI_LIST_ID = registerType(URI_LIST); 50 _instance = new FileTransfer(); 51 } 52 53 private this() {} 54 55 /** 56 * Returns the singleton instance of the FileTransfer class. 57 * 58 * @return the singleton instance of the FileTransfer class 59 */ 60 public static FileTransfer getInstance () { 61 return _instance; 62 } 63 64 /** 65 * This implementation of <code>javaToNative</code> converts a list of file names 66 * represented by a java <code>String[]</code> to a platform specific representation. 67 * Each <code>String</code> in the array contains the absolute path for a single 68 * file or directory. 69 * 70 * @param object a java <code>String[]</code> containing the file names to be converted 71 * @param transferData an empty <code>TransferData</code> object that will 72 * be filled in on return with the platform specific format of the data 73 * 74 * @see Transfer#nativeToJava 75 */ 76 public override void javaToNative(Object object, TransferData transferData) { 77 transferData.result = 0; 78 if (!checkFile(object) || !isSupportedType(transferData)) { 79 DND.error(DND.ERROR_INVALID_DATA); 80 } 81 String[] files = (cast(ArrayWrapperString2)object).array; 82 char[] buffer; 83 for (int i = 0; i < files.length; i++) { 84 String string = files[i]; 85 if (string.ptr is null) continue; 86 if (string.length is 0) continue; 87 GError* error; 88 auto localePtr = OS.g_filename_from_utf8(string.ptr, -1, null, null, &error); 89 if (error !is null || localePtr is null) continue; 90 auto uriPtr = OS.g_filename_to_uri(localePtr, null, &error); 91 OS.g_free(localePtr); 92 if (error !is null || uriPtr is null) continue; 93 String temp = fromStringz( uriPtr )._idup(); 94 OS.g_free(uriPtr); 95 size_t newLength = (i > 0) ? buffer.length+separator.length+temp.length : temp.length; 96 auto newBuffer = new char[newLength]; 97 size_t offset = 0; 98 if (i > 0) { 99 System.arraycopy(buffer, 0, newBuffer, 0, buffer.length); 100 offset += buffer.length; 101 System.arraycopy(separator, 0, newBuffer, offset, separator.length); 102 offset += separator.length; 103 } 104 System.arraycopy(temp, 0, newBuffer, offset, temp.length); 105 buffer = newBuffer; 106 } 107 if (buffer.length is 0) return; 108 char* ptr = cast(char*)OS.g_malloc(buffer.length+1); 109 ptr[ 0 .. buffer.length ] = buffer; 110 ptr[ buffer.length ] = '\0'; 111 transferData.pValue = ptr; 112 transferData.length = cast(int)/*64bit*/buffer.length; 113 transferData.format = 8; 114 transferData.result = 1; 115 } 116 /** 117 * This implementation of <code>nativeToJava</code> converts a platform specific 118 * representation of a list of file names to a java <code>String[]</code>. 119 * Each String in the array contains the absolute path for a single file or directory. 120 * 121 * @param transferData the platform specific representation of the data to be converted 122 * @return a java <code>String[]</code> containing a list of file names if the conversion 123 * was successful; otherwise null 124 * 125 * @see Transfer#javaToNative 126 */ 127 public override Object nativeToJava(TransferData transferData) { 128 if ( !isSupportedType(transferData) || transferData.pValue is null || transferData.length <= 0 ) return null; 129 auto temp = transferData.pValue[ 0 .. transferData.length ]; 130 char*[] files; 131 int offset = 0; 132 for (int i = 0; i < temp.length - 1; i++) { 133 if (temp[i] is '\r' && temp[i+1] is '\n') { 134 int size = i - offset; 135 char* file = cast(char*)OS.g_malloc(size + 1); 136 file[ 0 .. size ] = temp[ offset .. offset+size ]; 137 file[ size ] = '\0'; 138 files ~= file; 139 offset = i + 2; 140 } 141 } 142 if (offset < temp.length - 2) { 143 auto size = temp.length - offset; 144 char* file = cast(char*)OS.g_malloc(size + 1); 145 file[ 0 .. size ] = temp[ offset .. offset+size ]; 146 file[ size ] = '\0'; 147 files ~= file; 148 } 149 String[] fileNames; 150 for (int i = 0; i < files.length; i++) { 151 GError* error; 152 auto localePtr = OS.g_filename_from_uri(files[i], null, &error); 153 OS.g_free(files[i]); 154 if (error !is null || localePtr is null) continue; 155 auto utf8Ptr = OS.g_filename_to_utf8(localePtr, -1, null, null, &error); 156 OS.g_free(localePtr); 157 if (error !is null || utf8Ptr is null) continue; 158 String buffer = fromStringz( utf8Ptr )._idup(); 159 OS.g_free(utf8Ptr); 160 String name = buffer; 161 String[] newFileNames = new String[]( fileNames.length + 1 ); 162 System.arraycopy(fileNames, 0, newFileNames, 0, fileNames.length); 163 newFileNames[fileNames.length] = name; 164 fileNames = newFileNames; 165 } 166 if (fileNames.length is 0) return null; 167 return new ArrayWrapperString2( fileNames ); 168 } 169 170 protected override int[] getTypeIds(){ 171 return [URI_LIST_ID]; 172 } 173 174 protected override String[] getTypeNames(){ 175 return [URI_LIST]; 176 } 177 178 bool checkFile(Object object) { 179 if( object is null ) return false; 180 ArrayWrapperString2 arr = cast(ArrayWrapperString2)object; 181 if( arr is null ) return false; 182 if( arr.array.length is 0 ) return false; 183 184 String[] strings = arr.array; 185 for (int i = 0; i < strings.length; i++) { 186 if (strings[i] is null || strings[i].length is 0) return false; 187 } 188 return true; 189 } 190 191 protected override bool validate(Object object) { 192 return checkFile(object); 193 } 194 }