support promised file dragging in cocoa drag service. patch by Stan Shebs. b=358093 r=josh sr=pav

This commit is contained in:
joshmoz%gmail.com 2007-07-17 02:24:05 +00:00
Родитель e5d04d7bee
Коммит 78cb9a9752
6 изменённых файлов: 123 добавлений и 3 удалений

Просмотреть файл

@ -69,6 +69,12 @@
#import <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>
#ifdef MOZ_LOGGING
// make sure that logging is enabled before including prlog.h
#define FORCE_PR_LOG
#include "prlog.h"
#endif
class gfxASurface;
class nsChildView;
union nsPluginPort;

Просмотреть файл

@ -58,6 +58,8 @@
#include "nsIViewManager.h"
#include "nsIInterfaceRequestor.h"
#include "nsIServiceManager.h"
#include "nsILocalFile.h"
#include "nsILocalFileMac.h"
#include "nsGfxCIID.h"
#include "nsDragService.h"
@ -72,6 +74,10 @@
#undef DEBUG_UPDATE
#undef INVALIDATE_DEBUGGING // flash areas as they are invalidated
#ifdef PR_LOGGING
PRLogModuleInfo* sCocoaLog = nsnull;
#endif
extern "C" {
CG_EXTERN void CGContextResetCTM(CGContextRef);
CG_EXTERN void CGContextSetCTM(CGContextRef, CGAffineTransform);
@ -328,6 +334,12 @@ nsChildView::nsChildView() : nsBaseWidget()
{
SetBackgroundColor(NS_RGB(255, 255, 255));
SetForegroundColor(NS_RGB(0, 0, 0));
#ifdef PR_LOGGING
if (!sCocoaLog)
sCocoaLog = PR_NewLogModule("nsCocoaWidgets");
#endif
}
@ -1854,9 +1866,11 @@ NSEvent* globalDragEvent = nil;
}
// register for things we'll take from other applications
PR_LOG(sCocoaLog, PR_LOG_ALWAYS, ("ChildView initWithFrame: registering drag types\n"));
[self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType,
NSStringPboardType,
NSURLPboardType,
NSFilesPromisePboardType,
kWildcardPboardType,
nil]];
@ -3879,6 +3893,8 @@ static PRBool IsSpecialGeckoKey(UInt32 macKeyCode)
if (!mGeckoChild)
return NO;
PR_LOG(sCocoaLog, PR_LOG_ALWAYS, ("ChildView doDragAction: entered\n"));
if (!mDragService) {
CallGetService(kDragServiceContractID, &mDragService);
NS_ASSERTION(mDragService, "Couldn't get a drag service - big problem!");
@ -3945,6 +3961,8 @@ static PRBool IsSpecialGeckoKey(UInt32 macKeyCode)
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
{
PR_LOG(sCocoaLog, PR_LOG_ALWAYS, ("ChildView draggingEntered: entered\n"));
// there should never be a globalDragPboard when "draggingEntered:" is
// called, but just in case we'll take care of it here.
[globalDragPboard release];
@ -3962,6 +3980,8 @@ static PRBool IsSpecialGeckoKey(UInt32 macKeyCode)
- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
{
PR_LOG(sCocoaLog, PR_LOG_ALWAYS, ("ChildView draggingUpdated: entered\n"));
BOOL handled = [self doDragAction:NS_DRAGDROP_OVER sender:sender];
return handled ? NSDragOperationGeneric : NSDragOperationNone;
}
@ -3969,6 +3989,8 @@ static PRBool IsSpecialGeckoKey(UInt32 macKeyCode)
- (void)draggingExited:(id <NSDraggingInfo>)sender
{
PR_LOG(sCocoaLog, PR_LOG_ALWAYS, ("ChildView draggingExited: entered\n"));
[self doDragAction:NS_DRAGDROP_EXIT sender:sender];
}
@ -4004,6 +4026,63 @@ static PRBool IsSpecialGeckoKey(UInt32 macKeyCode)
return UINT_MAX;
}
// This method is a callback typically invoked in response to a drag ending on the desktop
// or a Findow folder window; the argument passed is a path to the drop location, to be used
// in constructing a complete pathname for the file(s) we want to create as a result of
// the drag.
- (NSArray *)namesOfPromisedFilesDroppedAtDestination:(id <NSDraggingInfo>)dropDestination
{
nsresult rv;
PR_LOG(sCocoaLog, PR_LOG_ALWAYS, ("ChildView namesOfPromisedFilesDroppedAtDestination: entering callback for promised files\n"));
nsCOMPtr<nsILocalFile> targFile;
NS_NewLocalFile(EmptyString(), PR_TRUE, getter_AddRefs(targFile));
nsCOMPtr<nsILocalFileMac> macLocalFile = do_QueryInterface(targFile);
if (!macLocalFile) {
NS_ERROR("No Mac local file");
return nil;
}
if (!NS_SUCCEEDED(macLocalFile->InitWithCFURL((CFURLRef)dropDestination))) {
NS_ERROR("failed InitWithCFURL");
return nil;
}
extern nsISupportsArray *draggedTransferables;
PRUint32 transferableCount;
rv = draggedTransferables->Count(&transferableCount);
if (NS_FAILED(rv))
return nil;
for (PRUint32 i = 0; i < transferableCount; i++) {
nsCOMPtr<nsISupports> genericItem;
draggedTransferables->GetElementAt(i, getter_AddRefs(genericItem));
nsCOMPtr<nsITransferable> item(do_QueryInterface(genericItem));
if (!item) {
NS_ERROR("no transferable");
return nil;
}
item->SetTransferData(kFilePromiseDirectoryMime, macLocalFile, sizeof(nsILocalFile*));
// now request the kFilePromiseMime data, which will invoke the data provider
// If successful, the returned data is a reference to the resulting file.
nsCOMPtr<nsISupports> fileDataPrimitive;
PRUint32 dataSize = 0;
item->GetTransferData(kFilePromiseMime, getter_AddRefs(fileDataPrimitive), &dataSize);
}
NSPasteboard* generalPboard = [NSPasteboard pasteboardWithName:NSDragPboard];
NSData* data = [generalPboard dataForType:@"application/x-moz-file-promise-dest-filename"];
NSString* name = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSArray* rslt = [NSArray arrayWithObject:name];
[name release];
return rslt;
}
#pragma mark -

Просмотреть файл

@ -43,6 +43,16 @@
#import <Cocoa/Cocoa.h>
#ifdef MOZ_LOGGING
// make sure that logging is enabled before including prlog.h
#define FORCE_PR_LOG
#include "prlog.h"
#endif
#ifdef PR_LOGGING
extern PRLogModuleInfo* sCocoaLog;
#endif
class nsITransferable;

Просмотреть файл

@ -299,7 +299,7 @@ nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTransferable)
nsXPIDLCString flavorStr;
currentFlavor->ToString(getter_Copies(flavorStr));
// printf("writing out clipboard data of type %s\n", flavorStr.get());
PR_LOG(sCocoaLog, PR_LOG_ALWAYS, ("writing out clipboard data of type %s (%d)\n", flavorStr.get(), i));
if (flavorStr.EqualsLiteral(kUnicodeMime)) {
void* data = nsnull;

Просмотреть файл

@ -43,6 +43,16 @@
#include <Cocoa/Cocoa.h>
#ifdef MOZ_LOGGING
// make sure that logging is enabled before including prlog.h
#define FORCE_PR_LOG
#include "prlog.h"
#endif
#ifdef PR_LOGGING
extern PRLogModuleInfo* sCocoaLog;
#endif
extern NSString* const kWildcardPboardType;
class nsDragService : public nsBaseDragService

Просмотреть файл

@ -69,6 +69,10 @@ extern NSPasteboard* globalDragPboard;
extern NSView* globalDragView;
extern NSEvent* globalDragEvent;
// This global makes the transferable array available to Cocoa's promised
// file destination callback.
nsISupportsArray *draggedTransferables;
NSString* const kWildcardPboardType = @"MozillaWildcard";
NS_IMPL_ADDREF_INHERITED(nsDragService, nsBaseDragService)
@ -262,12 +266,23 @@ nsDragService::InvokeDragSession(nsIDOMNode* aDOMNode, nsISupportsArray* aTransf
point = [[globalDragView window] convertScreenToBase: point];
NSPoint localPoint = [globalDragView convertPoint:point fromView:nil];
// Save the transferables away in case a promised file callback is invoked.
draggedTransferables = aTransferableArray;
nsBaseDragService::StartDragSession();
// It is possible to specify what file types we will create, but the Finder doesn't
// care; it is happy to store any type of file it is handed. So use an empty string
// for type.
NSPasteboard* workingPBoard = [NSPasteboard pasteboardWithName:NSDragPboard];
NSArray* fileTypeList = [NSArray arrayWithObject:@""];
[workingPBoard setPropertyList:fileTypeList forType:NSFilesPromisePboardType];
[globalDragView dragImage:image
at:localPoint
offset:NSMakeSize(0,0)
event:globalDragEvent
pasteboard:[NSPasteboard pasteboardWithName:NSDragPboard]
pasteboard:workingPBoard
source:globalDragView
slideBack:YES];
@ -331,7 +346,7 @@ nsDragService::GetData(nsITransferable* aTransferable, PRUint32 aItemIndex)
nsXPIDLCString flavorStr;
currentFlavor->ToString(getter_Copies(flavorStr));
// printf("looking for clipboard data of type %s\n", flavorStr.get());
PR_LOG(sCocoaLog, PR_LOG_ALWAYS, ("nsDragService::GetData: looking for clipboard data of type %s\n", flavorStr.get()));
if (flavorStr.EqualsLiteral(kFileMime)) {
NSArray* pFiles = [globalDragPboard propertyListForType:NSFilenamesPboardType];