зеркало из https://github.com/mozilla/pjs.git
native clipboard/d&d impls now handle text/plain internally, always providing text/unicode to a client. fixes bugs 8427 and 24010. r=scc.
This commit is contained in:
Родитель
c997e6def0
Коммит
02674553b8
|
@ -743,7 +743,7 @@ nsTextEditorDragListener::DragEnter(nsIDOMEvent* aDragEvent)
|
|||
nsCOMPtr<nsIDragSession> dragSession(do_QueryInterface(dragService));
|
||||
if ( dragSession ) {
|
||||
PRBool flavorSupported = PR_FALSE;
|
||||
dragSession->IsDataFlavorSupported(kTextMime, &flavorSupported);
|
||||
dragSession->IsDataFlavorSupported(kUnicodeMime, &flavorSupported);
|
||||
if ( flavorSupported )
|
||||
dragSession->SetCanDrop(PR_TRUE);
|
||||
}
|
||||
|
@ -762,7 +762,7 @@ nsTextEditorDragListener::DragOver(nsIDOMEvent* aDragEvent)
|
|||
nsCOMPtr<nsIDragSession> dragSession(do_QueryInterface(dragService));
|
||||
if ( dragSession ) {
|
||||
PRBool flavorSupported = PR_FALSE;
|
||||
dragSession->IsDataFlavorSupported(kTextMime, &flavorSupported);
|
||||
dragSession->IsDataFlavorSupported(kUnicodeMime, &flavorSupported);
|
||||
if ( flavorSupported )
|
||||
dragSession->SetCanDrop(PR_TRUE);
|
||||
}
|
||||
|
@ -801,7 +801,7 @@ nsTextEditorDragListener::DragDrop(nsIDOMEvent* aMouseEvent)
|
|||
// Add the text Flavor to the transferable,
|
||||
// because that is the only type of data we are
|
||||
// looking for at the moment.
|
||||
trans->AddDataFlavor(kTextMime);
|
||||
trans->AddDataFlavor(kUnicodeMime);
|
||||
//trans->AddDataFlavor(mImageDataFlavor);
|
||||
|
||||
// Fill the transferable with data for each drag item in succession
|
||||
|
@ -820,11 +820,11 @@ nsTextEditorDragListener::DragDrop(nsIDOMEvent* aMouseEvent)
|
|||
PRUint32 len;
|
||||
char* whichFlavor = nsnull;
|
||||
trans->GetAnyTransferData(&whichFlavor, getter_AddRefs(genericDataObj), &len);
|
||||
nsCOMPtr<nsISupportsString> textDataObj( do_QueryInterface(genericDataObj) );
|
||||
nsCOMPtr<nsISupportsWString> textDataObj( do_QueryInterface(genericDataObj) );
|
||||
// If the string was not empty then paste it in
|
||||
if ( textDataObj )
|
||||
{
|
||||
char* text = nsnull;
|
||||
PRUnichar* text = nsnull;
|
||||
textDataObj->ToString(&text);
|
||||
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor);
|
||||
if ( htmlEditor && text )
|
||||
|
|
|
@ -3753,7 +3753,6 @@ NS_IMETHODIMP nsHTMLEditor::Paste()
|
|||
trans->AddDataFlavor(kHTMLMime);
|
||||
}
|
||||
trans->AddDataFlavor(kUnicodeMime);
|
||||
trans->AddDataFlavor(kTextMime);
|
||||
|
||||
// Get the Data from the clipboard
|
||||
if (NS_SUCCEEDED(clipboard->GetData(trans)))
|
||||
|
@ -3779,18 +3778,6 @@ NS_IMETHODIMP nsHTMLEditor::Paste()
|
|||
rv = InsertHTML(stuffToPaste);
|
||||
}
|
||||
}
|
||||
else if (flavor.Equals(kTextMime))
|
||||
{
|
||||
nsCOMPtr<nsISupportsString> textDataObj ( do_QueryInterface(genericDataObj) );
|
||||
if (textDataObj && len > 0)
|
||||
{
|
||||
char* text = nsnull;
|
||||
textDataObj->ToString ( &text );
|
||||
stuffToPaste.SetString ( text, len );
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
rv = InsertText(stuffToPaste);
|
||||
}
|
||||
}
|
||||
else if (flavor.Equals(kUnicodeMime))
|
||||
{
|
||||
nsCOMPtr<nsISupportsWString> textDataObj ( do_QueryInterface(genericDataObj) );
|
||||
|
@ -3830,7 +3817,7 @@ NS_IMETHODIMP nsHTMLEditor::CanPaste(PRBool &aCanPaste)
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// the flavors that we can deal with
|
||||
char* textEditorFlavors[] = { kTextMime, kUnicodeMime, nsnull };
|
||||
char* textEditorFlavors[] = { kUnicodeMime, nsnull };
|
||||
char* htmlEditorFlavors[] = { kJPEGImageMime, kHTMLMime, nsnull };
|
||||
|
||||
nsCOMPtr<nsISupportsArray> flavorsList;
|
||||
|
@ -3958,7 +3945,6 @@ NS_IMETHODIMP nsHTMLEditor::PasteAsPlaintextQuotation()
|
|||
{
|
||||
// We only handle plaintext pastes here
|
||||
trans->AddDataFlavor(kUnicodeMime);
|
||||
trans->AddDataFlavor(kTextMime);
|
||||
|
||||
// Get the Data from the clipboard
|
||||
clipboard->GetData(trans);
|
||||
|
@ -3983,19 +3969,7 @@ NS_IMETHODIMP nsHTMLEditor::PasteAsPlaintextQuotation()
|
|||
#endif
|
||||
nsAutoString flavor(flav);
|
||||
nsAutoString stuffToPaste;
|
||||
if (flavor.Equals(kTextMime))
|
||||
{
|
||||
nsCOMPtr<nsISupportsString> textDataObj ( do_QueryInterface(genericDataObj) );
|
||||
if (textDataObj && len > 0)
|
||||
{
|
||||
char* text = nsnull;
|
||||
textDataObj->ToString ( &text );
|
||||
stuffToPaste.SetString ( text, len );
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
rv = InsertAsPlaintextQuotation(stuffToPaste, 0);
|
||||
}
|
||||
}
|
||||
else if (flavor.Equals(kUnicodeMime))
|
||||
if (flavor.Equals(kUnicodeMime))
|
||||
{
|
||||
nsCOMPtr<nsISupportsWString> textDataObj ( do_QueryInterface(genericDataObj) );
|
||||
if (textDataObj && len > 0)
|
||||
|
|
|
@ -3753,7 +3753,6 @@ NS_IMETHODIMP nsHTMLEditor::Paste()
|
|||
trans->AddDataFlavor(kHTMLMime);
|
||||
}
|
||||
trans->AddDataFlavor(kUnicodeMime);
|
||||
trans->AddDataFlavor(kTextMime);
|
||||
|
||||
// Get the Data from the clipboard
|
||||
if (NS_SUCCEEDED(clipboard->GetData(trans)))
|
||||
|
@ -3779,18 +3778,6 @@ NS_IMETHODIMP nsHTMLEditor::Paste()
|
|||
rv = InsertHTML(stuffToPaste);
|
||||
}
|
||||
}
|
||||
else if (flavor.Equals(kTextMime))
|
||||
{
|
||||
nsCOMPtr<nsISupportsString> textDataObj ( do_QueryInterface(genericDataObj) );
|
||||
if (textDataObj && len > 0)
|
||||
{
|
||||
char* text = nsnull;
|
||||
textDataObj->ToString ( &text );
|
||||
stuffToPaste.SetString ( text, len );
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
rv = InsertText(stuffToPaste);
|
||||
}
|
||||
}
|
||||
else if (flavor.Equals(kUnicodeMime))
|
||||
{
|
||||
nsCOMPtr<nsISupportsWString> textDataObj ( do_QueryInterface(genericDataObj) );
|
||||
|
@ -3830,7 +3817,7 @@ NS_IMETHODIMP nsHTMLEditor::CanPaste(PRBool &aCanPaste)
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// the flavors that we can deal with
|
||||
char* textEditorFlavors[] = { kTextMime, kUnicodeMime, nsnull };
|
||||
char* textEditorFlavors[] = { kUnicodeMime, nsnull };
|
||||
char* htmlEditorFlavors[] = { kJPEGImageMime, kHTMLMime, nsnull };
|
||||
|
||||
nsCOMPtr<nsISupportsArray> flavorsList;
|
||||
|
@ -3958,7 +3945,6 @@ NS_IMETHODIMP nsHTMLEditor::PasteAsPlaintextQuotation()
|
|||
{
|
||||
// We only handle plaintext pastes here
|
||||
trans->AddDataFlavor(kUnicodeMime);
|
||||
trans->AddDataFlavor(kTextMime);
|
||||
|
||||
// Get the Data from the clipboard
|
||||
clipboard->GetData(trans);
|
||||
|
@ -3983,19 +3969,7 @@ NS_IMETHODIMP nsHTMLEditor::PasteAsPlaintextQuotation()
|
|||
#endif
|
||||
nsAutoString flavor(flav);
|
||||
nsAutoString stuffToPaste;
|
||||
if (flavor.Equals(kTextMime))
|
||||
{
|
||||
nsCOMPtr<nsISupportsString> textDataObj ( do_QueryInterface(genericDataObj) );
|
||||
if (textDataObj && len > 0)
|
||||
{
|
||||
char* text = nsnull;
|
||||
textDataObj->ToString ( &text );
|
||||
stuffToPaste.SetString ( text, len );
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
rv = InsertAsPlaintextQuotation(stuffToPaste, 0);
|
||||
}
|
||||
}
|
||||
else if (flavor.Equals(kUnicodeMime))
|
||||
if (flavor.Equals(kUnicodeMime))
|
||||
{
|
||||
nsCOMPtr<nsISupportsWString> textDataObj ( do_QueryInterface(genericDataObj) );
|
||||
if (textDataObj && len > 0)
|
||||
|
|
|
@ -743,7 +743,7 @@ nsTextEditorDragListener::DragEnter(nsIDOMEvent* aDragEvent)
|
|||
nsCOMPtr<nsIDragSession> dragSession(do_QueryInterface(dragService));
|
||||
if ( dragSession ) {
|
||||
PRBool flavorSupported = PR_FALSE;
|
||||
dragSession->IsDataFlavorSupported(kTextMime, &flavorSupported);
|
||||
dragSession->IsDataFlavorSupported(kUnicodeMime, &flavorSupported);
|
||||
if ( flavorSupported )
|
||||
dragSession->SetCanDrop(PR_TRUE);
|
||||
}
|
||||
|
@ -762,7 +762,7 @@ nsTextEditorDragListener::DragOver(nsIDOMEvent* aDragEvent)
|
|||
nsCOMPtr<nsIDragSession> dragSession(do_QueryInterface(dragService));
|
||||
if ( dragSession ) {
|
||||
PRBool flavorSupported = PR_FALSE;
|
||||
dragSession->IsDataFlavorSupported(kTextMime, &flavorSupported);
|
||||
dragSession->IsDataFlavorSupported(kUnicodeMime, &flavorSupported);
|
||||
if ( flavorSupported )
|
||||
dragSession->SetCanDrop(PR_TRUE);
|
||||
}
|
||||
|
@ -801,7 +801,7 @@ nsTextEditorDragListener::DragDrop(nsIDOMEvent* aMouseEvent)
|
|||
// Add the text Flavor to the transferable,
|
||||
// because that is the only type of data we are
|
||||
// looking for at the moment.
|
||||
trans->AddDataFlavor(kTextMime);
|
||||
trans->AddDataFlavor(kUnicodeMime);
|
||||
//trans->AddDataFlavor(mImageDataFlavor);
|
||||
|
||||
// Fill the transferable with data for each drag item in succession
|
||||
|
@ -820,11 +820,11 @@ nsTextEditorDragListener::DragDrop(nsIDOMEvent* aMouseEvent)
|
|||
PRUint32 len;
|
||||
char* whichFlavor = nsnull;
|
||||
trans->GetAnyTransferData(&whichFlavor, getter_AddRefs(genericDataObj), &len);
|
||||
nsCOMPtr<nsISupportsString> textDataObj( do_QueryInterface(genericDataObj) );
|
||||
nsCOMPtr<nsISupportsWString> textDataObj( do_QueryInterface(genericDataObj) );
|
||||
// If the string was not empty then paste it in
|
||||
if ( textDataObj )
|
||||
{
|
||||
char* text = nsnull;
|
||||
PRUnichar* text = nsnull;
|
||||
textDataObj->ToString(&text);
|
||||
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor);
|
||||
if ( htmlEditor && text )
|
||||
|
|
|
@ -608,7 +608,7 @@ NS_IMETHODIMP mozXMLTerminal::Paste()
|
|||
|
||||
// DataFlavors to get out of transferable
|
||||
trans->AddDataFlavor(kHTMLMime);
|
||||
trans->AddDataFlavor(kTextMime);
|
||||
trans->AddDataFlavor(kUnicodeMime);
|
||||
|
||||
// Get data from clipboard
|
||||
result = clipboard->GetData(trans);
|
||||
|
@ -629,7 +629,7 @@ NS_IMETHODIMP mozXMLTerminal::Paste()
|
|||
XMLT_LOG(mozXMLTerminal::Paste,20,("flavour=%s\n", temCStr));
|
||||
nsAllocator::Free(temCStr);
|
||||
|
||||
if (flavor.Equals(kHTMLMime)) {
|
||||
if (flavor.Equals(kHTMLMime) || flavor.Equals(kUnicodeMime)) {
|
||||
nsCOMPtr<nsISupportsWString> textDataObj ( do_QueryInterface(genericDataObj) );
|
||||
if (textDataObj && objLen > 0) {
|
||||
PRUnichar* text = nsnull;
|
||||
|
@ -637,17 +637,7 @@ NS_IMETHODIMP mozXMLTerminal::Paste()
|
|||
pasteString.SetString ( text, objLen / 2 );
|
||||
result = SendTextAux(pasteString);
|
||||
}
|
||||
|
||||
} else if (flavor.Equals(kTextMime)) {
|
||||
nsCOMPtr<nsISupportsString> textDataObj ( do_QueryInterface(genericDataObj) );
|
||||
if (textDataObj && objLen > 0) {
|
||||
char* text = nsnull;
|
||||
textDataObj->ToString ( &text );
|
||||
pasteString.SetString ( text, objLen );
|
||||
result = SendTextAux(pasteString);
|
||||
}
|
||||
}
|
||||
|
||||
nsAllocator::Free(bestFlavor);
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -138,7 +138,7 @@ nsClipboard::~nsClipboard()
|
|||
|
||||
// free the selection data, if any
|
||||
if (mSelectionData.data != nsnull)
|
||||
g_free(mSelectionData.data);
|
||||
nsAllocator::Free(mSelectionData.data);
|
||||
|
||||
nsClipboard *cb = (nsClipboard*)gtk_object_get_data(GTK_OBJECT(sWidget), "cb");
|
||||
if (cb != nsnull)
|
||||
|
@ -536,6 +536,7 @@ nsClipboard::GetNativeClipboardData(nsITransferable * aTransferable)
|
|||
PRUint32 cnt;
|
||||
flavorList->Count(&cnt);
|
||||
nsCAutoString foundFlavor;
|
||||
PRBool foundData = PR_FALSE;
|
||||
for ( PRUint32 i = 0; i < cnt; ++i ) {
|
||||
nsCOMPtr<nsISupports> genericFlavor;
|
||||
flavorList->GetElementAt ( i, getter_AddRefs(genericFlavor) );
|
||||
|
@ -546,11 +547,31 @@ nsClipboard::GetNativeClipboardData(nsITransferable * aTransferable)
|
|||
gint format = GetFormat(flavorStr);
|
||||
if (DoConvert(format)) {
|
||||
foundFlavor = flavorStr;
|
||||
foundData = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !foundData ) {
|
||||
// if we still haven't found anything yet and we're asked to find text/unicode, then
|
||||
// try to give them text plain if it's there.
|
||||
gint format = GetFormat(kTextMime);
|
||||
if (DoConvert(format)) {
|
||||
const char* castedText = NS_REINTERPRET_CAST(char*, mSelectionData.data);
|
||||
PRUnichar* convertedText = nsnull;
|
||||
PRInt32 convertedTextLen = 0;
|
||||
nsPrimitiveHelpers::ConvertPlatformPlainTextToUnicode ( castedText, mSelectionData.length,
|
||||
&convertedText, &convertedTextLen );
|
||||
if ( convertedText ) {
|
||||
// out with the old, in with the new
|
||||
nsAllocator::Free(mSelectionData.data);
|
||||
mSelectionData.data = NS_REINTERPRET_CAST(guchar*, convertedText);
|
||||
mSelectionData.length = convertedTextLen * 2;
|
||||
foundData = PR_TRUE;
|
||||
}
|
||||
} // if plain text data on clipboard
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CLIPBOARD
|
||||
printf(" Got the callback: '%s', %d\n",
|
||||
mSelectionData.data, mSelectionData.length);
|
||||
|
@ -564,24 +585,16 @@ nsClipboard::GetNativeClipboardData(nsITransferable * aTransferable)
|
|||
// We just have to copy it to the transferable.
|
||||
//
|
||||
|
||||
#if 0
|
||||
// pinkerton - we have the flavor already from above, so we don't need
|
||||
// to re-derrive it.
|
||||
nsString *name = new nsString((const char*)gdk_atom_name(mSelectionData.type));
|
||||
int format = GetFormat(*name);
|
||||
df->SetString((const char*)gdk_atom_name(sSelTypes[format]));
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||
nsPrimitiveHelpers::CreatePrimitiveForData ( foundFlavor, mSelectionData.data, mSelectionData.length, getter_AddRefs(genericDataWrapper) );
|
||||
aTransferable->SetTransferData(foundFlavor,
|
||||
genericDataWrapper,
|
||||
mSelectionData.length);
|
||||
|
||||
//delete name;
|
||||
|
||||
// transferable is now copying the data, so we can free it.
|
||||
// g_free(mSelectionData.data);
|
||||
if ( foundData ) {
|
||||
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||
nsPrimitiveHelpers::CreatePrimitiveForData ( foundFlavor, mSelectionData.data, mSelectionData.length, getter_AddRefs(genericDataWrapper) );
|
||||
aTransferable->SetTransferData(foundFlavor,
|
||||
genericDataWrapper,
|
||||
mSelectionData.length);
|
||||
}
|
||||
|
||||
// transferable is now owning the data, so we can free it.
|
||||
nsAllocator::Free(mSelectionData.data);
|
||||
mSelectionData.data = nsnull;
|
||||
mSelectionData.length = 0;
|
||||
|
||||
|
@ -661,7 +674,7 @@ nsClipboard::SelectionReceiver (GtkWidget *aWidget,
|
|||
g_print(" Copying mSelectionData pointer -- ");
|
||||
#endif
|
||||
mSelectionData = *aSD;
|
||||
mSelectionData.data = g_new(guchar, aSD->length + 1);
|
||||
mSelectionData.data = NS_REINTERPRET_CAST(guchar*, nsAllocator::Alloc(aSD->length + 1));
|
||||
#ifdef DEBUG_CLIPBOARD
|
||||
g_print(" Data = %s\n Length = %i\n", aSD->data, aSD->length);
|
||||
#endif
|
||||
|
@ -712,6 +725,14 @@ NS_IMETHODIMP
|
|||
nsClipboard::HasDataMatchingFlavors(nsISupportsArray* aFlavorList, PRBool * outResult)
|
||||
{
|
||||
// XXX this doesn't work right. need to fix it.
|
||||
|
||||
// Note to implementor...(from pink the clipboard bitch).
|
||||
//
|
||||
// If a client asks for unicode, first check if unicode is present. If not, then
|
||||
// check for plain text. If it's there, say "yes" as we will do the conversion
|
||||
// in GetNativeClipboardData(). From this point on, no client will
|
||||
// ever ask for text/plain explicitly. If they do, you must ASSERT!
|
||||
|
||||
#if 0
|
||||
*outResult = PR_FALSE;
|
||||
PRUint32 length;
|
||||
|
|
|
@ -191,6 +191,7 @@ nsClipboard :: GetNativeClipboardData(nsITransferable * aTransferable)
|
|||
// Now walk down the list of flavors. When we find one that is actually on the
|
||||
// clipboard, copy out the data into the transferable in that format. SetTransferData()
|
||||
// implicitly handles conversions.
|
||||
PRBool dataFound = PR_FALSE;
|
||||
PRUint32 cnt;
|
||||
flavorList->Count(&cnt);
|
||||
for ( PRUint32 i = 0; i < cnt; ++i ) {
|
||||
|
@ -207,15 +208,38 @@ nsClipboard :: GetNativeClipboardData(nsITransferable * aTransferable)
|
|||
void* clipboardData = nsnull;
|
||||
PRInt32 dataSize = 0L;
|
||||
nsresult loadResult = GetDataOffClipboard ( macOSFlavor, &clipboardData, &dataSize );
|
||||
if ( NS_SUCCEEDED(loadResult) && clipboardData ) {
|
||||
|
||||
if ( NS_SUCCEEDED(loadResult) && clipboardData )
|
||||
dataFound = PR_TRUE;
|
||||
else {
|
||||
// if we are looking for text/unicode and we fail to find it on the clipboard first,
|
||||
// try again with text/plain. If that is present, convert it to unicode.
|
||||
if ( strcmp(flavorStr, kUnicodeMime) == 0 ) {
|
||||
loadResult = GetDataOffClipboard ( 'TEXT', &clipboardData, &dataSize );
|
||||
if ( NS_SUCCEEDED(loadResult) && clipboardData ) {
|
||||
const char* castedText = NS_REINTERPRET_CAST(char*, clipboardData);
|
||||
PRUnichar* convertedText = nsnull;
|
||||
PRInt32 convertedTextLen = 0;
|
||||
nsPrimitiveHelpers::ConvertPlatformPlainTextToUnicode ( castedText, dataSize,
|
||||
&convertedText, &convertedTextLen );
|
||||
if ( convertedText ) {
|
||||
// out with the old, in with the new
|
||||
nsAllocator::Free(clipboardData);
|
||||
clipboardData = convertedText;
|
||||
dataSize = convertedTextLen * 2;
|
||||
dataFound = PR_TRUE;
|
||||
}
|
||||
} // if plain text data on clipboard
|
||||
} // if looking for text/unicode
|
||||
} // else we try one last ditch effort to find our data
|
||||
|
||||
if ( dataFound ) {
|
||||
// the DOM only wants LF, so convert from MacOS line endings to DOM line
|
||||
// endings.
|
||||
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks ( flavorStr, &clipboardData, &dataSize );
|
||||
|
||||
// put it into the transferable
|
||||
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||
nsPrimitiveHelpers::CreatePrimitiveForData ( flavorStr, clipboardData, dataSize, getter_AddRefs(genericDataWrapper) );
|
||||
nsPrimitiveHelpers::CreatePrimitiveForData ( flavorStr, clipboardData, dataSize, getter_AddRefs(genericDataWrapper) );
|
||||
errCode = aTransferable->SetTransferData ( flavorStr, genericDataWrapper, dataSize );
|
||||
#ifdef NS_DEBUG
|
||||
if ( errCode != NS_OK ) printf("nsClipboard:: Error setting data into transferable\n");
|
||||
|
@ -282,6 +306,10 @@ nsClipboard :: GetDataOffClipboard ( ResType inMacFlavor, void** outData, PRInt3
|
|||
//
|
||||
// Check the clipboard to see if we have any data that matches the given flavors. This
|
||||
// does NOT actually fetch the data. The items in the flavor list are nsISupportsString's.
|
||||
//
|
||||
// Handle the case where we ask for unicode and it's not there, but plain text is. We
|
||||
// say "yes" in that case, knowing that we will have to perform a conversion when we actually
|
||||
// pull the data off the clipboard.
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsClipboard :: HasDataMatchingFlavors ( nsISupportsArray* aFlavorList, PRBool * outResult )
|
||||
|
@ -305,17 +333,47 @@ nsClipboard :: HasDataMatchingFlavors ( nsISupportsArray* aFlavorList, PRBool *
|
|||
nsXPIDLCString flavor;
|
||||
flavorWrapper->ToString ( getter_Copies(flavor) );
|
||||
|
||||
// now that we have the flavor (whew!), run it through the mime mapper. If we
|
||||
// get something back, chances are good it's there on the clipboard (ignoring that
|
||||
// there is zero length data, but i don't think we need to worry about that). If
|
||||
#ifdef NS_DEBUG
|
||||
if ( strcmp(flavor, kTextMime) == 0 )
|
||||
NS_WARNING ( "DO NOT USE THE text/plain DATA FLAVOR ANY MORE. USE text/unicode INSTEAD" );
|
||||
#endif
|
||||
|
||||
// now that we have the flavor (whew!), run it through the mime mapper. If
|
||||
// the mapper returns a null flavor, then it ain't there.
|
||||
ResType macFlavor = theMapper.MapMimeTypeToMacOSType ( flavor, PR_FALSE );
|
||||
if ( macFlavor ) {
|
||||
*outResult = PR_TRUE; // we found one!
|
||||
if ( CheckIfFlavorPresent(macFlavor) )
|
||||
*outResult = PR_TRUE; // we found one!
|
||||
break;
|
||||
}
|
||||
else {
|
||||
// if the client asked for unicode and it wasn't present, check if we have TEXT.
|
||||
// We'll handle the actual data substitution in GetNativeClipboardData().
|
||||
if ( strcmp(flavor, kUnicodeMime) == 0 ) {
|
||||
if ( CheckIfFlavorPresent('TEXT') )
|
||||
*outResult = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // foreach flavor
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// CheckIfFlavorPresent
|
||||
//
|
||||
// A little utility routine for derminining if a given flavor is really there
|
||||
//
|
||||
PRBool
|
||||
nsClipboard :: CheckIfFlavorPresent ( ResType inMacFlavor )
|
||||
{
|
||||
PRBool retval = PR_FALSE;
|
||||
PRInt32 offsetUnused = 0;
|
||||
OSErr clipResult = ::GetScrap(NULL, inMacFlavor, NS_REINTERPRET_CAST(long*, &offsetUnused));
|
||||
if ( clipResult > 0 )
|
||||
retval = PR_TRUE; // we found one!
|
||||
|
||||
return retval;
|
||||
} // CheckIfFlavorPresent
|
||||
|
|
|
@ -56,7 +56,10 @@ protected:
|
|||
// helper to get the data off the clipboard. Caller responsible for deleting
|
||||
// |outData| with delete[].
|
||||
nsresult GetDataOffClipboard ( ResType inMacFlavor, void** outData, PRInt32* outDataSize ) ;
|
||||
|
||||
|
||||
// helper to check if the data is really there
|
||||
PRBool CheckIfFlavorPresent ( ResType inMacFlavor ) ;
|
||||
|
||||
}; // nsClipboard
|
||||
|
||||
#endif // nsClipboard_h__
|
||||
|
|
|
@ -304,61 +304,61 @@ nsDragService :: GetData ( nsITransferable * aTransferable, PRUint32 aItemIndex
|
|||
FlavorType macOSFlavor = theMapper.MapMimeTypeToMacOSType(flavorStr, PR_FALSE);
|
||||
#if DEBUG_DD
|
||||
printf("looking for data in type %s, mac flavor %ld\n", NS_STATIC_CAST(const char*,flavorStr), macOSFlavor);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// check if it is present in the current drag item.
|
||||
FlavorFlags unused;
|
||||
if ( macOSFlavor && ::GetFlavorFlags(mDragRef, itemRef, macOSFlavor, &unused) == noErr ) {
|
||||
|
||||
#if DEBUG_DD
|
||||
printf("flavor found\n");
|
||||
#endif
|
||||
// we have it, pull it out of the drag manager. Put it into memory that we allocate
|
||||
// with new[] so that the tranferable can own it (and then later use delete[]
|
||||
// on it).
|
||||
Size dataSize = 0;
|
||||
OSErr err = ::GetFlavorDataSize ( mDragRef, itemRef, macOSFlavor, &dataSize );
|
||||
#if DEBUG_DD
|
||||
printf("flavor data size is %ld\n", dataSize);
|
||||
#endif
|
||||
if ( !err && dataSize > 0 ) {
|
||||
char* dataBuff = NS_REINTERPRET_CAST(char*, nsAllocator::Alloc(dataSize));
|
||||
if ( !dataBuff )
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
err = ::GetFlavorData ( mDragRef, itemRef, macOSFlavor, dataBuff, &dataSize, 0 );
|
||||
if ( err ) {
|
||||
#ifdef NS_DEBUG
|
||||
printf("nsClipboard: Error getting data out of drag manager, #%ld\n", err);
|
||||
#endif
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// the DOM only wants LF, so convert from MacOS line endings to DOM line
|
||||
// endings.
|
||||
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks ( flavorStr, &dataBuff, NS_REINTERPRET_CAST(int*, &dataSize) );
|
||||
PRBool dataFound = PR_FALSE;
|
||||
void* dataBuff;
|
||||
PRInt32 dataSize = 0;
|
||||
if ( macOSFlavor && ::GetFlavorFlags(mDragRef, itemRef, macOSFlavor, &unused) == noErr ) {
|
||||
nsresult loadResult = ExtractDataFromOS(mDragRef, itemRef, macOSFlavor, &dataBuff, &dataSize);
|
||||
if ( NS_SUCCEEDED(loadResult) && dataBuff )
|
||||
dataFound = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
// if we are looking for text/unicode and we fail to find it on the clipboard first,
|
||||
// try again with text/plain. If that is present, convert it to unicode.
|
||||
if ( strcmp(flavorStr, kUnicodeMime) == 0 ) {
|
||||
if ( ::GetFlavorFlags(mDragRef, itemRef, 'TEXT', &unused) == noErr ) {
|
||||
nsresult loadResult = ExtractDataFromOS(mDragRef, itemRef, 'TEXT', &dataBuff, &dataSize);
|
||||
if ( NS_SUCCEEDED(loadResult) && dataBuff ) {
|
||||
const char* castedText = NS_REINTERPRET_CAST(char*, dataBuff);
|
||||
PRUnichar* convertedText = nsnull;
|
||||
PRInt32 convertedTextLen = 0;
|
||||
nsPrimitiveHelpers::ConvertPlatformPlainTextToUnicode ( castedText, dataSize,
|
||||
&convertedText, &convertedTextLen );
|
||||
if ( convertedText ) {
|
||||
// out with the old, in with the new
|
||||
nsAllocator::Free(dataBuff);
|
||||
dataBuff = convertedText;
|
||||
dataSize = convertedTextLen * 2;
|
||||
dataFound = PR_TRUE;
|
||||
}
|
||||
} // if plain text data on clipboard
|
||||
} // if plain text flavor present
|
||||
} // if looking for text/unicode
|
||||
} // else we try one last ditch effort to find our data
|
||||
|
||||
if ( dataFound ) {
|
||||
// the DOM only wants LF, so convert from MacOS line endings to DOM line
|
||||
// endings.
|
||||
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks ( flavorStr, &dataBuff, NS_REINTERPRET_CAST(int*, &dataSize) );
|
||||
|
||||
// put it into the transferable.
|
||||
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||
nsPrimitiveHelpers::CreatePrimitiveForData ( flavorStr, dataBuff, dataSize, getter_AddRefs(genericDataWrapper) );
|
||||
errCode = aTransferable->SetTransferData ( flavorStr, genericDataWrapper, dataSize );
|
||||
#ifdef NS_DEBUG
|
||||
if ( errCode != NS_OK ) printf("nsDragService:: Error setting data into transferable\n");
|
||||
#endif
|
||||
// put it into the transferable.
|
||||
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||
nsPrimitiveHelpers::CreatePrimitiveForData ( flavorStr, dataBuff, dataSize, getter_AddRefs(genericDataWrapper) );
|
||||
errCode = aTransferable->SetTransferData ( flavorStr, genericDataWrapper, dataSize );
|
||||
#ifdef NS_DEBUG
|
||||
if ( errCode != NS_OK ) printf("nsDragService:: Error setting data into transferable\n");
|
||||
#endif
|
||||
|
||||
nsAllocator::Free ( dataBuff );
|
||||
}
|
||||
else {
|
||||
#ifdef NS_DEBUG
|
||||
printf("nsDragService: Error getting data out of drag manager, #%ld\n", err);
|
||||
#endif
|
||||
errCode = NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsAllocator::Free ( dataBuff );
|
||||
errCode = NS_OK;
|
||||
|
||||
// we found one, get out of this loop!
|
||||
break;
|
||||
|
||||
} // if a flavor found
|
||||
|
||||
}
|
||||
}
|
||||
} // foreach flavor
|
||||
|
||||
|
@ -366,12 +366,18 @@ printf("flavor data size is %ld\n", dataSize);
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// IsDataFlavorSupported
|
||||
//
|
||||
// Check the OS to see if the given drag flavor is in the list. Oddly returns
|
||||
// NS_OK for success and NS_ERROR_FAILURE if flavor is not present.
|
||||
//
|
||||
// Handle the case where we ask for unicode and it's not there, but plain text is. We
|
||||
// say "yes" in that case, knowing that we will have to perform a conversion when we actually
|
||||
// pull the data out of the drag.
|
||||
//
|
||||
// ¥¥¥ this is obviously useless with more than one drag item. Need to specify
|
||||
// ¥¥¥Êand index to this API
|
||||
//
|
||||
|
@ -381,6 +387,11 @@ nsDragService :: IsDataFlavorSupported(const char *aDataFlavor, PRBool *_retval)
|
|||
if ( !_retval )
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
if ( strcmp(aDataFlavor, kTextMime) == 0 )
|
||||
NS_WARNING ( "DO NOT USE THE text/plain DATA FLAVOR ANY MORE. USE text/unicode INSTEAD" );
|
||||
#endif
|
||||
|
||||
*_retval = PR_FALSE;
|
||||
|
||||
// convert to 4 character MacOS type
|
||||
|
@ -400,9 +411,16 @@ nsDragService :: IsDataFlavorSupported(const char *aDataFlavor, PRBool *_retval)
|
|||
return NS_ERROR_FAILURE;
|
||||
|
||||
FlavorFlags ignored;
|
||||
char foundFlavor = ::GetFlavorFlags(mDragRef, currItem, macFlavor, &ignored) == noErr;
|
||||
if ( foundFlavor )
|
||||
if ( ::GetFlavorFlags(mDragRef, currItem, macFlavor, &ignored) == noErr )
|
||||
*_retval = PR_TRUE;
|
||||
else {
|
||||
// if the client asked for unicode and it wasn't present, check if we have TEXT.
|
||||
// We'll handle the actual data substitution in GetDataForFlavor().
|
||||
if ( strcmp(aDataFlavor, kUnicodeMime) == 0 ) {
|
||||
if ( ::GetFlavorFlags(mDragRef, currItem, 'TEXT', &ignored) == noErr )
|
||||
*_retval = PR_TRUE;
|
||||
}
|
||||
}
|
||||
} // for each item in drag
|
||||
|
||||
return NS_OK;
|
||||
|
@ -566,10 +584,15 @@ nsDragService :: GetDataForFlavor ( nsISupportsArray* inDragItems, DragReference
|
|||
// Caller is responsible for deleting the memory.
|
||||
//
|
||||
char*
|
||||
nsDragService :: LookupMimeMappingsForItem ( DragReference inDragRef, ItemReference itemRef )
|
||||
nsDragService :: LookupMimeMappingsForItem ( DragReference inDragRef, ItemReference inItemRef )
|
||||
{
|
||||
char* mapperData = nsnull;
|
||||
Size mapperSize = 0;
|
||||
PRInt32 mapperSize = 0;
|
||||
ExtractDataFromOS(inDragRef, inItemRef, nsMimeMapperMac::MappingFlavor(), &mapperData, &mapperSize);
|
||||
|
||||
return mapperData;
|
||||
|
||||
#if 0
|
||||
OSErr err = ::GetFlavorDataSize ( inDragRef, itemRef, nsMimeMapperMac::MappingFlavor(), &mapperSize );
|
||||
if ( !err && mapperSize > 0 ) {
|
||||
mapperData = NS_REINTERPRET_CAST(char*, nsAllocator::Alloc(mapperSize + 1));
|
||||
|
@ -587,6 +610,51 @@ nsDragService :: LookupMimeMappingsForItem ( DragReference inDragRef, ItemRefere
|
|||
mapperData[mapperSize] = '\0'; // null terminate the data
|
||||
}
|
||||
|
||||
return mapperData;
|
||||
return mapperData;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ExtractDataFromOS
|
||||
//
|
||||
// Handles pulling the data from the DragManager. Will return NS_ERROR_FAILURE if it can't get
|
||||
// the data for whatever reason.
|
||||
//
|
||||
nsresult
|
||||
nsDragService :: ExtractDataFromOS ( DragReference inDragRef, ItemReference inItemRef, ResType inFlavor,
|
||||
void** outBuffer, PRInt32* outBuffSize )
|
||||
{
|
||||
if ( !outBuffer || !outBuffSize || !inFlavor )
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult retval = NS_OK;
|
||||
char* buff = nsnull;
|
||||
Size buffSize = 0;
|
||||
OSErr err = ::GetFlavorDataSize ( inDragRef, inItemRef, inFlavor, &buffSize );
|
||||
if ( !err && buffSize > 0 ) {
|
||||
buff = NS_REINTERPRET_CAST(char*, nsAllocator::Alloc(buffSize + 1));
|
||||
if ( buff ) {
|
||||
err = ::GetFlavorData ( inDragRef, inItemRef, inFlavor, buff, &buffSize, 0 );
|
||||
if ( err ) {
|
||||
#ifdef NS_DEBUG
|
||||
printf("nsDragService: Error getting data out of drag manager, #%ld\n", err);
|
||||
#endif
|
||||
retval = NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
retval = NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if ( NS_FAILED(retval) ) {
|
||||
if ( buff )
|
||||
nsAllocator::Free(buff);
|
||||
}
|
||||
else {
|
||||
*outBuffer = buff;
|
||||
*outBuffSize = buffSize;
|
||||
}
|
||||
return retval;
|
||||
|
||||
} // ExtractDataFromOS
|
||||
|
|
|
@ -70,6 +70,8 @@ private:
|
|||
void BuildDragRegion ( nsIScriptableRegion* inRegion, Point inGlobalMouseLoc, RgnHandle ioDragRgn ) ;
|
||||
OSErr GetDataForFlavor ( nsISupportsArray* inDragItems, DragReference inDragRef, unsigned int inItemIndex,
|
||||
FlavorType inFlavor, void** outData, unsigned int * outSize ) ;
|
||||
nsresult ExtractDataFromOS ( DragReference inDragRef, ItemReference inItemRef, ResType inFlavor,
|
||||
void** outBuffer, PRInt32* outBuffSize ) ;
|
||||
|
||||
// callback for the MacOS DragManager when a drop site asks for data
|
||||
static pascal OSErr DragSendDataProc ( FlavorType inFlavor, void* inRefCon,
|
||||
|
|
|
@ -566,18 +566,38 @@ nsresult nsClipboard::GetDataFromDataObject(IDataObject * aDataObject,
|
|||
|
||||
void * data;
|
||||
PRUint32 dataLen;
|
||||
PRBool success = PR_FALSE;
|
||||
|
||||
PRBool dataFound = PR_FALSE;
|
||||
if (nsnull != aDataObject) {
|
||||
if ( NS_SUCCEEDED(GetNativeDataOffClipboard(aDataObject, format, &data, &dataLen)) )
|
||||
success = PR_TRUE;
|
||||
dataFound = PR_TRUE;
|
||||
}
|
||||
else if (nsnull != aWindow) {
|
||||
if ( NS_SUCCEEDED(GetNativeDataOffClipboard(aWindow, format, &data, &dataLen)) )
|
||||
success = PR_TRUE;
|
||||
dataFound = PR_TRUE;
|
||||
}
|
||||
if ( !dataFound ) {
|
||||
// if we are looking for text/unicode and we fail to find it on the clipboard first,
|
||||
// try again with text/plain. If that is present, convert it to unicode.
|
||||
if ( strcmp(flavorStr, kUnicodeMime) == 0 ) {
|
||||
nsresult loadResult = GetNativeDataOffClipboard(aDataObject, GetFormat(kTextMime), &data, &dataLen);
|
||||
if ( NS_SUCCEEDED(loadResult) && data ) {
|
||||
const char* castedText = NS_REINTERPRET_CAST(char*, data);
|
||||
PRUnichar* convertedText = nsnull;
|
||||
PRInt32 convertedTextLen = 0;
|
||||
nsPrimitiveHelpers::ConvertPlatformPlainTextToUnicode ( castedText, dataLen,
|
||||
&convertedText, &convertedTextLen );
|
||||
if ( convertedText ) {
|
||||
// out with the old, in with the new
|
||||
nsAllocator::Free(data);
|
||||
data = convertedText;
|
||||
dataLen = convertedTextLen * 2;
|
||||
dataFound = PR_TRUE;
|
||||
}
|
||||
} // if plain text data on clipboard
|
||||
} // if looking for text/unicode
|
||||
} // if we try one last ditch effort to find our data
|
||||
|
||||
if ( success ) {
|
||||
if ( dataFound ) {
|
||||
// the DOM only wants LF, so convert from Win32 line endings to DOM line
|
||||
// endings.
|
||||
PRInt32 signedLen = NS_STATIC_CAST(PRInt32, dataLen);
|
||||
|
@ -589,6 +609,8 @@ nsresult nsClipboard::GetDataFromDataObject(IDataObject * aDataObject,
|
|||
aTransferable->SetTransferData(flavorStr, genericDataWrapper, dataLen);
|
||||
|
||||
nsAllocator::Free ( NS_REINTERPRET_CAST(char*, data) );
|
||||
|
||||
res = NS_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -714,22 +736,34 @@ NS_IMETHODIMP nsClipboard::HasDataMatchingFlavors(nsISupportsArray *aFlavorList,
|
|||
{
|
||||
*_retval = PR_FALSE;
|
||||
|
||||
PRUint32 i;
|
||||
PRUint32 cnt;
|
||||
|
||||
aFlavorList->Count(&cnt);
|
||||
for (i = 0;i < cnt; i++) {
|
||||
for (PRUint32 i = 0;i < cnt; i++) {
|
||||
nsCOMPtr<nsISupports> genericFlavor;
|
||||
aFlavorList->GetElementAt (i, getter_AddRefs(genericFlavor));
|
||||
nsCOMPtr<nsISupportsString> currentFlavor (do_QueryInterface(genericFlavor));
|
||||
if (currentFlavor) {
|
||||
nsXPIDLCString flavorStr;
|
||||
currentFlavor->ToString(getter_Copies(flavorStr));
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
if ( strcmp(flavorStr, kTextMime) == 0 )
|
||||
NS_WARNING ( "DO NOT USE THE text/plain DATA FLAVOR ANY MORE. USE text/unicode INSTEAD" );
|
||||
#endif
|
||||
|
||||
UINT format = GetFormat(flavorStr);
|
||||
if (::IsClipboardFormatAvailable(format)) {
|
||||
*_retval = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
// if the client asked for unicode and it wasn't present, check if we have CF_TEXT.
|
||||
// We'll handle the actual data substitution in the data object.
|
||||
if ( strcmp(flavorStr, kUnicodeMime) == 0 ) {
|
||||
if ( ::IsClipboardFormatAvailable(GetFormat(kTextMime)) )
|
||||
*_retval = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -213,7 +213,7 @@ STDMETHODIMP nsDataObj::QueryGetData(LPFORMATETC pFE)
|
|||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PRNTDEBUG2("***** nsDataObj::QueryGetData - Unknown format %d\n", pFE->cfFormat);
|
||||
return ResultFromScode(E_FAIL);
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ nsDataObjCollection::~nsDataObjCollection()
|
|||
delete df;
|
||||
}
|
||||
delete mDataFlavors;
|
||||
|
||||
|
||||
for (i=0;i<mDataObjects->Count();i++) {
|
||||
IDataObject * dataObj = (IDataObject *)mDataObjects->ElementAt(i);
|
||||
NS_RELEASE(dataObj);
|
||||
|
|
|
@ -33,12 +33,30 @@ class nsITransferable;
|
|||
|
||||
#define MULTI_MIME "Mozilla/IDataObjectCollectionFormat"
|
||||
|
||||
#if NOT_YET
|
||||
// {6e99c280-d820-11d3-bb6f-bbf26bfe623c}
|
||||
EXTERN_C GUID CDECL IID_DATA_OBJ_COLLECTION =
|
||||
{ 0x6e99c280, 0xd820, 0x11d3, { 0xbb, 0x6f, 0xbb, 0xf2, 0x6b, 0xfe, 0x62, 0x3c } };
|
||||
|
||||
|
||||
class nsPIDataObjCollection : IUnknown
|
||||
{
|
||||
public:
|
||||
|
||||
STDMETHODIMP AddDataObject(IDataObject * aDataObj) = 0;
|
||||
STDMETHODIMP GetNumDataObjects(PRInt32* outNum) = 0;
|
||||
STDMETHODIMP GetDataObjectAt(PRUint32 aItem, IDataObject** outItem) = 0;
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This ole registered class is used to facilitate drag-drop of objects which
|
||||
* can be adapted by an object derived from CfDragDrop. The CfDragDrop is
|
||||
* associated with instances via SetDragDrop().
|
||||
*/
|
||||
class nsDataObjCollection : public IDataObject
|
||||
|
||||
class nsDataObjCollection : public IDataObject //, public nsPIDataObjCollection
|
||||
{
|
||||
public: // construction, destruction
|
||||
nsDataObjCollection();
|
||||
|
@ -65,10 +83,17 @@ class nsDataObjCollection : public IDataObject
|
|||
void AddDataFlavor(nsString * aDataFlavor, LPFORMATETC aFE);
|
||||
void SetTransferable(nsITransferable * aTransferable);
|
||||
|
||||
#if NOT_YET
|
||||
// from nsPIDataObjCollection
|
||||
STDMETHODIMP AddDataObject(IDataObject * aDataObj);
|
||||
STDMETHODIMP GetNumDataObjects(PRInt32* outNum) { *outNum = mDataObjects->Count(); }
|
||||
STDMETHODIMP GetDataObjectAt(PRUint32 aItem, IDataObject** outItem) { *outItem = (IDataObject *)mDataObjects->ElementAt(aItem); }
|
||||
#endif
|
||||
|
||||
// from nsPIDataObjCollection
|
||||
void AddDataObject(IDataObject * aDataObj);
|
||||
PRInt32 GetNumDataObjects() { return mDataObjects->Count(); }
|
||||
IDataObject * GetDataObjectAt(PRUint32 aItem) { return (IDataObject *)mDataObjects->ElementAt(aItem); }
|
||||
|
||||
IDataObject* GetDataObjectAt(PRUint32 aItem) { return (IDataObject *)mDataObjects->ElementAt(aItem); }
|
||||
|
||||
// Return the registered OLE class ID of this object's CfDataObj.
|
||||
CLSID GetClassID() const;
|
||||
|
|
|
@ -143,8 +143,9 @@ NS_IMETHODIMP nsDragService::GetNumDropItems (PRUint32 * aNumItems)
|
|||
}
|
||||
|
||||
// If it is the get the number of items in the collection
|
||||
nsDataObjCollection * dataObjCol = (nsDataObjCollection *)mDataObject;
|
||||
*aNumItems = (PRUint32)dataObjCol->GetNumDataObjects();
|
||||
nsDataObjCollection * dataObjCol = NS_STATIC_CAST(nsDataObjCollection*, mDataObject);
|
||||
if ( dataObjCol )
|
||||
*aNumItems = dataObjCol->GetNumDataObjects();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -173,14 +174,15 @@ NS_IMETHODIMP nsDragService::GetData (nsITransferable * aTransferable, PRUint32
|
|||
}
|
||||
}
|
||||
|
||||
// If it is a collection of objects then get the data for the specified index
|
||||
nsDataObjCollection * dataObjCol = (nsDataObjCollection *)mDataObject;
|
||||
PRUint32 cnt = dataObjCol->GetNumDataObjects();
|
||||
if (anItem >= 0 && anItem < cnt) {
|
||||
IDataObject * dataObj = dataObjCol->GetDataObjectAt(anItem);
|
||||
return nsClipboard::GetDataFromDataObject(dataObj, nsnull, aTransferable);
|
||||
nsDataObjCollection * dataObjCol = NS_STATIC_CAST(nsDataObjCollection*, mDataObject);
|
||||
if ( dataObjCol ) {
|
||||
PRUint32 cnt = dataObjCol->GetNumDataObjects();
|
||||
if (anItem >= 0 && anItem < cnt) {
|
||||
IDataObject * dataObj = dataObjCol->GetDataObjectAt(anItem);
|
||||
return nsClipboard::GetDataFromDataObject(dataObj, nsnull, aTransferable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -202,35 +204,50 @@ NS_IMETHODIMP nsDragService::IsDataFlavorSupported(const char *aDataFlavor, PRBo
|
|||
if ( !aDataFlavor || !mDataObject || !_retval )
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// First check to see if the mDataObject is is Collection of IDataObjects
|
||||
#ifdef NS_DEBUG
|
||||
if ( strcmp(aDataFlavor, kTextMime) == 0 )
|
||||
NS_WARNING ( "DO NOT USE THE text/plain DATA FLAVOR ANY MORE. USE text/unicode INSTEAD" );
|
||||
#endif
|
||||
|
||||
*_retval = PR_FALSE;
|
||||
UINT format = nsClipboard::GetFormat(MULTI_MIME);
|
||||
|
||||
// Check to see if the mDataObject is a collection of IDataObjects or just a
|
||||
// single (which would be the case if something came from an external app).
|
||||
FORMATETC fe;
|
||||
UINT format = nsClipboard::GetFormat(MULTI_MIME);
|
||||
SET_FORMATETC(fe, format, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
|
||||
|
||||
if (S_OK != mDataObject->QueryGetData(&fe)) {
|
||||
// Ok, so we have a single object
|
||||
// now check to see if has the correct data type
|
||||
if ( mDataObject->QueryGetData(&fe) == S_OK ) {
|
||||
// We know we have one of our special collection objects.
|
||||
format = nsClipboard::GetFormat(aDataFlavor);
|
||||
SET_FORMATETC(fe, format, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL | TYMED_FILE | TYMED_GDI);
|
||||
|
||||
if (S_OK == mDataObject->QueryGetData(&fe))
|
||||
*_retval = PR_TRUE;;
|
||||
}
|
||||
|
||||
// Set it up for the data flavor
|
||||
format = nsClipboard::GetFormat(aDataFlavor);
|
||||
SET_FORMATETC(fe, format, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL | TYMED_FILE | TYMED_GDI);
|
||||
|
||||
// Ok, now see if any one of the IDataObjects in the collection
|
||||
// supports this data type
|
||||
nsDataObjCollection * dataObjCol = (nsDataObjCollection *)mDataObject;
|
||||
PRUint32 i;
|
||||
PRUint32 cnt = dataObjCol->GetNumDataObjects();
|
||||
for (i=0;i<cnt;i++) {
|
||||
IDataObject * dataObj = dataObjCol->GetDataObjectAt(i);
|
||||
if (S_OK == dataObj->QueryGetData(&fe))
|
||||
*_retval = PR_TRUE;
|
||||
// See if any one of the IDataObjects in the collection supports this data type
|
||||
nsDataObjCollection* dataObjCol = NS_STATIC_CAST(nsDataObjCollection*, mDataObject);
|
||||
if ( dataObjCol ) {
|
||||
PRUint32 cnt = dataObjCol->GetNumDataObjects();
|
||||
for (PRUint32 i=0;i<cnt;++i) {
|
||||
IDataObject * dataObj = dataObjCol->GetDataObjectAt(i);
|
||||
if (S_OK == dataObj->QueryGetData(&fe))
|
||||
*_retval = PR_TRUE; // found it!
|
||||
}
|
||||
}
|
||||
} // if special collection object
|
||||
else {
|
||||
// Ok, so we have a single object. Check to see if has the correct data type. Since
|
||||
// this can come from an outside app, we also need to see if we need to perform
|
||||
// text->unicode conversion if the client asked for unicode and it wasn't available.
|
||||
format = nsClipboard::GetFormat(aDataFlavor);
|
||||
SET_FORMATETC(fe, format, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL | TYMED_FILE | TYMED_GDI);
|
||||
if ( mDataObject->QueryGetData(&fe) == S_OK )
|
||||
*_retval = PR_TRUE; // found it!
|
||||
else {
|
||||
// try again, this time looking for plain text.
|
||||
format = nsClipboard::GetFormat(kTextMime);
|
||||
SET_FORMATETC(fe, format, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL | TYMED_FILE | TYMED_GDI);
|
||||
if ( mDataObject->QueryGetData(&fe) == S_OK )
|
||||
*_retval = PR_TRUE; // found it!
|
||||
} // else try again
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -165,7 +165,7 @@ nsPrimitiveHelpers :: ConvertUnicodeToPlatformPlainText ( PRUnichar* inUnicode,
|
|||
// the conversion.
|
||||
encoder->GetMaxLength(inUnicode, inUnicodeLen, outPlainTextLen);
|
||||
if ( *outPlainTextLen ) {
|
||||
*outPlainTextData = NS_REINTERPRET_CAST(char*, nsAllocator::Alloc(*outPlainTextLen + 1));
|
||||
*outPlainTextData = NS_REINTERPRET_CAST(char*, nsAllocator::Alloc(*outPlainTextLen + sizeof(char)));
|
||||
if ( *outPlainTextData ) {
|
||||
rv = encoder->Convert(inUnicode, &inUnicodeLen, *outPlainTextData, outPlainTextLen);
|
||||
(*outPlainTextData)[*outPlainTextLen] = '\0'; // null terminate. Convert() doesn't do it for us
|
||||
|
@ -177,6 +177,61 @@ nsPrimitiveHelpers :: ConvertUnicodeToPlatformPlainText ( PRUnichar* inUnicode,
|
|||
} // ConvertUnicodeToPlatformPlainText
|
||||
|
||||
|
||||
//
|
||||
// ConvertPlatformPlainTextToUnicode
|
||||
//
|
||||
// Given a char buffer (flavor text/plaikn), this converts it to unicode using
|
||||
// the appropriate platform charset encoding. |outUnicode| is null terminated,
|
||||
// but its length parameter, |outUnicodeLen|, does not reflect that. |outUnicodeLen| is
|
||||
// the length of the string in characters, not bytes.
|
||||
//
|
||||
void
|
||||
nsPrimitiveHelpers :: ConvertPlatformPlainTextToUnicode ( const char* inText, PRInt32 inTextLen,
|
||||
PRUnichar** outUnicode, PRInt32* outUnicodeLen )
|
||||
{
|
||||
if ( !outUnicode || !outUnicodeLen )
|
||||
return;
|
||||
|
||||
// Get the appropriate unicode decoder. We're guaranteed that this won't change
|
||||
// through the life of the app so we can cache it.
|
||||
nsresult rv;
|
||||
static nsCOMPtr<nsIUnicodeDecoder> decoder;
|
||||
static PRBool hasConverter = PR_FALSE;
|
||||
if ( !hasConverter ) {
|
||||
// get the charset
|
||||
nsCOMPtr <nsIPlatformCharset> platformCharsetService;
|
||||
nsAutoString platformCharset;
|
||||
nsresult res = nsComponentManager::CreateInstance(NS_PLATFORMCHARSET_PROGID, nsnull,
|
||||
NS_GET_IID(nsIPlatformCharset),
|
||||
getter_AddRefs(platformCharsetService));
|
||||
if (NS_SUCCEEDED(res))
|
||||
res = platformCharsetService->GetCharset(kPlatformCharsetSel_PlainTextInClipboard, platformCharset);
|
||||
if (NS_FAILED(res))
|
||||
platformCharset.SetString("ISO-8859-1");
|
||||
|
||||
// get the decoder
|
||||
NS_WITH_SERVICE(nsICharsetConverterManager, ccm, NS_CHARSETCONVERTERMANAGER_PROGID, &rv);
|
||||
rv = ccm->GetUnicodeDecoder(&platformCharset, getter_AddRefs(decoder));
|
||||
|
||||
hasConverter = PR_TRUE;
|
||||
}
|
||||
|
||||
// Estimate out length and allocate the buffer based on a worst-case estimate, then do
|
||||
// the conversion.
|
||||
decoder->GetMaxLength(inText, inTextLen, outUnicodeLen); // |outUnicodeLen| is number of chars
|
||||
if ( *outUnicodeLen ) {
|
||||
*outUnicode = NS_REINTERPRET_CAST(PRUnichar*, nsAllocator::Alloc((*outUnicodeLen + 1) * sizeof(PRUnichar)));
|
||||
if ( *outUnicode ) {
|
||||
rv = decoder->Convert(inText, &inTextLen, *outUnicode, outUnicodeLen);
|
||||
(*outUnicode)[*outUnicodeLen] = '\0'; // null terminate. Convert() doesn't do it for us
|
||||
}
|
||||
} // if valid length
|
||||
|
||||
NS_ASSERTION ( NS_SUCCEEDED(rv), "Error converting plain text to unicode" );
|
||||
|
||||
} // ConvertPlatformPlainTextToUnicode
|
||||
|
||||
|
||||
#ifdef XP_MAC
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
|
|
@ -48,11 +48,18 @@ public:
|
|||
|
||||
// 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,
|
||||
// string, not the # of bytes in the buffer. |outPlainTextData| is null terminated,
|
||||
// but its length parameter, |outPlainTextLen|, does not reflect that.
|
||||
static void ConvertUnicodeToPlatformPlainText ( PRUnichar* inUnicode, PRInt32 inUnicodeLen,
|
||||
char** outPlainTextData, PRInt32* outPlainTextLen ) ;
|
||||
|
||||
// Given a char buffer (flavor text/plaikn), this converts it to unicode using
|
||||
// the appropriate platform charset encoding. |outUnicode| is null terminated,
|
||||
// but its length parameter, |outUnicodeLen|, does not reflect that. |outUnicodeLen| is
|
||||
// the length of the string in characters, not bytes.
|
||||
static void ConvertPlatformPlainTextToUnicode ( const char* inText, PRInt32 inTextLen,
|
||||
PRUnichar** outUnicode, PRInt32* outUnicodeLen ) ;
|
||||
|
||||
}; // class nsPrimitiveHelpers
|
||||
|
||||
|
||||
|
|
|
@ -44,7 +44,6 @@ catch (ex) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
function GeneralDrag ( event )
|
||||
{
|
||||
if ( !gDragDropEnabled )
|
||||
|
@ -95,14 +94,14 @@ function BeginDragPersonalToolbar ( event )
|
|||
trans.addDataFlavor("moz/toolbaritem");
|
||||
var genData =
|
||||
Components.classes["component://netscape/supports-wstring"].createInstance(Components.interfaces.nsISupportsWString);
|
||||
trans.addDataFlavor("text/plain");
|
||||
trans.addDataFlavor("text/unicode");
|
||||
var genTextData =
|
||||
Components.classes["component://netscape/supports-string"].createInstance(Components.interfaces.nsISupportsString);
|
||||
Components.classes["component://netscape/supports-wstring"].createInstance(Components.interfaces.nsISupportsWString);
|
||||
if ( genData && genTextData ) {
|
||||
|
||||
var id = event.target.getAttribute("id");
|
||||
genData.data = id;
|
||||
genTextData.data = id;
|
||||
genTextData.data = id;
|
||||
|
||||
dump("ID: " + id + "\n");
|
||||
|
||||
|
@ -130,7 +129,7 @@ this doesn't work anymore (target is null), not sure why.
|
|||
*/
|
||||
|
||||
trans.setTransferData ( "moz/toolbaritem", genData, id.length*2 ); // double byte data (len*2)
|
||||
trans.setTransferData ( "text/plain", genTextData, id.length ); // single byte data
|
||||
trans.setTransferData ( "text/unicode", genTextData, id.length*2 ); // double byte data
|
||||
var transArray =
|
||||
Components.classes["component://netscape/supports-array"].createInstance(Components.interfaces.nsISupportsArray);
|
||||
if ( transArray ) {
|
||||
|
@ -254,7 +253,7 @@ function DragOverPersonalToolbar ( event )
|
|||
if ( dragSession ) {
|
||||
if ( dragSession.isDataFlavorSupported("moz/toolbaritem") )
|
||||
validFlavor = true;
|
||||
else if ( dragSession.isDataFlavorSupported("text/plain") )
|
||||
else if ( dragSession.isDataFlavorSupported("text/unicode") )
|
||||
validFlavor = true;
|
||||
//XXX other flavors here...
|
||||
|
||||
|
@ -280,9 +279,6 @@ function DragOverPersonalToolbar ( event )
|
|||
//
|
||||
function DragOverContentArea ( event )
|
||||
{
|
||||
if ( !gDragDropEnabled )
|
||||
return;
|
||||
|
||||
var validFlavor = false;
|
||||
var dragSession = null;
|
||||
|
||||
|
@ -293,8 +289,6 @@ function DragOverContentArea ( event )
|
|||
if ( dragSession ) {
|
||||
if ( dragSession.isDataFlavorSupported("moz/toolbaritem") )
|
||||
validFlavor = true;
|
||||
else if ( dragSession.isDataFlavorSupported("text/plain") )
|
||||
validFlavor = true;
|
||||
else if ( dragSession.isDataFlavorSupported("text/unicode") )
|
||||
validFlavor = true;
|
||||
//XXX other flavors here...such as files from the desktop?
|
||||
|
@ -319,9 +313,6 @@ function DragOverContentArea ( event )
|
|||
//
|
||||
function DropOnContentArea ( event )
|
||||
{
|
||||
if ( !gDragDropEnabled )
|
||||
return;
|
||||
|
||||
var dropAccepted = false;
|
||||
|
||||
var dragService =
|
||||
|
@ -333,7 +324,6 @@ function DropOnContentArea ( event )
|
|||
Components.classes["component://netscape/widget/transferable"].createInstance(Components.interfaces.nsITransferable);
|
||||
if ( trans ) {
|
||||
trans.addDataFlavor("text/unicode");
|
||||
trans.addDataFlavor("text/plain");
|
||||
for ( var i = 0; i < dragSession.numDropItems; ++i ) {
|
||||
var id = "";
|
||||
dragSession.getData ( trans, i );
|
||||
|
@ -349,14 +339,6 @@ function DropOnContentArea ( event )
|
|||
dump("ID: '" + id + "'\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( dataObj ) dataObj = dataObj.value.QueryInterface(Components.interfaces.nsISupportsString);
|
||||
if ( dataObj ) {
|
||||
// pull the URL out of the data object
|
||||
var id = dataObj.data.substring(0, len.value);
|
||||
dump("ID: '" + id + "'\n");
|
||||
}
|
||||
}
|
||||
|
||||
// stuff it into the url field and go, baby, go!
|
||||
var urlBar = document.getElementById ( "urlbar" );
|
||||
|
@ -382,9 +364,6 @@ function DropOnContentArea ( event )
|
|||
//
|
||||
function DragProxyIcon ( event )
|
||||
{
|
||||
if ( !gDragDropEnabled )
|
||||
return;
|
||||
|
||||
var dragStarted = false;
|
||||
var dragService =
|
||||
Components.classes["component://netscape/widget/dragservice"].getService(Components.interfaces.nsIDragService);
|
||||
|
@ -392,9 +371,9 @@ function DragProxyIcon ( event )
|
|||
var trans =
|
||||
Components.classes["component://netscape/widget/transferable"].createInstance(Components.interfaces.nsITransferable);
|
||||
if ( trans ) {
|
||||
trans.addDataFlavor("text/plain");
|
||||
trans.addDataFlavor("text/unicode");
|
||||
var genTextData =
|
||||
Components.classes["component://netscape/supports-string"].createInstance(Components.interfaces.nsISupportsString);
|
||||
Components.classes["component://netscape/supports-wstring"].createInstance(Components.interfaces.nsISupportsWString);
|
||||
if ( genTextData ) {
|
||||
|
||||
// pull the url out of the url bar
|
||||
|
@ -406,7 +385,7 @@ function DragProxyIcon ( event )
|
|||
|
||||
dump("ID: " + id + "\n");
|
||||
|
||||
trans.setTransferData ( "text/plain", genTextData, id.length ); // single byte data
|
||||
trans.setTransferData ( "text/unicode", genTextData, id.length * 2 ); // double byte data
|
||||
var transArray =
|
||||
Components.classes["component://netscape/supports-array"].createInstance(Components.interfaces.nsISupportsArray);
|
||||
if ( transArray ) {
|
||||
|
|
|
@ -383,13 +383,13 @@ nsContextMenu.prototype = {
|
|||
.classes["component://netscape/widget/transferable"]
|
||||
.createInstance( Components.interfaces.nsITransferable );
|
||||
if ( clipboard && transferable ) {
|
||||
transferable.addDataFlavor( "text/plain" );
|
||||
transferable.addDataFlavor( "text/unicode" );
|
||||
// Create wrapper for text.
|
||||
var data = createInstance( "component://netscape/supports-string",
|
||||
"nsISupportsString" );
|
||||
var data = createInstance( "component://netscape/supports-wstring",
|
||||
"nsISupportsWString" );
|
||||
if ( data ) {
|
||||
data.data = text ;
|
||||
transferable.setTransferData( "text/plain", data, text.length );
|
||||
transferable.setTransferData( "text/unicode", data, text.length * 2 );
|
||||
// Put on clipboard.
|
||||
clipboard.setData( transferable, null );
|
||||
}
|
||||
|
|
|
@ -84,11 +84,7 @@ function BeginDragTree ( event )
|
|||
Components.classes["component://netscape/supports-wstring"].createInstance(Components.interfaces.nsISupportsWString);
|
||||
if (!genData) return(false);
|
||||
|
||||
var genTextData =
|
||||
Components.classes["component://netscape/supports-string"].createInstance(Components.interfaces.nsISupportsString);
|
||||
if (!genTextData) return(false);
|
||||
|
||||
trans.addDataFlavor("text/plain");
|
||||
trans.addDataFlavor("text/unicode");
|
||||
|
||||
// id (url) is on the <treeitem> which is two levels above the <treecell> which is
|
||||
// the target of the event.
|
||||
|
@ -118,7 +114,7 @@ function BeginDragTree ( event )
|
|||
|
||||
|
||||
// trans.setTransferData ( "moz/toolbaritem", genData, id.length*2 ); // double byte data (len*2)
|
||||
trans.setTransferData ( "text/plain", genTextData, id.length ); // single byte data
|
||||
trans.setTransferData ( "text/unicode", genData, id.length * 2); // double byte data
|
||||
|
||||
var transArray =
|
||||
Components.classes["component://netscape/supports-array"].createInstance(Components.interfaces.nsISupportsArray);
|
||||
|
@ -154,7 +150,7 @@ function DragOverTree ( event )
|
|||
if ( !dragSession ) return(false);
|
||||
|
||||
if ( dragSession.isDataFlavorSupported("moz/toolbaritem") ) validFlavor = true;
|
||||
else if ( dragSession.isDataFlavorSupported("text/plain") ) validFlavor = true;
|
||||
else if ( dragSession.isDataFlavorSupported("text/unicode") ) validFlavor = true;
|
||||
//XXX other flavors here...
|
||||
|
||||
// touch the attribute on the rowgroup to trigger the repaint with the drop feedback.
|
||||
|
@ -230,7 +226,7 @@ function DropOnTree ( event )
|
|||
var trans =
|
||||
Components.classes["component://netscape/widget/transferable"].createInstance(Components.interfaces.nsITransferable);
|
||||
if ( !trans ) return(false);
|
||||
trans.addDataFlavor("text/plain");
|
||||
trans.addDataFlavor("text/unicode");
|
||||
|
||||
var dirty = false;
|
||||
|
||||
|
@ -241,11 +237,11 @@ function DropOnTree ( event )
|
|||
var bestFlavor = new Object();
|
||||
var len = new Object();
|
||||
trans.getAnyTransferData ( bestFlavor, dataObj, len );
|
||||
if ( dataObj ) dataObj = dataObj.value.QueryInterface(Components.interfaces.nsISupportsString);
|
||||
if ( dataObj ) dataObj = dataObj.value.QueryInterface(Components.interfaces.nsISupportsWString);
|
||||
if ( !dataObj ) continue;
|
||||
|
||||
// pull the URL out of the data object
|
||||
var sourceID = dataObj.data.substring(0, len.value);
|
||||
var sourceID = dataObj.data;
|
||||
if (!sourceID) continue;
|
||||
|
||||
debug(" Node #" + i + ": drop '" + sourceID + "' " + dropAction + " '" + targetID + "'");
|
||||
|
|
Загрузка…
Ссылка в новой задаче