Issue: 369376

Workaround

M webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/CurrentPageImpl.java

+void addStringToTransferable(String mimeType, String text) {

  This method is called from native code when a Transferable is being
  inspected for the DataFlavors it supports.

M webclient/classes_spec/org/mozilla/webclient/test/WorkDialog.java

- Whitespace

M webclient/src_moz/EmbedWindow.cpp
M webclient/src_moz/EmbedWindow.h

- copy code from nsPrimitiveHelpers to aid in the extraction of text
  from the nsITransferable

- Flesh out GetText(), SendTextToJava() methods.

M webclient/src_moz/Makefile.in

- Additional dependencies for nsPrimitiveHelpers copy.
This commit is contained in:
edburns%acm.org 2007-02-15 22:07:28 +00:00
parent 992dbcc9a8
commit 47eef2357e
5 changed files with 204 additions and 3 deletions

View File

@ -336,6 +336,10 @@ public void printPreview(boolean pre)
});
}
void addStringToTransferable(String mimeType, String text) {
System.out.println("mimeType:" + mimeType + " text:" + text);
}
//
// Native methods
//

View File

@ -25,7 +25,7 @@ public class WorkDialog extends GJTDialog {
public WorkDialog(Frame frame, DialogClient client, String title,
Panel workPanel, boolean modal) {
super(frame, title, client, modal);
this.workPanel = workPanel;
this.workPanel = workPanel;
setLayout(new BorderLayout());
if(workPanel != null)
add(workPanel, "North");

View File

@ -49,6 +49,10 @@
#include "nsIInputStream.h"
#include "nsIURI.h"
#include "nsIDocShellLoadInfo.h"
#include "nsIUnicodeEncoder.h"
#include "nsISaveAsCharset.h"
#include "nsIPlatformCharset.h"
#include "nsIEntityConverter.h"
#include "nsNetUtil.h" // for NS_NewPostDataStream
#include "NativeBrowserControl.h"
@ -58,6 +62,15 @@
#include "nsCRT.h"
void nsPrimitiveHelpers_CreateDataFromPrimitive(const char* aFlavor,
nsISupports* aPrimitive,
void** aDataBuff,
PRUint32 aDataLen);
nsresult
nsPrimitiveHelpers_ConvertUnicodeToPlatformPlainText (PRUnichar* inUnicode,
PRInt32 inUnicodeLen,
char** outPlainTextData,
PRInt32* outPlainTextLen);
EmbedWindow::EmbedWindow(void)
{
mOwner = nsnull;
@ -763,6 +776,8 @@ NS_IMETHODIMP EmbedWindow::OnCopyOrDrag(nsIDOMEvent *aEvent,
// Get the transferable list of data flavors
nsCOMPtr<nsISupportsArray> dfList;
aTransferable->FlavorsTransferableCanExport(getter_AddRefs(dfList));
jstring textData = nsnull;
jstring mimeType = nsnull;
// Walk through flavors that contain data and send them back to java
PRUint32 i;
@ -772,8 +787,8 @@ NS_IMETHODIMP EmbedWindow::OnCopyOrDrag(nsIDOMEvent *aEvent,
nsCOMPtr<nsISupports> genericFlavor;
dfList->GetElementAt ( i, getter_AddRefs(genericFlavor) );
nsCOMPtr<nsISupportsCString> currentFlavor ( do_QueryInterface(genericFlavor) );
nsXPIDLCString flavorStr;
if ( currentFlavor ) {
nsXPIDLCString flavorStr;
currentFlavor->ToString(getter_Copies(flavorStr));
UINT format = GetFormat(flavorStr);
@ -781,6 +796,7 @@ NS_IMETHODIMP EmbedWindow::OnCopyOrDrag(nsIDOMEvent *aEvent,
// map one flavor to another or add additional flavors based
// on what's required for the win32 impl.
if ( strcmp(flavorStr, kUnicodeMime) == 0 ) {
rv = GetText(env, aTransferable, flavorStr, &textData);
// if we find text/unicode, also advertise text/plain
// (which we will convert on our own in
// nsDataObj::GetText().
@ -788,6 +804,7 @@ NS_IMETHODIMP EmbedWindow::OnCopyOrDrag(nsIDOMEvent *aEvent,
else if ( strcmp(flavorStr, kHTMLMime) == 0 ) {
// if we find text/html, also advertise win32's html flavor (which we will convert
// on our own in nsDataObj::GetText().
rv = GetText(env, aTransferable, flavorStr, &textData);
}
else if ( strcmp(flavorStr, kURLMime) == 0 ) {
// if we're a url, in addition to also being text, we
@ -818,6 +835,15 @@ NS_IMETHODIMP EmbedWindow::OnCopyOrDrag(nsIDOMEvent *aEvent,
}
#endif
}
if (NS_SUCCEEDED(rv) && textData) {
mimeType = ::util_NewStringUTF(env, flavorStr);
rv = SendTextToJava(env, mimeType, textData);
::util_DeleteStringUTF(env, mimeType);
}
if (textData) {
::util_DeleteStringUTF(env, textData);
}
}
return NS_OK;
}
@ -855,6 +881,84 @@ UINT EmbedWindow::GetFormat(const char* aMimeStr)
return format;
}
NS_IMETHODIMP
EmbedWindow::GetText(JNIEnv *env,
nsITransferable *aTransferable,
const nsACString & aDataFlavor,
jstring *result)
{
if (nsnull == result) {
return NS_ERROR_NULL_POINTER;
}
// taken from widget\src\windows\nsDataObj.cpp nsDataObj::GetText().
void* data;
PRUint32 len;
// if someone asks for text/plain, look up text/unicode instead in the transferable.
const char* flavorStr;
const nsPromiseFlatCString& flat = PromiseFlatCString(aDataFlavor);
if ( aDataFlavor.Equals("text/plain") ) {
flavorStr = kUnicodeMime;
}
else {
flavorStr = flat.get();
}
// NOTE: CreateDataFromPrimitive creates new memory, that needs to be deleted
nsCOMPtr<nsISupports> genericDataWrapper;
aTransferable->GetTransferData(flavorStr, getter_AddRefs(genericDataWrapper), &len);
if ( !len ) {
return NS_ERROR_NULL_POINTER;
}
nsPrimitiveHelpers_CreateDataFromPrimitive(flavorStr, genericDataWrapper,
&data, len );
// We play games under the hood and advertise flavors that we know we
// can support, only they require a bit of conversion or munging of the data.
// Do that here.
//
// Someone is asking for text/plain; convert the unicode (assuming it's present)
// to text with the correct platform encoding.
char* plainTextData = nsnull;
PRUnichar* castedUnicode = NS_REINTERPRET_CAST(PRUnichar*, data);
PRInt32 plainTextLen = 0;
nsPrimitiveHelpers_ConvertUnicodeToPlatformPlainText ( castedUnicode, len / 2, &plainTextData, &plainTextLen );
*result = ::util_NewStringUTF(env, plainTextData);
nsMemory::Free(data);
return NS_OK;
}
NS_IMETHODIMP
EmbedWindow::SendTextToJava(JNIEnv *env, jstring mimeType, jstring textData)
{
PR_ASSERT(nsnull != aCurrentPageObj);
jclass clazz = nsnull;
jmethodID mid = nsnull;
if (nsnull == (clazz = env->GetObjectClass(aCurrentPageObj))) {
return NS_ERROR_NULL_POINTER;
}
if (nsnull == (mid = env->GetMethodID(clazz, "addStringToTransferable",
"(Ljava/lang/String;Ljava/lang/String;)V"))) {
return NS_ERROR_NULL_POINTER;
}
env->CallVoidMethod(aCurrentPageObj, mid,
mimeType, textData);
if (env->ExceptionOccurred()) {
env->ExceptionDescribe();
env->ExceptionClear();
return NS_ERROR_FAILURE;
}
return NS_OK;
}
// nsITooltipListener
@ -967,3 +1071,86 @@ EmbedWindow::GetInterface(const nsIID &aIID, void** aInstancePtr)
return rv;
}
//
// CreateDataFromPrimitive
//
// Given a nsISupports* primitive and the flavor it represents, creates a new data
// buffer with the data in it. This data will be null terminated, but the length
// parameter does not reflect that.
//
void
nsPrimitiveHelpers_CreateDataFromPrimitive ( const char* aFlavor, nsISupports* aPrimitive,
void** aDataBuff, PRUint32 aDataLen )
{
if ( !aDataBuff )
return;
if ( strcmp(aFlavor,kTextMime) == 0 ) {
nsCOMPtr<nsISupportsCString> plainText ( do_QueryInterface(aPrimitive) );
if ( plainText ) {
nsCAutoString data;
plainText->GetData ( data );
*aDataBuff = ToNewCString(data);
}
}
else {
nsCOMPtr<nsISupportsString> doubleByteText ( do_QueryInterface(aPrimitive) );
if ( doubleByteText ) {
nsAutoString data;
doubleByteText->GetData ( data );
*aDataBuff = ToNewUnicode(data);
}
}
}
//
// ConvertUnicodeToPlatformPlainText
//
// Given a unicode buffer (flavor text/unicode), this converts it to plain text using
// the appropriate platform charset encoding. |inUnicodeLen| is the length of the input
// string, not the # of bytes in the buffer. The |outPlainTextData| is null terminated,
// but its length parameter, |outPlainTextLen|, does not reflect that.
//
nsresult
nsPrimitiveHelpers_ConvertUnicodeToPlatformPlainText ( PRUnichar* inUnicode, PRInt32 inUnicodeLen,
char** outPlainTextData, PRInt32* outPlainTextLen )
{
if ( !outPlainTextData || !outPlainTextLen )
return NS_ERROR_INVALID_ARG;
// Get the appropriate unicode encoder. We're guaranteed that this won't change
// through the life of the app so we can cache it.
nsresult rv;
nsCOMPtr<nsIUnicodeEncoder> encoder;
// get the charset
nsCAutoString platformCharset;
nsCOMPtr <nsIPlatformCharset> platformCharsetService = do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv))
rv = platformCharsetService->GetCharset(kPlatformCharsetSel_PlainTextInClipboard, platformCharset);
if (NS_FAILED(rv))
platformCharset.AssignLiteral("ISO-8859-1");
// use transliterate to convert things like smart quotes to normal quotes for plain text
nsCOMPtr<nsISaveAsCharset> converter = do_CreateInstance("@mozilla.org/intl/saveascharset;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = converter->Init(platformCharset.get(),
nsISaveAsCharset::attr_EntityAfterCharsetConv +
nsISaveAsCharset::attr_FallbackQuestionMark,
nsIEntityConverter::transliterate);
NS_ENSURE_SUCCESS(rv, rv);
rv = converter->Convert(inUnicode, outPlainTextData);
*outPlainTextLen = *outPlainTextData ? strlen(*outPlainTextData) : 0;
NS_ASSERTION ( NS_SUCCEEDED(rv), "Error converting unicode to plain text" );
return rv;
} // ConvertUnicodeToPlatformPlainText

View File

@ -47,6 +47,7 @@ class nsIInputStream;
class nsIURI;
class nsIDocShellLoadInfo;
class nsIWeakReference;
class nsITransferable;
#include "ns_util.h"
@ -112,6 +113,11 @@ public:
private:
UINT GetFormat(const char* aMimeStr);
NS_IMETHOD GetText(JNIEnv * env, nsITransferable *aTransferable,
const nsACString & aDataFlavor, jstring *result);
NS_IMETHOD SendTextToJava(JNIEnv *env,
jstring mimeType,
jstring textData);
NativeBrowserControl *mOwner;
nsCOMPtr<nsIWebBrowser> mWebBrowser; // [OWNER]

View File

@ -61,6 +61,8 @@ REQUIRES = xpcom \
find \
appcomps \
appshell \
uconv \
unicharutil \
pref \
locale \
intl \
@ -163,6 +165,7 @@ EXTRA_LIBS += \
$(DIST)/lib/$(LIB_PREFIX)embed_base_s.$(LIB_SUFFIX) \
$(NULL)
ifeq ($(OS_ARCH),WINNT)
EXTRA_LIBS += \
$(DIST)/lib/wc_share.lib \
@ -199,6 +202,8 @@ EXTRA_DSO_LDOPTS += -lwc_share
endif
endif
INCLUDES += -I$(MOZ_SRC)/mozilla/widget/src/xpwidgets
ifeq ($(OS_ARCH),Linux)
INCLUDES := -I$(MOZ_JDKHOME)/include -I$(MOZ_JDKHOME)/include/linux $(INCLUDES) \
-I$(DEPTH)/widget/src/gtk -I$(srcdir)/../src_share -I../src_share
@ -218,4 +223,3 @@ endif
clobber_all:: clobber