diff --git a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/CurrentPageImpl.java b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/CurrentPageImpl.java index 0c8c17df003..d58688f978f 100644 --- a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/CurrentPageImpl.java +++ b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/CurrentPageImpl.java @@ -336,6 +336,10 @@ public void printPreview(boolean pre) }); } +void addStringToTransferable(String mimeType, String text) { + System.out.println("mimeType:" + mimeType + " text:" + text); +} + // // Native methods // diff --git a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/test/WorkDialog.java b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/test/WorkDialog.java index 5e7945a2180..8036882bed7 100644 --- a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/test/WorkDialog.java +++ b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/test/WorkDialog.java @@ -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"); diff --git a/mozilla/java/webclient/src_moz/EmbedWindow.cpp b/mozilla/java/webclient/src_moz/EmbedWindow.cpp index 64f8a6e7b9f..1919f260f12 100644 --- a/mozilla/java/webclient/src_moz/EmbedWindow.cpp +++ b/mozilla/java/webclient/src_moz/EmbedWindow.cpp @@ -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 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 genericFlavor; dfList->GetElementAt ( i, getter_AddRefs(genericFlavor) ); nsCOMPtr 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 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 plainText ( do_QueryInterface(aPrimitive) ); + if ( plainText ) { + nsCAutoString data; + plainText->GetData ( data ); + *aDataBuff = ToNewCString(data); + } + } + else { + nsCOMPtr 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 encoder; + + // get the charset + nsCAutoString platformCharset; + nsCOMPtr 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 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 diff --git a/mozilla/java/webclient/src_moz/EmbedWindow.h b/mozilla/java/webclient/src_moz/EmbedWindow.h index ea001df3307..797ae218fc8 100644 --- a/mozilla/java/webclient/src_moz/EmbedWindow.h +++ b/mozilla/java/webclient/src_moz/EmbedWindow.h @@ -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 mWebBrowser; // [OWNER] diff --git a/mozilla/java/webclient/src_moz/Makefile.in b/mozilla/java/webclient/src_moz/Makefile.in index f24e5578529..894b4f53866 100644 --- a/mozilla/java/webclient/src_moz/Makefile.in +++ b/mozilla/java/webclient/src_moz/Makefile.in @@ -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 -