| //------------------------------------------------------------------------------ |
| // Copyright (c) 2005, 2006 IBM Corporation and others. |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v1.0 |
| // which accompanies this distribution, and is available at |
| // http://www.eclipse.org/legal/epl-v10.html |
| // |
| // Contributors: |
| // IBM Corporation - initial implementation |
| //------------------------------------------------------------------------------ |
| package org.eclipse.epf.common.win32; |
| |
| import org.eclipse.swt.dnd.ByteArrayTransfer; |
| import org.eclipse.swt.dnd.DND; |
| import org.eclipse.swt.dnd.TransferData; |
| import org.eclipse.swt.internal.ole.win32.COM; |
| import org.eclipse.swt.internal.ole.win32.FORMATETC; |
| import org.eclipse.swt.internal.ole.win32.IDataObject; |
| import org.eclipse.swt.internal.ole.win32.STGMEDIUM; |
| import org.eclipse.swt.internal.win32.OS; |
| |
| /** |
| * The class <code>HTMLTransfer</code> provides a platform specific mechanism |
| * for converting text in HTML format represented as a java <code>String</code> |
| * to a platform specific representation of the data and vice versa. See |
| * <code>Transfer</code> for additional information. |
| * |
| * <p> |
| * An example of a java <code>String</code> containing HTML text is shown |
| * below: |
| * </p> |
| * |
| * <code><pre> |
| * String htmlData = " |
| * <p> |
| * This is a paragraph of text. |
| * </p> |
| * "; |
| * </code></pre> |
| */ |
| public class Win32HTMLTransfer extends ByteArrayTransfer { |
| |
| static Win32HTMLTransfer _instance = new Win32HTMLTransfer(); |
| |
| static final String HTML_FORMAT = "HTML Format"; //$NON-NLS-1$ |
| |
| static final int HTML_FORMATID = registerType(HTML_FORMAT); |
| |
| static final String NUMBER = "00000000"; //$NON-NLS-1$ |
| |
| static final String HEADER = "Version:0.9\r\nStartHTML:" + NUMBER |
| + "\r\nEndHTML:" + NUMBER + "\r\nStartFragment:" + NUMBER |
| + "\r\nEndFragment:" + NUMBER + "\r\n"; |
| |
| static final String PREFIX = "<html><body><!--StartFragment-->"; //$NON-NLS-1$ |
| |
| static final String SUFFIX = "<!--EndFragment--></body></html>"; //$NON-NLS-1$ |
| |
| static final String StartFragment = "StartFragment:"; //$NON-NLS-1$ |
| |
| static final String EndFragment = "EndFragment:"; //$NON-NLS-1$ |
| |
| public Win32HTMLTransfer() { |
| } |
| |
| /** |
| * Returns the singleton instance of the HTMLTransfer class. |
| * |
| * @return the singleton instance of the HTMLTransfer class |
| */ |
| public static Win32HTMLTransfer getInstance() { |
| return _instance; |
| } |
| |
| /** |
| * This implementation of <code>javaToNative</code> converts |
| * HTML-formatted text represented by a java <code>String</code> to a |
| * platform specific representation. For additional information see |
| * <code>Transfer#javaToNative</code>. |
| * |
| * @param object |
| * a java <code>String</code> containing HTML text |
| * @param transferData |
| * an empty <code>TransferData</code> object; this object will |
| * be filled in on return with the platform specific format of |
| * the data |
| */ |
| public void javaToNative(Object object, TransferData transferData) { |
| if (!checkHTML(object) || !isSupportedType(transferData)) { |
| DND.error(DND.ERROR_INVALID_DATA); |
| } |
| String string = (String) object; |
| int count = string.length(); |
| char[] chars = new char[count + 1]; |
| string.getChars(0, count, chars, 0); |
| int codePage = OS.GetACP(); |
| int cchMultiByte = OS.WideCharToMultiByte(codePage, 0, chars, -1, null, |
| 0, null, null); |
| if (cchMultiByte == 0) { |
| transferData.stgmedium = new STGMEDIUM(); |
| transferData.result = COM.DV_E_STGMEDIUM; |
| return; |
| } |
| int startHTML = HEADER.length(); |
| int startFragment = startHTML + PREFIX.length(); |
| int endFragment = startFragment + cchMultiByte - 1; |
| int endHTML = endFragment + SUFFIX.length(); |
| |
| StringBuffer buffer = new StringBuffer(HEADER); |
| int maxLength = NUMBER.length(); |
| // startHTML |
| int start = buffer.toString().indexOf(NUMBER); |
| String temp = Integer.toString(startHTML); |
| buffer.replace(start + maxLength - temp.length(), start + maxLength, |
| temp); |
| // endHTML |
| start = buffer.toString().indexOf(NUMBER, start); |
| temp = Integer.toString(endHTML); |
| buffer.replace(start + maxLength - temp.length(), start + maxLength, |
| temp); |
| // startFragment |
| start = buffer.toString().indexOf(NUMBER, start); |
| temp = Integer.toString(startFragment); |
| buffer.replace(start + maxLength - temp.length(), start + maxLength, |
| temp); |
| // endFragment |
| start = buffer.toString().indexOf(NUMBER, start); |
| temp = Integer.toString(endFragment); |
| buffer.replace(start + maxLength - temp.length(), start + maxLength, |
| temp); |
| |
| buffer.append(PREFIX); |
| buffer.append(string); |
| buffer.append(SUFFIX); |
| |
| count = buffer.length(); |
| chars = new char[count + 1]; |
| buffer.getChars(0, count, chars, 0); |
| cchMultiByte = OS.WideCharToMultiByte(codePage, 0, chars, -1, null, 0, |
| null, null); |
| int lpMultiByteStr = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, |
| cchMultiByte); |
| OS.WideCharToMultiByte(codePage, 0, chars, -1, lpMultiByteStr, |
| cchMultiByte, null, null); |
| transferData.stgmedium = new STGMEDIUM(); |
| transferData.stgmedium.tymed = COM.TYMED_HGLOBAL; |
| transferData.stgmedium.unionField = lpMultiByteStr; |
| transferData.stgmedium.pUnkForRelease = 0; |
| transferData.result = COM.S_OK; |
| return; |
| } |
| |
| /** |
| * This implementation of <code>nativeToJava</code> converts a platform |
| * specific representation of HTML text to a java <code>String</code>. |
| * For additional information see <code>Transfer#nativeToJava</code>. |
| * |
| * @param transferData |
| * the platform specific representation of the data to be been |
| * converted |
| * @return a java <code>String</code> containing HTML text if the |
| * conversion was successful; otherwise null |
| */ |
| public Object nativeToJava(TransferData transferData) { |
| if (!isSupportedType(transferData) || transferData.pIDataObject == 0) |
| return null; |
| IDataObject data = new IDataObject(transferData.pIDataObject); |
| data.AddRef(); |
| STGMEDIUM stgmedium = new STGMEDIUM(); |
| FORMATETC formatetc = transferData.formatetc; |
| stgmedium.tymed = COM.TYMED_HGLOBAL; |
| transferData.result = data.GetData(formatetc, stgmedium); |
| data.Release(); |
| if (transferData.result != COM.S_OK) |
| return null; |
| int hMem = stgmedium.unionField; |
| |
| try { |
| int lpMultiByteStr = OS.GlobalLock(hMem); |
| if (lpMultiByteStr == 0) |
| return null; |
| try { |
| int codePage = OS.GetACP(); |
| int cchWideChar = OS.MultiByteToWideChar(codePage, |
| OS.MB_PRECOMPOSED, lpMultiByteStr, -1, null, 0); |
| if (cchWideChar == 0) |
| return null; |
| char[] lpWideCharStr = new char[cchWideChar - 1]; |
| OS |
| .MultiByteToWideChar(codePage, OS.MB_PRECOMPOSED, |
| lpMultiByteStr, -1, lpWideCharStr, |
| lpWideCharStr.length); |
| return new String(lpWideCharStr); |
| } finally { |
| OS.GlobalUnlock(hMem); |
| } |
| } finally { |
| OS.GlobalFree(hMem); |
| } |
| } |
| |
| protected int[] getTypeIds() { |
| return new int[] { HTML_FORMATID }; |
| } |
| |
| protected String[] getTypeNames() { |
| return new String[] { HTML_FORMAT }; |
| } |
| |
| boolean checkHTML(Object object) { |
| return (object != null && object instanceof String && ((String) object) |
| .length() > 0); |
| } |
| |
| protected boolean validate(Object object) { |
| return checkHTML(object); |
| } |
| } |