blob: 926d8d75ce68cb6b616aa7383b59ca1537bc16dd [file] [log] [blame]
//------------------------------------------------------------------------------
// 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 = &quot;
* <p>
* This is a paragraph of text.
* </p>
* &quot;;
* </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);
}
}