root/dwt/dnd/TextTransfer.d

Revision 320:da968414c383, 7.4 kB (checked in by Frank Benoit <benoit@tionex.de>, 1 month ago)

Merge changes SWT 3.4.1

Line 
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 dwt.dnd.TextTransfer;
14
15 import dwt.internal.ole.win32.COM;
16 import dwt.internal.ole.win32.OBJIDL;
17 import dwt.internal.win32.OS;
18
19 import dwt.dnd.ByteArrayTransfer;
20 import dwt.dnd.TransferData;
21 import dwt.dnd.DND;
22
23 import dwt.dwthelper.utils;
24 static import tango.text.Text;
25 alias tango.text.Text.Text!(char) StringBuffer;
26
27 /**
28  * The class <code>TextTransfer</code> provides a platform specific mechanism
29  * for converting plain text represented as a java <code>String</code>
30  * to a platform specific representation of the data and vice versa.
31  *
32  * <p>An example of a java <code>String</code> containing plain text is shown
33  * below:</p>
34  *
35  * <code><pre>
36  *     String textData = "Hello World";
37  * </code></pre>
38  *
39  * @see Transfer
40  */
41 public class TextTransfer : ByteArrayTransfer {
42
43     private static TextTransfer _instance;
44     private static const String CF_UNICODETEXT = "CF_UNICODETEXT"; //$NON-NLS-1$
45     private static const String CF_TEXT = "CF_TEXT"; //$NON-NLS-1$
46     private static const int CF_UNICODETEXTID = COM.CF_UNICODETEXT;
47     private static const int CF_TEXTID = COM.CF_TEXT;
48
49 private this() {}
50
51 /**
52  * Returns the singleton instance of the TextTransfer class.
53  *
54  * @return the singleton instance of the TextTransfer class
55  */
56 public static TextTransfer getInstance () {
57     if( _instance is null ){
58         synchronized {
59             if( _instance is null ){
60                 _instance = new TextTransfer();
61             }
62         }
63     }
64     return _instance;
65 }
66
67 /**
68  * This implementation of <code>javaToNative</code> converts plain text
69  * represented by a java <code>String</code> to a platform specific representation.
70  *
71  * @param object a java <code>String</code> containing text
72  * @param transferData an empty <code>TransferData</code> object that will
73  *      be filled in on return with the platform specific format of the data
74  *
75  * @see Transfer#nativeToJava
76  */
77 public void javaToNative (Object object, TransferData transferData){
78     if (!checkText(object) || !isSupportedType(transferData)) {
79         DND.error(DND.ERROR_INVALID_DATA);
80     }
81     transferData.result = COM.E_FAIL;
82     String string = (cast(ArrayWrapperString)object).array;
83     switch (transferData.type) {
84         case COM.CF_UNICODETEXT: {
85             wchar[] chars = StrToWCHARs(0,string, true);
86             int charCount = chars.length;
87             int byteCount = chars.length * 2;
88             auto newPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, byteCount);
89             OS.MoveMemory(newPtr, chars.ptr, byteCount);
90             transferData.stgmedium = new STGMEDIUM();
91             transferData.stgmedium.tymed = COM.TYMED_HGLOBAL;
92             transferData.stgmedium.unionField = newPtr;
93             transferData.stgmedium.pUnkForRelease = null;
94             transferData.result = COM.S_OK;
95             break;
96         }
97         case COM.CF_TEXT: {
98             wchar[] chars = StrToWCHARs(0,string, true);
99             int count = chars.length;
100             int codePage = OS.GetACP();
101             int cchMultiByte = OS.WideCharToMultiByte(codePage, 0, chars.ptr, -1, null, 0, null, null);
102             if (cchMultiByte is 0) {
103                 transferData.stgmedium = new STGMEDIUM();
104                 transferData.result = COM.DV_E_STGMEDIUM;
105                 return;
106             }
107             auto lpMultiByteStr = cast(CHAR*)OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, cchMultiByte);
108             OS.WideCharToMultiByte(codePage, 0, chars.ptr, -1, lpMultiByteStr, cchMultiByte, null, null);
109             transferData.stgmedium = new STGMEDIUM();
110             transferData.stgmedium.tymed = COM.TYMED_HGLOBAL;
111             transferData.stgmedium.unionField = lpMultiByteStr;
112             transferData.stgmedium.pUnkForRelease = null;
113             transferData.result = COM.S_OK;
114             break;
115         }
116         default:
117     }
118     return;
119 }
120
121 /**
122  * This implementation of <code>nativeToJava</code> converts a platform specific
123  * representation of plain text to a java <code>String</code>.
124  *
125  * @param transferData the platform specific representation of the data to be converted
126  * @return a java <code>String</code> containing text if the conversion was successful; otherwise null
127  *
128  * @see Transfer#javaToNative
129  */
130 public Object nativeToJava(TransferData transferData){
131     if (!isSupportedType(transferData) || transferData.pIDataObject is null) return null;
132
133     IDataObject data = transferData.pIDataObject;
134     data.AddRef();
135     FORMATETC* formatetc = transferData.formatetc;
136     STGMEDIUM* stgmedium = new STGMEDIUM();
137     stgmedium.tymed = COM.TYMED_HGLOBAL;
138     transferData.result = getData(data, formatetc, stgmedium);
139     data.Release();
140     if (transferData.result !is COM.S_OK) return null;
141     auto hMem = stgmedium.unionField;
142     try {
143         switch (transferData.type) {
144             case CF_UNICODETEXTID: {
145                 /* Ensure byteCount is a multiple of 2 bytes */
146                 int size = OS.GlobalSize(hMem) / 2 * 2;
147                 if (size is 0) return null;
148                 wchar[] chars = new wchar[size/2];
149                 auto ptr = OS.GlobalLock(hMem);
150                 if (ptr is null) return null;
151                 try {
152                     OS.MoveMemory(chars.ptr, ptr, size);
153                     int length_ = chars.length;
154                     for (int i=0; i<chars.length; i++) {
155                         if (chars [i] is '\0') {
156                             length_ = i;
157                             break;
158                         }
159                     }
160                     return new ArrayWrapperString (WCHARsToStr(chars[ 0 .. length_]));
161                 } finally {
162                     OS.GlobalUnlock(hMem);
163                 }
164             }
165             case CF_TEXTID: {
166                 auto lpMultiByteStr = cast(CHAR*)OS.GlobalLock(hMem);
167                 if (lpMultiByteStr is null) return null;
168                 try {
169                     int codePage = OS.GetACP();
170                     int cchWideChar = OS.MultiByteToWideChar (codePage, OS.MB_PRECOMPOSED, lpMultiByteStr, -1, null, 0);
171                     if (cchWideChar is 0) return null;
172                     wchar[] lpWideCharStr = new wchar [cchWideChar - 1];
173                     OS.MultiByteToWideChar (codePage, OS.MB_PRECOMPOSED, lpMultiByteStr, -1, lpWideCharStr.ptr, lpWideCharStr.length);
174                     return new ArrayWrapperString( WCHARzToStr(lpWideCharStr.ptr));
175                 } finally {
176                     OS.GlobalUnlock(hMem);
177                 }
178             }
179             default:
180         }
181     } finally {
182         OS.GlobalFree(hMem);
183     }
184     return null;
185 }
186
187 protected int[] getTypeIds(){
188     return [CF_UNICODETEXTID, CF_TEXTID];
189 }
190
191 protected String[] getTypeNames(){
192     return [CF_UNICODETEXT, CF_TEXT];
193 }
194
195 bool checkText(Object object) {
196     if( auto s = cast(ArrayWrapperString)object ){
197         return s.array.length > 0;
198     }
199     return false;
200 }
201
202 protected bool validate(Object object) {
203     return checkText(object);
204 }
205 }
Note: See TracBrowser for help on using the browser.