зеркало из https://github.com/mozilla/gecko-dev.git
share more code between clipboard and drag services. original patch by Colin Barrett, more clean up by me. b=358094 r=cbarrett sr=roc
This commit is contained in:
Родитель
11cb6cb594
Коммит
37ee900e61
|
@ -41,6 +41,8 @@
|
||||||
|
|
||||||
#include "nsBaseClipboard.h"
|
#include "nsBaseClipboard.h"
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
class nsITransferable;
|
class nsITransferable;
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,6 +56,10 @@ public:
|
||||||
// nsIClipboard
|
// nsIClipboard
|
||||||
NS_IMETHOD HasDataMatchingFlavors(nsISupportsArray *aFlavorList, PRInt32 aWhichClipboard, PRBool *_retval);
|
NS_IMETHOD HasDataMatchingFlavors(nsISupportsArray *aFlavorList, PRInt32 aWhichClipboard, PRBool *_retval);
|
||||||
|
|
||||||
|
// Helper methods, used also by nsDragService
|
||||||
|
static NSDictionary* PasteboardDictFromTransferable(nsITransferable *aTransferable);
|
||||||
|
static nsresult CopyPasteboardDataToTransferable(NSPasteboard* aPasteboard, nsITransferable* aTransferable, PRUint32 aItemIndex);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// impelement the native clipboard behavior
|
// impelement the native clipboard behavior
|
||||||
|
|
|
@ -46,8 +46,7 @@
|
||||||
#include "nsPrimitiveHelpers.h"
|
#include "nsPrimitiveHelpers.h"
|
||||||
#include "nsMemory.h"
|
#include "nsMemory.h"
|
||||||
#include "nsIImage.h"
|
#include "nsIImage.h"
|
||||||
|
#include "nsILocalFile.h"
|
||||||
#import <Cocoa/Cocoa.h>
|
|
||||||
|
|
||||||
nsClipboard::nsClipboard() : nsBaseClipboard()
|
nsClipboard::nsClipboard() : nsBaseClipboard()
|
||||||
{
|
{
|
||||||
|
@ -67,12 +66,93 @@ nsClipboard::SetNativeClipboardData(PRInt32 aWhichClipboard)
|
||||||
|
|
||||||
mIgnoreEmptyNotification = PR_TRUE;
|
mIgnoreEmptyNotification = PR_TRUE;
|
||||||
|
|
||||||
NSMutableDictionary* pasteboardOutputDict = [NSMutableDictionary dictionaryWithCapacity:1];
|
NSDictionary* pasteboardOutputDict = PasteboardDictFromTransferable(mTransferable);
|
||||||
|
if (!pasteboardOutputDict)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// write everything out to the general pasteboard
|
||||||
|
unsigned int outputCount = [pasteboardOutputDict count];
|
||||||
|
NSArray* outputKeys = [pasteboardOutputDict allKeys];
|
||||||
|
NSPasteboard* generalPBoard = [NSPasteboard generalPasteboard];
|
||||||
|
[generalPBoard declareTypes:outputKeys owner:nil];
|
||||||
|
for (unsigned int i = 0; i < outputCount; i++) {
|
||||||
|
NSString* currentKey = [outputKeys objectAtIndex:i];
|
||||||
|
id currentValue = [pasteboardOutputDict valueForKey:currentKey];
|
||||||
|
if (currentKey == NSStringPboardType)
|
||||||
|
[generalPBoard setString:currentValue forType:currentKey];
|
||||||
|
else
|
||||||
|
[generalPBoard setData:currentValue forType:currentKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
mIgnoreEmptyNotification = PR_FALSE;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsClipboard::GetNativeClipboardData(nsITransferable* aTransferable, PRInt32 aWhichClipboard)
|
||||||
|
{
|
||||||
|
if ((aWhichClipboard != kGlobalClipboard) || !aTransferable)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
return CopyPasteboardDataToTransferable([NSPasteboard generalPasteboard], aTransferable, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsClipboard::HasDataMatchingFlavors(nsISupportsArray* aFlavorList, PRInt32 aWhichClipboard, PRBool* outResult)
|
||||||
|
{
|
||||||
|
*outResult = PR_FALSE;
|
||||||
|
|
||||||
|
if ((aWhichClipboard != kGlobalClipboard) || !aFlavorList)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
NSPasteboard* generalPBoard = [NSPasteboard generalPasteboard];
|
||||||
|
|
||||||
|
PRUint32 flavorCount;
|
||||||
|
aFlavorList->Count(&flavorCount);
|
||||||
|
for (PRUint32 i = 0; i < flavorCount; i++) {
|
||||||
|
nsCOMPtr<nsISupports> genericFlavor;
|
||||||
|
aFlavorList->GetElementAt(i, getter_AddRefs(genericFlavor));
|
||||||
|
nsCOMPtr<nsISupportsCString> flavorWrapper(do_QueryInterface(genericFlavor));
|
||||||
|
if (flavorWrapper) {
|
||||||
|
nsXPIDLCString flavorStr;
|
||||||
|
flavorWrapper->ToString(getter_Copies(flavorStr));
|
||||||
|
if (strcmp(flavorStr, kUnicodeMime) == 0) {
|
||||||
|
NSString* availableType = [generalPBoard availableTypeFromArray:[NSArray arrayWithObject:NSStringPboardType]];
|
||||||
|
if (availableType && [availableType isEqualToString:NSStringPboardType]) {
|
||||||
|
*outResult = PR_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
NSString* lookingForType = [NSString stringWithUTF8String:flavorStr];
|
||||||
|
NSString* availableType = [generalPBoard availableTypeFromArray:[NSArray arrayWithObject:lookingForType]];
|
||||||
|
if (availableType && [availableType isEqualToString:lookingForType]) {
|
||||||
|
*outResult = PR_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
NSDictionary*
|
||||||
|
nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTransferable)
|
||||||
|
{
|
||||||
|
if (!aTransferable)
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
NSMutableDictionary* pasteboardOutputDict = [NSMutableDictionary dictionary];
|
||||||
|
|
||||||
nsCOMPtr<nsISupportsArray> flavorList;
|
nsCOMPtr<nsISupportsArray> flavorList;
|
||||||
nsresult rv = mTransferable->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
|
nsresult rv = aTransferable->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return NS_ERROR_FAILURE;
|
return nil;
|
||||||
|
|
||||||
PRUint32 flavorCount;
|
PRUint32 flavorCount;
|
||||||
flavorList->Count(&flavorCount);
|
flavorList->Count(&flavorCount);
|
||||||
|
@ -92,7 +172,7 @@ nsClipboard::SetNativeClipboardData(PRInt32 aWhichClipboard)
|
||||||
strcmp(flavorStr, kGIFImageMime) == 0 || strcmp(flavorStr, kNativeImageMime) == 0) {
|
strcmp(flavorStr, kGIFImageMime) == 0 || strcmp(flavorStr, kNativeImageMime) == 0) {
|
||||||
PRUint32 dataSize = 0;
|
PRUint32 dataSize = 0;
|
||||||
nsCOMPtr<nsISupports> transferSupports;
|
nsCOMPtr<nsISupports> transferSupports;
|
||||||
mTransferable->GetTransferData(flavorStr, getter_AddRefs(transferSupports), &dataSize);
|
aTransferable->GetTransferData(flavorStr, getter_AddRefs(transferSupports), &dataSize);
|
||||||
nsCOMPtr<nsISupportsInterfacePointer> ptrPrimitive(do_QueryInterface(transferSupports));
|
nsCOMPtr<nsISupportsInterfacePointer> ptrPrimitive(do_QueryInterface(transferSupports));
|
||||||
if (!ptrPrimitive)
|
if (!ptrPrimitive)
|
||||||
continue;
|
continue;
|
||||||
|
@ -159,7 +239,7 @@ nsClipboard::SetNativeClipboardData(PRInt32 aWhichClipboard)
|
||||||
void* data = nsnull;
|
void* data = nsnull;
|
||||||
PRUint32 dataSize = 0;
|
PRUint32 dataSize = 0;
|
||||||
nsCOMPtr<nsISupports> genericDataWrapper;
|
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||||
rv = mTransferable->GetTransferData(flavorStr, getter_AddRefs(genericDataWrapper), &dataSize);
|
rv = aTransferable->GetTransferData(flavorStr, getter_AddRefs(genericDataWrapper), &dataSize);
|
||||||
nsPrimitiveHelpers::CreateDataFromPrimitive(flavorStr, genericDataWrapper, &data, dataSize);
|
nsPrimitiveHelpers::CreateDataFromPrimitive(flavorStr, genericDataWrapper, &data, dataSize);
|
||||||
|
|
||||||
// if it is kUnicodeMime, it is text we want to export as standard NSStringPboardType
|
// if it is kUnicodeMime, it is text we want to export as standard NSStringPboardType
|
||||||
|
@ -178,31 +258,15 @@ nsClipboard::SetNativeClipboardData(PRInt32 aWhichClipboard)
|
||||||
nsMemory::Free(data);
|
nsMemory::Free(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// write everything out to the general pasteboard
|
return pasteboardOutputDict;
|
||||||
unsigned int outputCount = [pasteboardOutputDict count];
|
|
||||||
NSArray* outputKeys = [pasteboardOutputDict allKeys];
|
|
||||||
NSPasteboard* generalPBoard = [NSPasteboard generalPasteboard];
|
|
||||||
[generalPBoard declareTypes:outputKeys owner:nil];
|
|
||||||
for (unsigned int i = 0; i < outputCount; i++) {
|
|
||||||
NSString* currentKey = [outputKeys objectAtIndex:i];
|
|
||||||
id currentValue = [pasteboardOutputDict valueForKey:currentKey];
|
|
||||||
if (currentKey == NSStringPboardType)
|
|
||||||
[generalPBoard setString:currentValue forType:currentKey];
|
|
||||||
else
|
|
||||||
[generalPBoard setData:currentValue forType:currentKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
mIgnoreEmptyNotification = PR_FALSE;
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
NS_IMETHODIMP
|
nsresult
|
||||||
nsClipboard::GetNativeClipboardData(nsITransferable * aTransferable, PRInt32 aWhichClipboard)
|
nsClipboard::CopyPasteboardDataToTransferable(NSPasteboard* aPasteboard, nsITransferable* aTransferable, PRUint32 aItemIndex)
|
||||||
{
|
{
|
||||||
if ((aWhichClipboard != kGlobalClipboard) || !aTransferable)
|
if (!aTransferable || !aPasteboard)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
// get flavor list that includes all acceptable flavors (including ones obtained through conversion)
|
// get flavor list that includes all acceptable flavors (including ones obtained through conversion)
|
||||||
|
@ -211,8 +275,6 @@ nsClipboard::GetNativeClipboardData(nsITransferable * aTransferable, PRInt32 aWh
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
NSPasteboard* generalPBoard = [NSPasteboard generalPasteboard];
|
|
||||||
|
|
||||||
PRUint32 flavorCount;
|
PRUint32 flavorCount;
|
||||||
flavorList->Count(&flavorCount);
|
flavorList->Count(&flavorCount);
|
||||||
for (PRUint32 i = 0; i < flavorCount; i++) {
|
for (PRUint32 i = 0; i < flavorCount; i++) {
|
||||||
|
@ -228,8 +290,35 @@ nsClipboard::GetNativeClipboardData(nsITransferable * aTransferable, PRInt32 aWh
|
||||||
|
|
||||||
// printf("looking for clipboard data of type %s\n", flavorStr.get());
|
// printf("looking for clipboard data of type %s\n", flavorStr.get());
|
||||||
|
|
||||||
if (strcmp(flavorStr, kUnicodeMime) == 0) {
|
if (strcmp(flavorStr, kFileMime) == 0) {
|
||||||
NSString* pString = [generalPBoard stringForType:NSStringPboardType];
|
NSArray* pFiles = [aPasteboard propertyListForType:NSFilenamesPboardType];
|
||||||
|
if (!pFiles || [pFiles count] < (aItemIndex + 1))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
NSString* filePath = [pFiles objectAtIndex:aItemIndex];
|
||||||
|
if (!filePath)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
unsigned int stringLength = [filePath length];
|
||||||
|
unsigned int dataLength = (stringLength + 1) * sizeof(PRUnichar); // in bytes
|
||||||
|
PRUnichar* clipboardDataPtr = (PRUnichar*)malloc(dataLength);
|
||||||
|
[filePath getCharacters:clipboardDataPtr];
|
||||||
|
clipboardDataPtr[stringLength] = 0; // null terminate
|
||||||
|
|
||||||
|
nsCOMPtr<nsILocalFile> file;
|
||||||
|
nsresult rv = NS_NewLocalFile(nsDependentString(clipboardDataPtr), PR_TRUE, getter_AddRefs(file));
|
||||||
|
free(clipboardDataPtr);
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||||
|
genericDataWrapper = do_QueryInterface(file);
|
||||||
|
aTransferable->SetTransferData(flavorStr, genericDataWrapper, dataLength);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (strcmp(flavorStr, kUnicodeMime) == 0) {
|
||||||
|
NSString* pString = [aPasteboard stringForType:NSStringPboardType];
|
||||||
if (!pString)
|
if (!pString)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -255,25 +344,26 @@ nsClipboard::GetNativeClipboardData(nsITransferable * aTransferable, PRInt32 aWh
|
||||||
getter_AddRefs(genericDataWrapper));
|
getter_AddRefs(genericDataWrapper));
|
||||||
aTransferable->SetTransferData(flavorStr, genericDataWrapper, dataLength);
|
aTransferable->SetTransferData(flavorStr, genericDataWrapper, dataLength);
|
||||||
free(clipboardDataPtr);
|
free(clipboardDataPtr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (strcmp(flavorStr, kPNGImageMime) == 0 || strcmp(flavorStr, kJPEGImageMime) == 0 ||
|
else if (strcmp(flavorStr, kPNGImageMime) == 0 || strcmp(flavorStr, kJPEGImageMime) == 0 ||
|
||||||
strcmp(flavorStr, kGIFImageMime) == 0) {
|
strcmp(flavorStr, kGIFImageMime) == 0) {
|
||||||
// We have never supported this on Mac, we could someday but nobody does this. We want this
|
// We have never supported this on Mac, we could someday but nobody does this. We want this
|
||||||
// test here so that we don't try to output this data as generic string data.
|
// test here so that we don't try to get this as a custom type.
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
NSData* pData = [generalPBoard dataForType:[NSString stringWithUTF8String:flavorStr]];
|
// this is some sort of data that mozilla put on the clipboard itself if it exists
|
||||||
|
NSData* pData = [aPasteboard dataForType:[NSString stringWithUTF8String:flavorStr]];
|
||||||
if (!pData)
|
if (!pData)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
unsigned int dataLength = [pData length];
|
unsigned int dataLength = [pData length];
|
||||||
unsigned char* clipboardDataPtr = (unsigned char*)malloc(dataLength);
|
unsigned char* clipboardDataPtr = (unsigned char*)malloc(dataLength);
|
||||||
[pData getBytes:(void*)clipboardDataPtr];
|
[pData getBytes:(void*)clipboardDataPtr];
|
||||||
|
|
||||||
// The DOM only wants LF, so convert from MacOS line endings to DOM line endings.
|
// The DOM only wants LF, so convert from MacOS line endings to DOM line endings.
|
||||||
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks(flavorStr, (void**)&clipboardDataPtr, (PRInt32*)&dataLength);
|
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks(flavorStr, (void**)&clipboardDataPtr, (PRInt32*)&dataLength);
|
||||||
|
|
||||||
nsCOMPtr<nsISupports> genericDataWrapper;
|
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||||
nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr, clipboardDataPtr, dataLength,
|
nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr, clipboardDataPtr, dataLength,
|
||||||
getter_AddRefs(genericDataWrapper));
|
getter_AddRefs(genericDataWrapper));
|
||||||
|
@ -285,44 +375,3 @@ nsClipboard::GetNativeClipboardData(nsITransferable * aTransferable, PRInt32 aWh
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsClipboard::HasDataMatchingFlavors(nsISupportsArray* aFlavorList, PRInt32 aWhichClipboard, PRBool * outResult)
|
|
||||||
{
|
|
||||||
*outResult = PR_FALSE;
|
|
||||||
|
|
||||||
if ((aWhichClipboard != kGlobalClipboard) || !aFlavorList)
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
NSPasteboard* generalPBoard = [NSPasteboard generalPasteboard];
|
|
||||||
|
|
||||||
PRUint32 flavorCount;
|
|
||||||
aFlavorList->Count(&flavorCount);
|
|
||||||
for (PRUint32 i = 0; i < flavorCount; i++) {
|
|
||||||
nsCOMPtr<nsISupports> genericFlavor;
|
|
||||||
aFlavorList->GetElementAt(i, getter_AddRefs(genericFlavor));
|
|
||||||
nsCOMPtr<nsISupportsCString> flavorWrapper(do_QueryInterface(genericFlavor));
|
|
||||||
if (flavorWrapper) {
|
|
||||||
nsXPIDLCString flavorStr;
|
|
||||||
flavorWrapper->ToString(getter_Copies(flavorStr));
|
|
||||||
if (strcmp(flavorStr, kUnicodeMime) == 0) {
|
|
||||||
NSString* availableType = [generalPBoard availableTypeFromArray:[NSArray arrayWithObject:NSStringPboardType]];
|
|
||||||
if (availableType && [availableType isEqualToString:NSStringPboardType]) {
|
|
||||||
*outResult = PR_TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
NSString* lookingForType = [NSString stringWithUTF8String:flavorStr];
|
|
||||||
NSString* availableType = [generalPBoard availableTypeFromArray:[NSArray arrayWithObject:lookingForType]];
|
|
||||||
if (availableType && [availableType isEqualToString:lookingForType]) {
|
|
||||||
*outResult = PR_TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
|
@ -45,9 +45,6 @@
|
||||||
|
|
||||||
extern NSString* const kWildcardPboardType;
|
extern NSString* const kWildcardPboardType;
|
||||||
|
|
||||||
class nsILocalFile;
|
|
||||||
class nsIDOMDragEvent;
|
|
||||||
|
|
||||||
class nsDragService : public nsBaseDragService
|
class nsDragService : public nsBaseDragService
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -104,118 +104,11 @@ static nsresult SetUpDragClipboard(nsISupportsArray* aTransferableArray)
|
||||||
if (!currentTransferable)
|
if (!currentTransferable)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
NSMutableDictionary* pasteboardOutputDict = [NSMutableDictionary dictionaryWithCapacity:1];
|
// Transform the transferable to an NSDictionary
|
||||||
|
NSDictionary* pasteboardOutputDict = nsClipboard::PasteboardDictFromTransferable(currentTransferable);
|
||||||
nsCOMPtr<nsISupportsArray> flavorList;
|
if (!pasteboardOutputDict)
|
||||||
nsresult rv = currentTransferable->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
PRUint32 flavorCount;
|
|
||||||
flavorList->Count(&flavorCount);
|
|
||||||
for (PRUint32 i = 0; i < flavorCount; i++) {
|
|
||||||
nsCOMPtr<nsISupports> genericFlavor;
|
|
||||||
flavorList->GetElementAt(i, getter_AddRefs(genericFlavor));
|
|
||||||
nsCOMPtr<nsISupportsCString> currentFlavor(do_QueryInterface(genericFlavor));
|
|
||||||
if (!currentFlavor)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
nsXPIDLCString flavorStr;
|
|
||||||
currentFlavor->ToString(getter_Copies(flavorStr));
|
|
||||||
|
|
||||||
// printf("writing out clipboard data of type %s\n", flavorStr.get());
|
|
||||||
|
|
||||||
if (strcmp(flavorStr, kPNGImageMime) == 0 || strcmp(flavorStr, kJPEGImageMime) == 0 ||
|
|
||||||
strcmp(flavorStr, kGIFImageMime) == 0 || strcmp(flavorStr, kNativeImageMime) == 0) {
|
|
||||||
PRUint32 dataSize = 0;
|
|
||||||
nsCOMPtr<nsISupports> transferSupports;
|
|
||||||
currentTransferable->GetTransferData(flavorStr, getter_AddRefs(transferSupports), &dataSize);
|
|
||||||
nsCOMPtr<nsISupportsInterfacePointer> ptrPrimitive(do_QueryInterface(transferSupports));
|
|
||||||
if (!ptrPrimitive)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
nsCOMPtr<nsISupports> primitiveData;
|
|
||||||
ptrPrimitive->GetData(getter_AddRefs(primitiveData));
|
|
||||||
|
|
||||||
nsCOMPtr<nsIImage> image(do_QueryInterface(primitiveData));
|
|
||||||
if (!image) {
|
|
||||||
NS_WARNING("Image isn't an nsIImage in transferable");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NS_FAILED(image->LockImagePixels(PR_FALSE)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
PRInt32 height = image->GetHeight();
|
|
||||||
PRInt32 stride = image->GetLineStride();
|
|
||||||
PRInt32 width = image->GetWidth();
|
|
||||||
if ((stride % 4 != 0) || (height < 1) || (width < 1))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
PRUint32* imageData = (PRUint32*)image->GetBits();
|
|
||||||
|
|
||||||
PRUint32* reorderedData = (PRUint32*)malloc(height * stride);
|
|
||||||
if (!reorderedData)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// We have to reorder data to have alpha last because only Tiger can handle
|
|
||||||
// alpha being first.
|
|
||||||
PRUint32 imageLength = ((stride * height) / 4);
|
|
||||||
for (PRUint32 i = 0; i < imageLength; i++) {
|
|
||||||
PRUint32 pixel = imageData[i];
|
|
||||||
reorderedData[i] = CFSwapInt32HostToBig((pixel << 8) | (pixel >> 24));
|
|
||||||
}
|
|
||||||
|
|
||||||
PRUint8* planes[2];
|
|
||||||
planes[0] = (PRUint8*)reorderedData;
|
|
||||||
planes[1] = nsnull;
|
|
||||||
NSBitmapImageRep* imageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:planes
|
|
||||||
pixelsWide:width
|
|
||||||
pixelsHigh:height
|
|
||||||
bitsPerSample:8
|
|
||||||
samplesPerPixel:4
|
|
||||||
hasAlpha:YES
|
|
||||||
isPlanar:NO
|
|
||||||
colorSpaceName:NSDeviceRGBColorSpace
|
|
||||||
bytesPerRow:stride
|
|
||||||
bitsPerPixel:32];
|
|
||||||
NSData* tiffData = [imageRep TIFFRepresentationUsingCompression:NSTIFFCompressionNone factor:1.0];
|
|
||||||
[imageRep release];
|
|
||||||
free(reorderedData);
|
|
||||||
|
|
||||||
if (NS_FAILED(image->UnlockImagePixels(PR_FALSE)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
[pasteboardOutputDict setObject:tiffData forKey:NSTIFFPboardType];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* If it isn't an image, we just throw the data on the clipboard with the mime string
|
|
||||||
* as its key. If we recognize the data as something we want to export in standard
|
|
||||||
* terms, then we do that too.
|
|
||||||
*/
|
|
||||||
void* data = nsnull;
|
|
||||||
PRUint32 dataSize = 0;
|
|
||||||
nsCOMPtr<nsISupports> genericDataWrapper;
|
|
||||||
rv = currentTransferable->GetTransferData(flavorStr, getter_AddRefs(genericDataWrapper), &dataSize);
|
|
||||||
nsPrimitiveHelpers::CreateDataFromPrimitive(flavorStr, genericDataWrapper, &data, dataSize);
|
|
||||||
|
|
||||||
// if it is kUnicodeMime, it is text we want to export as standard NSStringPboardType
|
|
||||||
if (strcmp(flavorStr, kUnicodeMime) == 0) {
|
|
||||||
NSString* nativeString = [NSString stringWithCharacters:(const unichar*)data length:(dataSize / sizeof(PRUnichar))];
|
|
||||||
// be nice to Carbon apps, normalize the receiver’s contents using Form C.
|
|
||||||
nativeString = [nativeString precomposedStringWithCanonicalMapping];
|
|
||||||
[pasteboardOutputDict setObject:nativeString forKey:NSStringPboardType];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
NSString* key = [NSString stringWithUTF8String:flavorStr];
|
|
||||||
NSData* value = [NSData dataWithBytes:data length:dataSize];
|
|
||||||
[pasteboardOutputDict setObject:value forKey:key];
|
|
||||||
}
|
|
||||||
|
|
||||||
nsMemory::Free(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// write everything out to the general pasteboard
|
// write everything out to the general pasteboard
|
||||||
unsigned int outputCount = [pasteboardOutputDict count];
|
unsigned int outputCount = [pasteboardOutputDict count];
|
||||||
NSArray* outputKeys = [pasteboardOutputDict allKeys];
|
NSArray* outputKeys = [pasteboardOutputDict allKeys];
|
||||||
|
@ -384,111 +277,8 @@ nsDragService::InvokeDragSession(nsIDOMNode* aDOMNode, nsISupportsArray* aTransf
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDragService::GetData(nsITransferable* aTransferable, PRUint32 aItemIndex)
|
nsDragService::GetData(nsITransferable* aTransferable, PRUint32 aItemIndex)
|
||||||
{
|
{
|
||||||
if (!aTransferable)
|
// Ask the clipboard to look this up for us
|
||||||
return NS_ERROR_FAILURE;
|
return nsClipboard::CopyPasteboardDataToTransferable(globalDragPboard, aTransferable, aItemIndex);
|
||||||
|
|
||||||
// get flavor list that includes all acceptable flavors (including ones obtained through conversion)
|
|
||||||
nsCOMPtr<nsISupportsArray> flavorList;
|
|
||||||
nsresult rv = aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavorList));
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
PRUint32 flavorCount;
|
|
||||||
flavorList->Count(&flavorCount);
|
|
||||||
for (PRUint32 i = 0; i < flavorCount; i++) {
|
|
||||||
nsCOMPtr<nsISupports> genericFlavor;
|
|
||||||
flavorList->GetElementAt(i, getter_AddRefs(genericFlavor));
|
|
||||||
nsCOMPtr<nsISupportsCString> currentFlavor(do_QueryInterface(genericFlavor));
|
|
||||||
|
|
||||||
if (!currentFlavor)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
nsXPIDLCString flavorStr;
|
|
||||||
currentFlavor->ToString(getter_Copies(flavorStr));
|
|
||||||
|
|
||||||
// printf("looking for clipboard data of type %s\n", flavorStr.get());
|
|
||||||
|
|
||||||
if (strcmp(flavorStr, kFileMime) == 0) {
|
|
||||||
NSArray* pFiles = [globalDragPboard propertyListForType:NSFilenamesPboardType];
|
|
||||||
if (!pFiles || [pFiles count] < (aItemIndex + 1))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
NSString* filePath = [pFiles objectAtIndex:aItemIndex];
|
|
||||||
if (!filePath)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
unsigned int stringLength = [filePath length];
|
|
||||||
unsigned int dataLength = (stringLength + 1) * sizeof(PRUnichar); // in bytes
|
|
||||||
PRUnichar* clipboardDataPtr = (PRUnichar*)malloc(dataLength);
|
|
||||||
[filePath getCharacters:clipboardDataPtr];
|
|
||||||
clipboardDataPtr[stringLength] = 0; // null terminate
|
|
||||||
|
|
||||||
nsCOMPtr<nsILocalFile> file;
|
|
||||||
nsresult rv = NS_NewLocalFile(nsDependentString(clipboardDataPtr), PR_TRUE, getter_AddRefs(file));
|
|
||||||
free(clipboardDataPtr);
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
nsCOMPtr<nsISupports> genericDataWrapper;
|
|
||||||
genericDataWrapper = do_QueryInterface(file);
|
|
||||||
aTransferable->SetTransferData(flavorStr, genericDataWrapper, dataLength);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (strcmp(flavorStr, kUnicodeMime) == 0) {
|
|
||||||
NSString* pString = [globalDragPboard stringForType:NSStringPboardType];
|
|
||||||
if (!pString)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
NSData* stringData = [pString dataUsingEncoding:NSUnicodeStringEncoding];
|
|
||||||
unsigned int dataLength = [stringData length];
|
|
||||||
unsigned char* clipboardDataPtr = (unsigned char*)malloc(dataLength);
|
|
||||||
[stringData getBytes:(void*)clipboardDataPtr];
|
|
||||||
|
|
||||||
// The DOM only wants LF, so convert from MacOS line endings to DOM line endings.
|
|
||||||
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks(flavorStr, (void**)&clipboardDataPtr, (PRInt32*)&dataLength);
|
|
||||||
|
|
||||||
// skip BOM (Byte Order Mark to distinguish little or big endian)
|
|
||||||
unsigned char* clipboardDataPtrNoBOM = clipboardDataPtr;
|
|
||||||
if ((dataLength > 2) &&
|
|
||||||
((clipboardDataPtr[0] == 0xFE && clipboardDataPtr[1] == 0xFF) ||
|
|
||||||
(clipboardDataPtr[0] == 0xFF && clipboardDataPtr[1] == 0xFE))) {
|
|
||||||
dataLength -= sizeof(PRUnichar);
|
|
||||||
clipboardDataPtrNoBOM += sizeof(PRUnichar);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsISupports> genericDataWrapper;
|
|
||||||
nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr, clipboardDataPtrNoBOM, dataLength,
|
|
||||||
getter_AddRefs(genericDataWrapper));
|
|
||||||
aTransferable->SetTransferData(flavorStr, genericDataWrapper, dataLength);
|
|
||||||
free(clipboardDataPtr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (strcmp(flavorStr, kPNGImageMime) == 0 || strcmp(flavorStr, kJPEGImageMime) == 0 ||
|
|
||||||
strcmp(flavorStr, kGIFImageMime) == 0) {
|
|
||||||
// We have never supported this on Mac, we could someday but nobody does this. We want this
|
|
||||||
// test here so that we don't try to get this as a custom type.
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// this is some sort of data that mozilla put on the clipboard itself if it exists
|
|
||||||
NSData* pData = [globalDragPboard dataForType:[NSString stringWithUTF8String:flavorStr]];
|
|
||||||
if (!pData)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
unsigned int dataLength = [pData length];
|
|
||||||
unsigned char* clipboardDataPtr = (unsigned char*)malloc(dataLength);
|
|
||||||
[pData getBytes:(void*)clipboardDataPtr];
|
|
||||||
|
|
||||||
nsCOMPtr<nsISupports> genericDataWrapper;
|
|
||||||
nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr, clipboardDataPtr, dataLength,
|
|
||||||
getter_AddRefs(genericDataWrapper));
|
|
||||||
aTransferable->SetTransferData(flavorStr, genericDataWrapper, dataLength);
|
|
||||||
free(clipboardDataPtr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче