зеркало из https://github.com/mozilla/pjs.git
Bug 193053: drag and drop-related changes to allow for the dragging and copying of image bits, and to allow dragging into the file system. r=pinkerton/brade, sr=bryner/bz.
This commit is contained in:
Родитель
8893b1e6fd
Коммит
f3456b4697
|
@ -40,6 +40,13 @@
|
|||
|
||||
class nsISelection;
|
||||
class nsIDocument;
|
||||
class nsIDOMNode;
|
||||
class nsIDOMHTMLImageElement;
|
||||
class nsIContent;
|
||||
class nsIPresContext;
|
||||
class nsIPresShell;
|
||||
class nsIImageFrame;
|
||||
class nsIImage;
|
||||
class nsITransferable;
|
||||
|
||||
class nsCopySupport
|
||||
|
@ -50,4 +57,17 @@ class nsCopySupport
|
|||
static nsresult DoHooks(nsIDocument *aDoc, nsITransferable *aTrans,
|
||||
PRBool *aDoPutOnClipboard);
|
||||
static nsresult IsPlainTextContext(nsISelection *aSel, nsIDocument *aDoc, PRBool *aIsPlainTextContext);
|
||||
|
||||
// Get the selection, or entire document, in the format specified by the mime type
|
||||
// (text/html or text/plain). If aSel is non-null, use it, otherwise get the entire
|
||||
// doc.
|
||||
static nsresult GetContents(const nsACString& aMimeType, PRUint32 aFlags, nsISelection *aSel, nsIDocument *aDoc, nsAString& outdata);
|
||||
|
||||
static nsresult ImageCopy(nsIDOMHTMLImageElement* imageElement, PRInt16 aClipboardID);
|
||||
|
||||
protected:
|
||||
|
||||
// these are ripped from nsContentAreaDragDrop. This so needs factoring.
|
||||
static nsresult GetImageFromDOMNode(nsIDOMNode* inNode, nsIImage**outImage);
|
||||
|
||||
};
|
||||
|
|
|
@ -52,6 +52,7 @@ REQUIRES = xpcom \
|
|||
xuldoc \
|
||||
intl \
|
||||
windowwatcher \
|
||||
webbrowserpersist \
|
||||
imglib2 \
|
||||
uriloader \
|
||||
webbrwsr \
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
|
||||
// Helper Classes
|
||||
#include "nsString.h"
|
||||
#include "nsXPIDLString.h"
|
||||
|
||||
// Interfaces needed to be included
|
||||
#include "nsIDOMNSUIEvent.h"
|
||||
|
@ -86,7 +85,7 @@
|
|||
#include "nsINameSpaceManager.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIPresShell.h"
|
||||
|
@ -99,6 +98,8 @@
|
|||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIDocumentEncoder.h"
|
||||
#include "nsRange.h"
|
||||
#include "nsIWebBrowserPersist.h"
|
||||
#include "nsEscape.h"
|
||||
|
||||
|
||||
NS_IMPL_ADDREF(nsContentAreaDragDrop)
|
||||
|
@ -108,6 +109,7 @@ NS_INTERFACE_MAP_BEGIN(nsContentAreaDragDrop)
|
|||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMDragListener)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMEventListener, nsIDOMDragListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMDragListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIFlavorDataProvider)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDragDropHandler)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
@ -155,7 +157,7 @@ nsContentAreaDragDrop::Detach()
|
|||
//
|
||||
// Subscribe to the events that will allow us to track drags.
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsContentAreaDragDrop::AddDragListener()
|
||||
{
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
@ -176,7 +178,7 @@ nsContentAreaDragDrop::AddDragListener()
|
|||
//
|
||||
// Unsubscribe from all the various drag events that we were listening to.
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsContentAreaDragDrop::RemoveDragListener()
|
||||
{
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
@ -304,7 +306,7 @@ nsContentAreaDragDrop::ExtractURLFromData(const nsACString & inFlavor, nsISuppor
|
|||
return;
|
||||
outURL.Truncate();
|
||||
|
||||
if ( inFlavor.Equals(kUnicodeMime) ) {
|
||||
if ( inFlavor.Equals(kUnicodeMime) || inFlavor.Equals(kURLDataMime) ) {
|
||||
// the data is regular unicode, just go with what we get. It may be a url, it
|
||||
// may not be. *shrug*
|
||||
nsCOMPtr<nsISupportsString> stringData(do_QueryInterface(inDataWrapper));
|
||||
|
@ -374,12 +376,13 @@ nsContentAreaDragDrop::DragDrop(nsIDOMEvent* inMouseEvent)
|
|||
nsCOMPtr<nsITransferable> trans(do_CreateInstance("@mozilla.org/widget/transferable;1"));
|
||||
if ( !trans )
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
||||
// add the relevant flavors. order is important (highest fidelity to lowest)
|
||||
trans->AddDataFlavor(kURLDataMime);
|
||||
trans->AddDataFlavor(kURLMime);
|
||||
trans->AddDataFlavor(kFileMime);
|
||||
trans->AddDataFlavor(kUnicodeMime);
|
||||
|
||||
|
||||
nsresult rv = session->GetData(trans, 0); // again, we only care about the first object
|
||||
if ( NS_SUCCEEDED(rv) ) {
|
||||
// if the client has provided an override callback, call it. It may
|
||||
|
@ -980,6 +983,18 @@ nsContentAreaDragDrop::CreateTransferable(const nsAString & inURLString, const n
|
|||
return NS_ERROR_FAILURE;
|
||||
urlPrimitive->SetData(dragData);
|
||||
trans->SetTransferData(kURLMime, urlPrimitive, dragData.Length() * sizeof(PRUnichar));
|
||||
|
||||
nsCOMPtr<nsISupportsString> urlDataPrimitive(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
|
||||
if (!urlDataPrimitive)
|
||||
return NS_ERROR_FAILURE;
|
||||
urlDataPrimitive->SetData(inURLString);
|
||||
trans->SetTransferData(kURLDataMime, urlDataPrimitive, inURLString.Length() * sizeof(PRUnichar));
|
||||
|
||||
nsCOMPtr<nsISupportsString> urlDescPrimitive(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
|
||||
if (!urlDescPrimitive)
|
||||
return NS_ERROR_FAILURE;
|
||||
urlDescPrimitive->SetData(inTitleString);
|
||||
trans->SetTransferData(kURLDescriptionMime, urlDescPrimitive, inTitleString.Length() * sizeof(PRUnichar));
|
||||
}
|
||||
|
||||
// add the full html
|
||||
|
@ -1007,6 +1022,26 @@ nsContentAreaDragDrop::CreateTransferable(const nsAString & inURLString, const n
|
|||
return NS_ERROR_FAILURE;
|
||||
ptrPrimitive->SetData(inImage);
|
||||
trans->SetTransferData(kNativeImageMime, ptrPrimitive, sizeof(nsIImage*));
|
||||
// assume the image comes from a file, and add a file promise. We register ourselves
|
||||
// as a nsIFlavorDataProvider, and will use the GetFlavorData callback to save the
|
||||
// image to disk.
|
||||
trans->SetTransferData(kFilePromiseMime, NS_STATIC_CAST(nsIFlavorDataProvider*, this), nsITransferable::kFlavorHasDataProvider);
|
||||
|
||||
nsCOMPtr<nsISupportsString> imageUrlPrimitive(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
|
||||
if (!imageUrlPrimitive)
|
||||
return NS_ERROR_FAILURE;
|
||||
imageUrlPrimitive->SetData(inImageSourceString);
|
||||
trans->SetTransferData(kFilePromiseURLMime, imageUrlPrimitive, inImageSourceString.Length() * sizeof(PRUnichar));
|
||||
|
||||
// if not an anchor, add the image url
|
||||
if (!inIsAnchor)
|
||||
{
|
||||
nsCOMPtr<nsISupportsString> urlDataPrimitive(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
|
||||
if (!urlDataPrimitive)
|
||||
return NS_ERROR_FAILURE;
|
||||
urlDataPrimitive->SetData(inURLString);
|
||||
trans->SetTransferData(kURLDataMime, urlDataPrimitive, inURLString.Length() * sizeof(PRUnichar));
|
||||
}
|
||||
}
|
||||
|
||||
*outTrans = trans;
|
||||
|
@ -1318,3 +1353,127 @@ nsContentAreaDragDrop::GetImageFromDOMNode(nsIDOMNode* inNode, nsIImage**outImag
|
|||
|
||||
return CallGetInterface(ir.get(), outImage);
|
||||
}
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
// SaveURIToFile
|
||||
// used on platforms where it's possible to drag items (e.g. images)
|
||||
// into the file system
|
||||
nsresult
|
||||
nsContentAreaDragDrop::SaveURIToFileInDirectory(nsAString& inSourceURIString, nsILocalFile* inDestDirectory, nsILocalFile** outFile)
|
||||
{
|
||||
*outFile = nsnull;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// clone it because it belongs to the drag data, so we shouldn't mess with it
|
||||
nsCOMPtr<nsIFile> clonedFile;
|
||||
rv = inDestDirectory->Clone(getter_AddRefs(clonedFile));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsILocalFile> destFile = do_QueryInterface(clonedFile);
|
||||
if (!destFile) return NS_ERROR_NO_INTERFACE;
|
||||
|
||||
nsCOMPtr<nsIURI> sourceURI;
|
||||
rv = NS_NewURI(getter_AddRefs(sourceURI), inSourceURIString);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIURL> sourceURL = do_QueryInterface(sourceURI);
|
||||
if (!sourceURL) return NS_ERROR_NO_INTERFACE;
|
||||
|
||||
nsCAutoString fileName; // escaped, UTF-8
|
||||
sourceURL->GetFileName(fileName);
|
||||
|
||||
if (fileName.IsEmpty())
|
||||
return NS_ERROR_FAILURE; // this is an error; the URL must point to a file
|
||||
|
||||
NS_UnescapeURL(fileName);
|
||||
NS_ConvertUTF8toUCS2 wideFileName(fileName);
|
||||
|
||||
// make the name safe for the filesystem
|
||||
wideFileName.ReplaceChar(PRUnichar('/'), PRUnichar('_'));
|
||||
wideFileName.ReplaceChar(PRUnichar('\\'), PRUnichar('_'));
|
||||
wideFileName.ReplaceChar(PRUnichar(':'), PRUnichar('_'));
|
||||
|
||||
rv = destFile->Append(wideFileName);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = destFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// we rely on the fact that the WPB is refcounted by the channel etc,
|
||||
// so we don't keep a ref to it. It will die when finished.
|
||||
nsCOMPtr<nsIWebBrowserPersist> persist = do_CreateInstance("@mozilla.org/embedding/browser/nsWebBrowserPersist;1", &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsISupports> fileAsSupports = do_QueryInterface(destFile);
|
||||
rv = persist->SaveURI(sourceURI, nsnull, nsnull, nsnull, nsnull, fileAsSupports);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
*outFile = destFile;
|
||||
NS_ADDREF(*outFile);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// This is our nsIFlavorDataProvider callback. There are several assumptions here that
|
||||
// make this work:
|
||||
//
|
||||
// 1. Someone put a kFilePromiseURLMime flavor into the transferable with the source
|
||||
// URI of the file to save (as a string). We did that above.
|
||||
//
|
||||
// 2. Someone put a kFilePromiseDirectoryMime flavor into the transferable with
|
||||
// an nsILocalFile for the directory we are to save in. That has to be done
|
||||
// by platform-specific code (in widget), which gets the destination directory
|
||||
// from OS-specific drag information.
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsContentAreaDragDrop::GetFlavorData(nsITransferable *aTransferable,
|
||||
const char *aFlavor, nsISupports **aData, PRUint32 *aDataLen)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aData && aDataLen);
|
||||
*aData = nsnull;
|
||||
*aDataLen = 0;
|
||||
|
||||
nsresult rv = NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
if (strcmp(aFlavor, kFilePromiseMime) == 0)
|
||||
{
|
||||
// get the URI from the kFilePromiseURLMime flavor
|
||||
NS_ENSURE_ARG(aTransferable);
|
||||
nsCOMPtr<nsISupports> urlPrimitive;
|
||||
PRUint32 dataSize = 0;
|
||||
aTransferable->GetTransferData(kFilePromiseURLMime, getter_AddRefs(urlPrimitive), &dataSize);
|
||||
nsCOMPtr<nsISupportsString> srcUrlPrimitive = do_QueryInterface(urlPrimitive);
|
||||
if (!srcUrlPrimitive) return NS_ERROR_FAILURE;
|
||||
|
||||
nsAutoString sourceURLString;
|
||||
srcUrlPrimitive->GetData(sourceURLString);
|
||||
if (sourceURLString.IsEmpty())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// get the target directory from the kFilePromiseDirectoryMime flavor
|
||||
nsCOMPtr<nsISupports> dirPrimitive;
|
||||
dataSize = 0;
|
||||
aTransferable->GetTransferData(kFilePromiseDirectoryMime, getter_AddRefs(dirPrimitive), &dataSize);
|
||||
nsCOMPtr<nsILocalFile> destDirectory = do_QueryInterface(dirPrimitive);
|
||||
if (!destDirectory) return NS_ERROR_FAILURE;
|
||||
|
||||
// now save the file
|
||||
nsCOMPtr<nsILocalFile> destFile;
|
||||
rv = SaveURIToFileInDirectory(sourceURLString, destDirectory, getter_AddRefs(destFile));
|
||||
|
||||
// send back an nsILocalFile
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
CallQueryInterface(destFile, aData);
|
||||
*aDataLen = sizeof(nsILocalFile*);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "nsIDragDropHandler.h"
|
||||
#include "nsIDOMDragListener.h"
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsITransferable.h"
|
||||
|
||||
class nsIDOMNode;
|
||||
class nsISelection;
|
||||
|
@ -54,9 +55,10 @@ class nsIPresShell;
|
|||
class nsIPresContext;
|
||||
class nsIContent;
|
||||
class nsIDocument;
|
||||
class nsIURI;
|
||||
class nsILocalFile;
|
||||
class nsISimpleEnumerator;
|
||||
|
||||
|
||||
// {1f34bc80-1bc7-11d6-a384-d705dd0746fc}
|
||||
#define NS_CONTENTAREADRAGDROP_CID \
|
||||
{ 0x1f34bc80, 0x1bc7, 0x11d6, { 0xa3, 0x84, 0xd7, 0x05, 0xdd, 0x07, 0x46, 0xfc } }
|
||||
|
@ -71,11 +73,14 @@ class nsISimpleEnumerator;
|
|||
// to drag and drop. Registers itself with the DOM with AddChromeListeners()
|
||||
// and removes itself with RemoveChromeListeners().
|
||||
//
|
||||
class nsContentAreaDragDrop : public nsIDOMDragListener, public nsIDragDropHandler
|
||||
class nsContentAreaDragDrop : public nsIDOMDragListener,
|
||||
public nsIDragDropHandler,
|
||||
public nsIFlavorDataProvider
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDRAGDROPHANDLER
|
||||
NS_DECL_NSIFLAVORDATAPROVIDER
|
||||
|
||||
nsContentAreaDragDrop ( ) ;
|
||||
virtual ~nsContentAreaDragDrop ( ) ;
|
||||
|
@ -91,8 +96,8 @@ public:
|
|||
private:
|
||||
|
||||
// Add/remove the relevant listeners
|
||||
NS_IMETHOD AddDragListener();
|
||||
NS_IMETHOD RemoveDragListener();
|
||||
nsresult AddDragListener();
|
||||
nsresult RemoveDragListener();
|
||||
|
||||
// utility routines
|
||||
static void FindFirstAnchor(nsIDOMNode* inNode, nsIDOMNode** outAnchor);
|
||||
|
@ -110,6 +115,8 @@ private:
|
|||
// if inNode is null, use the selection from the window
|
||||
static nsresult SerializeNodeOrSelection(const char* inMimeType, PRUint32 inFlags,
|
||||
nsIDOMWindow* inWindow, nsIDOMNode* inNode, nsAString& outResultString);
|
||||
|
||||
static nsresult SaveURIToFileInDirectory(nsAString& inSourceURIString, nsILocalFile* inDestDirectory, nsILocalFile** outFile);
|
||||
|
||||
PRBool BuildDragData(nsIDOMEvent* inMouseEvent, nsAString & outURLString, nsAString & outTitleString,
|
||||
nsAString & outHTMLString, nsAString & outImageSourceString, nsIImage** outImage, PRBool* outIsAnchor);
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "nsXPCOM.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIDOMRange.h"
|
||||
#include "nsIFrame.h"
|
||||
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIClipboardDragDropHooks.h"
|
||||
|
@ -70,6 +71,17 @@
|
|||
//static NS_DEFINE_CID(kUBidiUtilCID, NS_UNICHARBIDIUTIL_CID);
|
||||
#endif
|
||||
|
||||
// image copy stuff
|
||||
#include "nsIDOMHTMLImageElement.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsIImageLoadingContent.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIImage.h"
|
||||
|
||||
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
|
||||
static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID);
|
||||
static NS_DEFINE_CID(kHTMLConverterCID, NS_HTMLFORMATCONVERTER_CID);
|
||||
|
@ -379,3 +391,121 @@ nsresult nsCopySupport::IsPlainTextContext(nsISelection *aSel, nsIDocument *aDoc
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCopySupport::GetContents(const nsACString& aMimeType, PRUint32 aFlags, nsISelection *aSel, nsIDocument *aDoc, nsAString& outdata)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDocumentEncoder> docEncoder;
|
||||
|
||||
nsCAutoString encoderContractID(NS_DOC_ENCODER_CONTRACTID_BASE);
|
||||
encoderContractID.Append(aMimeType);
|
||||
|
||||
docEncoder = do_CreateInstance(encoderContractID.get());
|
||||
NS_ENSURE_TRUE(docEncoder, NS_ERROR_FAILURE);
|
||||
|
||||
PRUint32 flags = aFlags;
|
||||
|
||||
if (aMimeType.Equals("text/plain"))
|
||||
flags |= nsIDocumentEncoder::OutputPreformatted;
|
||||
|
||||
NS_ConvertASCIItoUCS2 unicodeMimeType(aMimeType);
|
||||
rv = docEncoder->Init(aDoc, unicodeMimeType, flags);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (aSel)
|
||||
{
|
||||
rv = docEncoder->SetSelection(aSel);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
// encode the selection
|
||||
return docEncoder->EncodeToString(outdata);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsCopySupport::ImageCopy(nsIDOMHTMLImageElement* imageElement, PRInt16 aClipboardID)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> imageNode = do_QueryInterface(imageElement, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!imageNode) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIImage> image;
|
||||
rv = GetImageFromDOMNode(imageNode, getter_AddRefs(image));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!image) return NS_ERROR_FAILURE;
|
||||
|
||||
// Get the Clipboard
|
||||
nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!clipboard) return NS_ERROR_FAILURE;
|
||||
|
||||
// Create a transferable for putting data on the Clipboard
|
||||
nsCOMPtr<nsITransferable> trans = do_CreateInstance(kCTransferableCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!trans) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsISupportsInterfacePointer> ptrPrimitive(do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!ptrPrimitive) return NS_ERROR_FAILURE;
|
||||
ptrPrimitive->SetData(image);
|
||||
|
||||
trans->SetTransferData(kNativeImageMime, ptrPrimitive, sizeof(nsISupports*));
|
||||
|
||||
// put the transferable on the clipboard
|
||||
return clipboard->SetData(trans, nsnull, aClipboardID);
|
||||
}
|
||||
|
||||
//
|
||||
// GetImage
|
||||
//
|
||||
// Given a dom node that's an image, finds the nsIImage associated with it.
|
||||
//
|
||||
// XXX see also nsContentAreaDragDrop, and factor!
|
||||
nsresult
|
||||
nsCopySupport::GetImageFromDOMNode(nsIDOMNode* inNode, nsIImage**outImage)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(outImage);
|
||||
*outImage = nsnull;
|
||||
|
||||
nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(inNode));
|
||||
if (!content) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIRequest> imgRequest;
|
||||
content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
|
||||
getter_AddRefs(imgRequest));
|
||||
if (!imgRequest) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIContainer> imgContainer;
|
||||
imgRequest->GetImage(getter_AddRefs(imgContainer));
|
||||
|
||||
if (!imgContainer) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> imgFrame;
|
||||
imgContainer->GetFrameAt(0, getter_AddRefs(imgFrame));
|
||||
|
||||
if (!imgFrame) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInterfaceRequestor> ir = do_QueryInterface(imgFrame);
|
||||
|
||||
if (!ir) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
return CallGetInterface(ir.get(), outImage);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "nsXPCOM.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIDOMRange.h"
|
||||
#include "nsIFrame.h"
|
||||
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIClipboardDragDropHooks.h"
|
||||
|
@ -70,6 +71,17 @@
|
|||
//static NS_DEFINE_CID(kUBidiUtilCID, NS_UNICHARBIDIUTIL_CID);
|
||||
#endif
|
||||
|
||||
// image copy stuff
|
||||
#include "nsIDOMHTMLImageElement.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsIImageLoadingContent.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIImage.h"
|
||||
|
||||
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
|
||||
static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID);
|
||||
static NS_DEFINE_CID(kHTMLConverterCID, NS_HTMLFORMATCONVERTER_CID);
|
||||
|
@ -379,3 +391,121 @@ nsresult nsCopySupport::IsPlainTextContext(nsISelection *aSel, nsIDocument *aDoc
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCopySupport::GetContents(const nsACString& aMimeType, PRUint32 aFlags, nsISelection *aSel, nsIDocument *aDoc, nsAString& outdata)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDocumentEncoder> docEncoder;
|
||||
|
||||
nsCAutoString encoderContractID(NS_DOC_ENCODER_CONTRACTID_BASE);
|
||||
encoderContractID.Append(aMimeType);
|
||||
|
||||
docEncoder = do_CreateInstance(encoderContractID.get());
|
||||
NS_ENSURE_TRUE(docEncoder, NS_ERROR_FAILURE);
|
||||
|
||||
PRUint32 flags = aFlags;
|
||||
|
||||
if (aMimeType.Equals("text/plain"))
|
||||
flags |= nsIDocumentEncoder::OutputPreformatted;
|
||||
|
||||
NS_ConvertASCIItoUCS2 unicodeMimeType(aMimeType);
|
||||
rv = docEncoder->Init(aDoc, unicodeMimeType, flags);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (aSel)
|
||||
{
|
||||
rv = docEncoder->SetSelection(aSel);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
// encode the selection
|
||||
return docEncoder->EncodeToString(outdata);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsCopySupport::ImageCopy(nsIDOMHTMLImageElement* imageElement, PRInt16 aClipboardID)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> imageNode = do_QueryInterface(imageElement, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!imageNode) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIImage> image;
|
||||
rv = GetImageFromDOMNode(imageNode, getter_AddRefs(image));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!image) return NS_ERROR_FAILURE;
|
||||
|
||||
// Get the Clipboard
|
||||
nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!clipboard) return NS_ERROR_FAILURE;
|
||||
|
||||
// Create a transferable for putting data on the Clipboard
|
||||
nsCOMPtr<nsITransferable> trans = do_CreateInstance(kCTransferableCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!trans) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsISupportsInterfacePointer> ptrPrimitive(do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!ptrPrimitive) return NS_ERROR_FAILURE;
|
||||
ptrPrimitive->SetData(image);
|
||||
|
||||
trans->SetTransferData(kNativeImageMime, ptrPrimitive, sizeof(nsISupports*));
|
||||
|
||||
// put the transferable on the clipboard
|
||||
return clipboard->SetData(trans, nsnull, aClipboardID);
|
||||
}
|
||||
|
||||
//
|
||||
// GetImage
|
||||
//
|
||||
// Given a dom node that's an image, finds the nsIImage associated with it.
|
||||
//
|
||||
// XXX see also nsContentAreaDragDrop, and factor!
|
||||
nsresult
|
||||
nsCopySupport::GetImageFromDOMNode(nsIDOMNode* inNode, nsIImage**outImage)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(outImage);
|
||||
*outImage = nsnull;
|
||||
|
||||
nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(inNode));
|
||||
if (!content) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIRequest> imgRequest;
|
||||
content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
|
||||
getter_AddRefs(imgRequest));
|
||||
if (!imgRequest) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIContainer> imgContainer;
|
||||
imgRequest->GetImage(getter_AddRefs(imgContainer));
|
||||
|
||||
if (!imgContainer) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> imgFrame;
|
||||
imgContainer->GetFrameAt(0, getter_AddRefs(imgFrame));
|
||||
|
||||
if (!imgFrame) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInterfaceRequestor> ir = do_QueryInterface(imgFrame);
|
||||
|
||||
if (!ir) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
return CallGetInterface(ir.get(), outImage);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -40,6 +40,13 @@
|
|||
|
||||
class nsISelection;
|
||||
class nsIDocument;
|
||||
class nsIDOMNode;
|
||||
class nsIDOMHTMLImageElement;
|
||||
class nsIContent;
|
||||
class nsIPresContext;
|
||||
class nsIPresShell;
|
||||
class nsIImageFrame;
|
||||
class nsIImage;
|
||||
class nsITransferable;
|
||||
|
||||
class nsCopySupport
|
||||
|
@ -50,4 +57,17 @@ class nsCopySupport
|
|||
static nsresult DoHooks(nsIDocument *aDoc, nsITransferable *aTrans,
|
||||
PRBool *aDoPutOnClipboard);
|
||||
static nsresult IsPlainTextContext(nsISelection *aSel, nsIDocument *aDoc, PRBool *aIsPlainTextContext);
|
||||
|
||||
// Get the selection, or entire document, in the format specified by the mime type
|
||||
// (text/html or text/plain). If aSel is non-null, use it, otherwise get the entire
|
||||
// doc.
|
||||
static nsresult GetContents(const nsACString& aMimeType, PRUint32 aFlags, nsISelection *aSel, nsIDocument *aDoc, nsAString& outdata);
|
||||
|
||||
static nsresult ImageCopy(nsIDOMHTMLImageElement* imageElement, PRInt16 aClipboardID);
|
||||
|
||||
protected:
|
||||
|
||||
// these are ripped from nsContentAreaDragDrop. This so needs factoring.
|
||||
static nsresult GetImageFromDOMNode(nsIDOMNode* inNode, nsIImage**outImage);
|
||||
|
||||
};
|
||||
|
|
|
@ -29,24 +29,66 @@
|
|||
|
||||
// these probably shouldn't live here, but in some central repository shared
|
||||
// by the entire app.
|
||||
#define kTextMime "text/plain"
|
||||
#define kUnicodeMime "text/unicode"
|
||||
#define kHTMLMime "text/html"
|
||||
#define kAOLMailMime "AOLMAIL"
|
||||
#define kPNGImageMime "image/png"
|
||||
#define kJPEGImageMime "image/jpg"
|
||||
#define kGIFImageMime "image/gif"
|
||||
#define kFileMime "application/x-moz-file"
|
||||
#define kURLMime "text/x-moz-url"
|
||||
#define kNativeImageMime "application/x-moz-nativeimage"
|
||||
#define kNativeHTMLMime "application/x-moz-nativehtml"
|
||||
#define kTextMime "text/plain"
|
||||
#define kUnicodeMime "text/unicode"
|
||||
#define kHTMLMime "text/html"
|
||||
#define kAOLMailMime "AOLMAIL"
|
||||
#define kPNGImageMime "image/png"
|
||||
#define kJPEGImageMime "image/jpg"
|
||||
#define kGIFImageMime "image/gif"
|
||||
#define kFileMime "application/x-moz-file"
|
||||
|
||||
#define kURLMime "text/x-moz-url" // data contains url\ntitle
|
||||
#define kURLDataMime "text/x-moz-url-data" // data contains url only
|
||||
#define kURLDescriptionMime "text/x-moz-url-desc" // data contains description
|
||||
#define kNativeImageMime "application/x-moz-nativeimage"
|
||||
#define kNativeHTMLMime "application/x-moz-nativehtml"
|
||||
|
||||
// the source URL for a file promise
|
||||
#define kFilePromiseURLMime "application/x-moz-file-promise-url"
|
||||
// a dataless flavor used to interact with the OS during file drags
|
||||
#define kFilePromiseMime "application/x-moz-file-promise"
|
||||
// a synthetic flavor, put into the transferable once we know the destination directory of a file drag
|
||||
#define kFilePromiseDirectoryMime "application/x-moz-file-promise-dir"
|
||||
|
||||
%}
|
||||
|
||||
|
||||
/**
|
||||
* nsIFlavorDataProvider allows a flavor to 'promise' data later,
|
||||
* supplying the data lazily.
|
||||
*
|
||||
* To use it, call setTransferData, passing the flavor string,
|
||||
* a nsIFlavorDataProvider QI'd to nsISupports, and a data size of 0.
|
||||
*
|
||||
* When someone calls getTransferData later, if the data size is
|
||||
* stored as 0, the nsISupports will be QI'd to nsIFlavorDataProvider,
|
||||
* and its getFlavorData called.
|
||||
*
|
||||
*/
|
||||
interface nsITransferable;
|
||||
|
||||
[scriptable, uuid(7E225E5F-711C-11D7-9FAE-000393636592)]
|
||||
interface nsIFlavorDataProvider : nsISupports
|
||||
{
|
||||
|
||||
/**
|
||||
* Retrieve the data from this data provider.
|
||||
*
|
||||
* @param aTransferable (in parameter) the transferable we're being called for.
|
||||
* @param aFlavor (in parameter) the flavor of data to retrieve
|
||||
* @param aData the data. Some variant of class in nsISupportsPrimitives.idl
|
||||
* @param aDataLen the length of the data
|
||||
*/
|
||||
void getFlavorData(in nsITransferable aTransferable, in string aFlavor, out nsISupports aData, out unsigned long aDataLen);
|
||||
};
|
||||
|
||||
|
||||
[scriptable, uuid(8B5314BC-DB01-11d2-96CE-0060B0FB9956)]
|
||||
interface nsITransferable : nsISupports
|
||||
{
|
||||
const long kFlavorHasDataProvider = 0;
|
||||
|
||||
/**
|
||||
* Computes a list of flavors (mime types as nsISupportsCString) that the transferable
|
||||
* can export, either through intrinsic knowledge or output data converters.
|
||||
|
@ -99,8 +141,9 @@ interface nsITransferable : nsISupports
|
|||
* will maintain its own copy the data, so it is not necessary to do that beforehand.
|
||||
*
|
||||
* @param aFlavor the flavor of data that is being set
|
||||
* @param aData the data, some variant of class in nsISupportsPrimitives.idl
|
||||
* @param aDataLen the length of the data
|
||||
* @param aData the data, some variant of class in nsISupportsPrimitives.idl,
|
||||
* or an nsIFlavorDataProvider (see above)
|
||||
* @param aDataLen the length of the data, or 0 if passing a nsIFlavorDataProvider
|
||||
*/
|
||||
void setTransferData ( in string aFlavor, in nsISupports aData, in unsigned long aDataLen ) ;
|
||||
|
||||
|
|
|
@ -211,13 +211,19 @@ nsClipboard :: SetNativeClipboardData ( PRInt32 aWhichClipboard )
|
|||
}
|
||||
} // if unicode
|
||||
else if ( strcmp(flavorStr, kPNGImageMime) == 0 || strcmp(flavorStr, kJPEGImageMime) == 0 ||
|
||||
strcmp(flavorStr, kGIFImageMime) == 0 ) {
|
||||
strcmp(flavorStr, kGIFImageMime) == 0 || strcmp(flavorStr, kNativeImageMime) == 0 ) {
|
||||
// we have an image, which is in the transferable as an nsIImage. Convert it
|
||||
// to PICT (PicHandle) and put those bits on the clipboard. The actual size
|
||||
// of the picture is the size of the handle, not sizeof(Picture).
|
||||
nsCOMPtr<nsISupports> imageSupports;
|
||||
errCode = mTransferable->GetTransferData ( flavorStr, getter_AddRefs(imageSupports), &dataSize );
|
||||
nsCOMPtr<nsIImageMac> image ( do_QueryInterface(imageSupports) );
|
||||
nsCOMPtr<nsISupports> transferSupports;
|
||||
errCode = mTransferable->GetTransferData ( flavorStr, getter_AddRefs(transferSupports), &dataSize );
|
||||
nsCOMPtr<nsISupportsInterfacePointer> ptrPrimitive(do_QueryInterface(transferSupports));
|
||||
nsCOMPtr<nsIImageMac> image;
|
||||
if (ptrPrimitive) {
|
||||
nsCOMPtr<nsISupports> primitiveData;
|
||||
ptrPrimitive->GetData(getter_AddRefs(primitiveData));
|
||||
image = do_QueryInterface(primitiveData);
|
||||
}
|
||||
if ( image ) {
|
||||
PicHandle picture = nsnull;
|
||||
image->ConvertToPICT ( &picture );
|
||||
|
|
|
@ -55,11 +55,10 @@
|
|||
#include "nsXPCOM.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsPrimitiveHelpers.h"
|
||||
#include "nsILocalFileMac.h"
|
||||
#include "nsWatchTask.h"
|
||||
#include "nsLinebreakConverter.h"
|
||||
|
||||
// rjc
|
||||
#include <Gestalt.h>
|
||||
|
@ -74,10 +73,16 @@
|
|||
#include "nsPoint.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsCarbonHelpers.h"
|
||||
#include "nsGfxUtils.h"
|
||||
|
||||
// file save stuff
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsILocalFileMac.h"
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsIXULContent.h"
|
||||
#endif
|
||||
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIImageMac.h"
|
||||
#include "nsIImage.h"
|
||||
|
@ -96,7 +101,10 @@ NS_IMPL_QUERY_INTERFACE3(nsDragService, nsIDragService, nsIDragSession, nsIDragS
|
|||
// DragService constructor
|
||||
//
|
||||
nsDragService::nsDragService()
|
||||
: mDragRef(0), mDataItems(nsnull), mImageDraggingSupported(PR_FALSE), mDragSendDataUPP(nsnull)
|
||||
: mDragSendDataUPP(nsnull)
|
||||
, mDragRef(0)
|
||||
, mDataItems(nsnull)
|
||||
, mImageDraggingSupported(PR_FALSE)
|
||||
{
|
||||
#if USE_TRANSLUCENT_DRAGS
|
||||
// check if the Drag Manager supports image dragging
|
||||
|
@ -123,7 +131,7 @@ nsDragService::~nsDragService()
|
|||
|
||||
|
||||
PRBool
|
||||
nsDragService :: ComputeGlobalRectFromFrame ( nsIDOMNode* aDOMNode, Rect & outScreenRect )
|
||||
nsDragService::ComputeGlobalRectFromFrame ( nsIDOMNode* aDOMNode, Rect & outScreenRect )
|
||||
{
|
||||
NS_ASSERTION ( aDOMNode, "Oopps, no DOM node" );
|
||||
|
||||
|
@ -165,7 +173,6 @@ nsDragService :: ComputeGlobalRectFromFrame ( nsIDOMNode* aDOMNode, Rect & outSc
|
|||
//
|
||||
|
||||
nsRect aRect(0,0,0,0);
|
||||
nsIView *parentView = nsnull;
|
||||
aFrame->GetRect(aRect);
|
||||
|
||||
// Find offset from our view
|
||||
|
@ -218,7 +225,7 @@ nsDragService :: ComputeGlobalRectFromFrame ( nsIDOMNode* aDOMNode, Rect & outSc
|
|||
// Do all the work to kick it off.
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsDragService :: InvokeDragSession (nsIDOMNode *aDOMNode, nsISupportsArray * aTransferableArray, nsIScriptableRegion * aDragRgn, PRUint32 aActionType)
|
||||
nsDragService::InvokeDragSession (nsIDOMNode *aDOMNode, nsISupportsArray * aTransferableArray, nsIScriptableRegion * aDragRgn, PRUint32 aActionType)
|
||||
{
|
||||
::InitCursor();
|
||||
nsBaseDragService::InvokeDragSession ( aDOMNode, aTransferableArray, aDragRgn, aActionType );
|
||||
|
@ -232,10 +239,6 @@ nsDragService :: InvokeDragSession (nsIDOMNode *aDOMNode, nsISupportsArray * aTr
|
|||
printf("**** created drag ref %ld\n", theDragRef);
|
||||
#endif
|
||||
|
||||
// add the flavors from the transferables. Cache this array for the send data proc
|
||||
mDataItems = aTransferableArray;
|
||||
RegisterDragItemsAndFlavors ( aTransferableArray ) ;
|
||||
|
||||
Rect frameRect = { 0, 0, 0, 0 };
|
||||
RgnHandle theDragRgn = ::NewRgn();
|
||||
::RectRgn(theDragRgn, &frameRect);
|
||||
|
@ -253,6 +256,10 @@ printf("**** created drag ref %ld\n", theDragRef);
|
|||
else
|
||||
BuildDragRegion ( aDragRgn, aDOMNode, theDragRgn );
|
||||
|
||||
// add the flavors from the transferables. Cache this array for the send data proc
|
||||
mDataItems = aTransferableArray;
|
||||
RegisterDragItemsAndFlavors(aTransferableArray, theDragRgn);
|
||||
|
||||
// we have to synthesize the native event because we may be called from JavaScript
|
||||
// through XPConnect. In that case, we only have a DOM event and no way to
|
||||
// get to the native event. As a consequence, we just always fake it.
|
||||
|
@ -307,7 +314,7 @@ printf("**** disposing drag ref %ld\n", theDragRef);
|
|||
// Returns PR_TRUE if the region is something that can be used with SetDragImage()
|
||||
//
|
||||
PRBool
|
||||
nsDragService :: BuildDragRegion ( nsIScriptableRegion* inRegion, nsIDOMNode* inNode, RgnHandle ioDragRgn )
|
||||
nsDragService::BuildDragRegion ( nsIScriptableRegion* inRegion, nsIDOMNode* inNode, RgnHandle ioDragRgn )
|
||||
{
|
||||
PRBool retVal = PR_TRUE;
|
||||
nsCOMPtr<nsIRegion> geckoRegion;
|
||||
|
@ -377,13 +384,17 @@ nsDragService :: BuildDragRegion ( nsIScriptableRegion* inRegion, nsIDOMNode* in
|
|||
// requested.
|
||||
//
|
||||
void
|
||||
nsDragService :: RegisterDragItemsAndFlavors ( nsISupportsArray * inArray )
|
||||
nsDragService::RegisterDragItemsAndFlavors(nsISupportsArray* inArray, RgnHandle inDragRgn)
|
||||
{
|
||||
const FlavorFlags flags = 0;
|
||||
|
||||
unsigned int numDragItems = 0;
|
||||
Rect dragRgnBounds = {0, 0, 0, 0};
|
||||
if (inDragRgn)
|
||||
GetRegionBounds(inDragRgn, &dragRgnBounds);
|
||||
|
||||
PRUint32 numDragItems = 0;
|
||||
inArray->Count ( &numDragItems ) ;
|
||||
for ( int itemIndex = 0; itemIndex < numDragItems; ++itemIndex ) {
|
||||
for ( PRUint32 itemIndex = 0; itemIndex < numDragItems; ++itemIndex ) {
|
||||
nsMimeMapperMac theMapper;
|
||||
|
||||
nsCOMPtr<nsISupports> genericItem;
|
||||
|
@ -394,25 +405,39 @@ nsDragService :: RegisterDragItemsAndFlavors ( nsISupportsArray * inArray )
|
|||
if ( NS_SUCCEEDED(currItem->FlavorsTransferableCanExport(getter_AddRefs(flavorList))) ) {
|
||||
PRUint32 numFlavors;
|
||||
flavorList->Count ( &numFlavors );
|
||||
for ( int flavorIndex = 0; flavorIndex < numFlavors; ++flavorIndex ) {
|
||||
for ( PRUint32 flavorIndex = 0; flavorIndex < numFlavors; ++flavorIndex ) {
|
||||
|
||||
nsCOMPtr<nsISupports> genericWrapper;
|
||||
flavorList->GetElementAt ( flavorIndex, getter_AddRefs(genericWrapper) );
|
||||
nsCOMPtr<nsISupportsCString> currentFlavor ( do_QueryInterface(genericWrapper) );
|
||||
if ( currentFlavor ) {
|
||||
nsXPIDLCString flavorStr;
|
||||
currentFlavor->ToString ( getter_Copies(flavorStr) );
|
||||
FlavorType macOSFlavor = theMapper.MapMimeTypeToMacOSType(flavorStr);
|
||||
::AddDragItemFlavor ( mDragRef, itemIndex, macOSFlavor, NULL, 0, flags );
|
||||
|
||||
// If we advertise text/unicode, then make sure we add 'TEXT' to the list
|
||||
// of flavors supported since we will do the conversion ourselves in GetDataForFlavor()
|
||||
if ( strcmp(flavorStr, kUnicodeMime) == 0 ) {
|
||||
theMapper.MapMimeTypeToMacOSType(kTextMime);
|
||||
::AddDragItemFlavor ( mDragRef, itemIndex, 'TEXT', NULL, 0, flags );
|
||||
::AddDragItemFlavor ( mDragRef, itemIndex, 'styl', NULL, 0, flags );
|
||||
}
|
||||
}
|
||||
if ( currentFlavor ) {
|
||||
nsCAutoString flavorStr;
|
||||
currentFlavor->GetData(flavorStr);
|
||||
FlavorType macOSFlavor = theMapper.MapMimeTypeToMacOSType(flavorStr.get());
|
||||
|
||||
if (macOSFlavor == kDragFlavorTypePromiseHFS) {
|
||||
// we got kFilePromiseMime
|
||||
// kDragFlavorTypePromiseHFS is special. See http://developer.apple.com/technotes/tn/tn1085.html
|
||||
PromiseHFSFlavor promiseData;
|
||||
promiseData.fileType = 0; // let the file extension prevail!
|
||||
promiseData.fileCreator = 0;
|
||||
promiseData.fdFlags = 0;
|
||||
promiseData.promisedFlavor = kDragPromisedFlavor;
|
||||
|
||||
::AddDragItemFlavor(mDragRef, itemIndex, kDragFlavorTypePromiseHFS, &promiseData, sizeof(promiseData), flavorNotSaved);
|
||||
::AddDragItemFlavor(mDragRef, itemIndex, kDragPromisedFlavor, NULL, 0, flavorNotSaved);
|
||||
}
|
||||
else
|
||||
::AddDragItemFlavor(mDragRef, itemIndex, macOSFlavor, NULL, 0, flags);
|
||||
|
||||
// If we advertise text/unicode, then make sure we add 'TEXT' to the list
|
||||
// of flavors supported since we will do the conversion ourselves in GetDataForFlavor()
|
||||
if ( strcmp(flavorStr.get(), kUnicodeMime) == 0 ) {
|
||||
theMapper.MapMimeTypeToMacOSType(kTextMime);
|
||||
::AddDragItemFlavor ( mDragRef, itemIndex, 'TEXT', NULL, 0, flags );
|
||||
::AddDragItemFlavor ( mDragRef, itemIndex, 'styl', NULL, 0, flags );
|
||||
}
|
||||
}
|
||||
|
||||
} // foreach flavor in item
|
||||
} // if valid flavor list
|
||||
|
@ -428,6 +453,8 @@ nsDragService :: RegisterDragItemsAndFlavors ( nsISupportsArray * inArray )
|
|||
::AddDragItemFlavor ( mDragRef, itemIndex, nsMimeMapperMac::MappingFlavor(),
|
||||
mapping, mappingLen, flags );
|
||||
nsCRT::free ( mapping );
|
||||
|
||||
::SetDragItemBounds(mDragRef, itemIndex, &dragRgnBounds);
|
||||
}
|
||||
|
||||
} // foreach drag item
|
||||
|
@ -443,7 +470,7 @@ nsDragService :: RegisterDragItemsAndFlavors ( nsISupportsArray * inArray )
|
|||
// stop as soon as we find a match.
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsDragService :: GetData ( nsITransferable * aTransferable, PRUint32 aItemIndex )
|
||||
nsDragService::GetData ( nsITransferable * aTransferable, PRUint32 aItemIndex )
|
||||
{
|
||||
nsresult errCode = NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -473,33 +500,33 @@ nsDragService :: GetData ( nsITransferable * aTransferable, PRUint32 aItemIndex
|
|||
// implicitly handles conversions.
|
||||
PRUint32 cnt;
|
||||
flavorList->Count ( &cnt );
|
||||
for ( int i = 0; i < cnt; ++i ) {
|
||||
for (PRUint32 i = 0; i < cnt; ++i) {
|
||||
nsCOMPtr<nsISupports> genericWrapper;
|
||||
flavorList->GetElementAt ( i, getter_AddRefs(genericWrapper) );
|
||||
nsCOMPtr<nsISupportsCString> currentFlavor ( do_QueryInterface(genericWrapper) );
|
||||
if ( currentFlavor ) {
|
||||
// find MacOS flavor (but don't add it if it's not there)
|
||||
nsXPIDLCString flavorStr;
|
||||
currentFlavor->ToString ( getter_Copies(flavorStr) );
|
||||
FlavorType macOSFlavor = theMapper.MapMimeTypeToMacOSType(flavorStr, PR_FALSE);
|
||||
nsCAutoString flavorStr;
|
||||
currentFlavor->GetData(flavorStr);
|
||||
FlavorType macOSFlavor = theMapper.MapMimeTypeToMacOSType(flavorStr.get(), PR_FALSE);
|
||||
#if DEBUG_DD
|
||||
printf("looking for data in type %s, mac flavor %ld\n", NS_STATIC_CAST(const char*,flavorStr), macOSFlavor);
|
||||
printf("looking for data in type %s, mac flavor %ld\n", flavorStr.get(), macOSFlavor);
|
||||
#endif
|
||||
|
||||
// check if it is present in the current drag item.
|
||||
FlavorFlags unused;
|
||||
PRBool dataFound = PR_FALSE;
|
||||
void* dataBuff;
|
||||
void* dataBuff = nsnull;
|
||||
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;
|
||||
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,
|
||||
// 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 ( strcmp(flavorStr.get(), kUnicodeMime) == 0 ) {
|
||||
if ( ::GetFlavorFlags(mDragRef, itemRef, 'TEXT', &unused) == noErr ) {
|
||||
|
||||
// if 'styl' is available, we can get a script of the first run
|
||||
|
@ -554,19 +581,35 @@ printf("looking for data in type %s, mac flavor %ld\n", NS_STATIC_CAST(const cha
|
|||
} // else we try one last ditch effort to find our data
|
||||
|
||||
if ( dataFound ) {
|
||||
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||
if ( strcmp(flavorStr, kFileMime) == 0 ) {
|
||||
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||
|
||||
if ( strcmp(flavorStr.get(), kFileMime) == 0 ) {
|
||||
// we have a HFSFlavor struct in |dataBuff|. Create an nsLocalFileMac object.
|
||||
HFSFlavor* fileData = NS_REINTERPRET_CAST(HFSFlavor*, dataBuff);
|
||||
NS_ASSERTION ( sizeof(HFSFlavor) == dataSize, "Ooops, we realy don't have a HFSFlavor" );
|
||||
NS_ASSERTION ( sizeof(HFSFlavor) == dataSize, "Ooops, we really don't have a HFSFlavor" );
|
||||
nsCOMPtr<nsILocalFileMac> file;
|
||||
if ( NS_SUCCEEDED(NS_NewLocalFileWithFSSpec(&fileData->fileSpec, PR_TRUE, getter_AddRefs(file))) )
|
||||
genericDataWrapper = do_QueryInterface(file);
|
||||
}
|
||||
else if ((strcmp(flavorStr.get(), kURLDataMime) == 0) || (strcmp(flavorStr.get(), kURLDescriptionMime) == 0)) {
|
||||
// need to convert platform data to unicode
|
||||
const char* castedText = NS_REINTERPRET_CAST(char*, dataBuff);
|
||||
PRUnichar* convertedText = nsnull;
|
||||
PRInt32 convertedTextLen = 0;
|
||||
nsPrimitiveHelpers::ConvertPlatformPlainTextToUnicode(castedText, dataSize,
|
||||
&convertedText, &convertedTextLen);
|
||||
if (convertedText)
|
||||
{
|
||||
nsMemory::Free(dataBuff);
|
||||
dataBuff = convertedText;
|
||||
dataSize = convertedTextLen * 2;
|
||||
nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr.get(), (void *)dataBuff, dataSize, getter_AddRefs(genericDataWrapper));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// we probably have some form of text. The DOM only wants LF, so convert k
|
||||
// from MacOS line endings to DOM line endings.
|
||||
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks ( flavorStr, &dataBuff, NS_REINTERPRET_CAST(int*, &dataSize) );
|
||||
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks(flavorStr.get(), &dataBuff, NS_REINTERPRET_CAST(int*, &dataSize));
|
||||
|
||||
unsigned char *dataPtr = (unsigned char *) dataBuff;
|
||||
#if TARGET_CARBON
|
||||
|
@ -582,15 +625,14 @@ printf("looking for data in type %s, mac flavor %ld\n", NS_STATIC_CAST(const cha
|
|||
dataPtr += sizeof(PRUnichar);
|
||||
}
|
||||
#endif
|
||||
nsPrimitiveHelpers::CreatePrimitiveForData ( flavorStr, (void *) dataPtr, dataSize, getter_AddRefs(genericDataWrapper) );
|
||||
nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr.get(), (void *) dataPtr, dataSize, getter_AddRefs(genericDataWrapper));
|
||||
}
|
||||
|
||||
// put it into the transferable.
|
||||
errCode = aTransferable->SetTransferData ( flavorStr, genericDataWrapper, dataSize );
|
||||
#ifdef NS_DEBUG
|
||||
errCode = aTransferable->SetTransferData(flavorStr.get(), genericDataWrapper, dataSize);
|
||||
#ifdef NS_DEBUG
|
||||
if ( errCode != NS_OK ) printf("nsDragService:: Error setting data into transferable\n");
|
||||
#endif
|
||||
|
||||
#endif
|
||||
nsMemory::Free ( dataBuff );
|
||||
errCode = NS_OK;
|
||||
|
||||
|
@ -618,7 +660,7 @@ printf("looking for data in type %s, mac flavor %ld\n", NS_STATIC_CAST(const cha
|
|||
// ¥¥¥Êand index to this API
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsDragService :: IsDataFlavorSupported(const char *aDataFlavor, PRBool *_retval)
|
||||
nsDragService::IsDataFlavorSupported(const char *aDataFlavor, PRBool *_retval)
|
||||
{
|
||||
if ( !_retval )
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
@ -670,7 +712,7 @@ nsDragService :: IsDataFlavorSupported(const char *aDataFlavor, PRBool *_retval)
|
|||
// Returns the number of drop items present in the current drag.
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsDragService :: GetNumDropItems ( PRUint32 * aNumItems )
|
||||
nsDragService::GetNumDropItems ( PRUint32 * aNumItems )
|
||||
{
|
||||
// we have to put it into a short first because that's what the MacOS API's expect.
|
||||
// After it's in a short, getting it into a long is no problem. Oh well.
|
||||
|
@ -690,7 +732,7 @@ nsDragService :: GetNumDropItems ( PRUint32 * aNumItems )
|
|||
// current dragRef w/out resorting to knowing the internals of the implementation
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsDragService :: SetDragReference ( DragReference aDragRef )
|
||||
nsDragService::SetDragReference ( DragReference aDragRef )
|
||||
{
|
||||
mDragRef = aDragRef;
|
||||
return NS_OK;
|
||||
|
@ -712,16 +754,16 @@ nsDragService :: SetDragReference ( DragReference aDragRef )
|
|||
// and pass that along.
|
||||
//
|
||||
pascal OSErr
|
||||
nsDragService :: DragSendDataProc ( FlavorType inFlavor, void* inRefCon, ItemReference inItemRef,
|
||||
DragReference inDragRef )
|
||||
nsDragService::DragSendDataProc(FlavorType inFlavor, void* inRefCon, ItemReference inItemRef,
|
||||
DragReference inDragRef)
|
||||
{
|
||||
OSErr retVal = noErr;
|
||||
nsDragService* self = NS_STATIC_CAST(nsDragService*, inRefCon);
|
||||
NS_ASSERTION ( self, "Refcon not set correctly for DragSendDataProc" );
|
||||
if ( self ) {
|
||||
nsDragService* dragService = NS_STATIC_CAST(nsDragService*, inRefCon);
|
||||
NS_ASSERTION ( dragService, "Refcon not set correctly for DragSendDataProc" );
|
||||
if (dragService) {
|
||||
void* data = nsnull;
|
||||
PRUint32 dataSize = 0;
|
||||
retVal = self->GetDataForFlavor ( self->mDataItems, inDragRef, inItemRef, inFlavor, &data, &dataSize );
|
||||
retVal = dragService->GetDataForFlavor(dragService->mDataItems, inDragRef, inItemRef, inFlavor, &data, &dataSize);
|
||||
if ( retVal == noErr ) {
|
||||
// make the data accessable to the DragManager
|
||||
retVal = ::SetDragItemFlavorData ( inDragRef, inItemRef, inFlavor, data, dataSize, 0 );
|
||||
|
@ -750,141 +792,210 @@ nsDragService :: DragSendDataProc ( FlavorType inFlavor, void* inRefCon, ItemRef
|
|||
// wouldn't have been allowed to look for unicode.
|
||||
//
|
||||
OSErr
|
||||
nsDragService :: GetDataForFlavor ( nsISupportsArray* inDragItems, DragReference inDragRef, unsigned int inItemIndex,
|
||||
FlavorType inFlavor, void** outData, unsigned int* outDataSize )
|
||||
nsDragService::GetDataForFlavor(nsISupportsArray* inDragItems, DragReference inDragRef, unsigned int inItemIndex,
|
||||
FlavorType inFlavor, void** outData, unsigned int* outDataSize)
|
||||
{
|
||||
if ( !inDragItems || !inDragRef )
|
||||
return paramErr;
|
||||
|
||||
*outData = nsnull;
|
||||
*outDataSize = 0;
|
||||
|
||||
OSErr retVal = noErr;
|
||||
nsresult rv;
|
||||
|
||||
// (assumes that the items were placed into the transferable as nsITranferable*'s, not nsISupports*'s.)
|
||||
nsCOMPtr<nsISupports> genericItem;
|
||||
inDragItems->GetElementAt ( inItemIndex, getter_AddRefs(genericItem) );
|
||||
nsCOMPtr<nsITransferable> item ( do_QueryInterface(genericItem) );
|
||||
if ( item ) {
|
||||
nsCAutoString mimeFlavor;
|
||||
inDragItems->GetElementAt(inItemIndex, getter_AddRefs(genericItem));
|
||||
nsCOMPtr<nsITransferable> item(do_QueryInterface(genericItem));
|
||||
if (!item) return cantGetFlavorErr;
|
||||
|
||||
// create a mime mapper to help us out based on data in a special flavor for this item.
|
||||
char* mappings = LookupMimeMappingsForItem(inDragRef, inItemIndex) ;
|
||||
nsMimeMapperMac theMapper ( mappings );
|
||||
theMapper.MapMacOSTypeToMimeType ( inFlavor, mimeFlavor );
|
||||
nsMemory::Free ( mappings );
|
||||
char* mappings = LookupMimeMappingsForItem(inDragRef, inItemIndex);
|
||||
nsMimeMapperMac theMapper(mappings);
|
||||
|
||||
nsCAutoString mimeFlavor;
|
||||
theMapper.MapMacOSTypeToMimeType(inFlavor, mimeFlavor);
|
||||
nsMemory::Free(mappings);
|
||||
|
||||
// if someone was asking for text/plain, lookup unicode instead so we can convert it.
|
||||
PRBool needToDoConversionToPlainText = PR_FALSE;
|
||||
const char* actualFlavor = mimeFlavor.get();
|
||||
if ( strcmp(mimeFlavor.get(), kTextMime) == 0 || inFlavor == 'styl' )
|
||||
{
|
||||
actualFlavor = kUnicodeMime;
|
||||
needToDoConversionToPlainText = PR_TRUE;
|
||||
}
|
||||
else if (strcmp(actualFlavor, kURLDataMime) == 0)
|
||||
{
|
||||
needToDoConversionToPlainText = PR_TRUE;
|
||||
}
|
||||
else if (strcmp(actualFlavor, kURLDescriptionMime) == 0)
|
||||
{
|
||||
needToDoConversionToPlainText = PR_TRUE;
|
||||
}
|
||||
else if (strcmp(actualFlavor, kFilePromiseMime) == 0)
|
||||
{
|
||||
/* Here's how file dragging works:
|
||||
|
||||
// if someone was asking for text/plain, lookup unicode instead so we can convert it.
|
||||
PRBool needToDoConversionToPlainText = PR_FALSE;
|
||||
const char* actualFlavor = mimeFlavor.get();
|
||||
if ( strcmp(mimeFlavor.get(),kTextMime) == 0 ||
|
||||
inFlavor == 'styl' ) {
|
||||
actualFlavor = kUnicodeMime;
|
||||
needToDoConversionToPlainText = PR_TRUE;
|
||||
}
|
||||
else
|
||||
actualFlavor = mimeFlavor.get();
|
||||
Drag code adds a kFilePromiseMime flavor to the transferable, with an
|
||||
nsIFlavorDataProvider.
|
||||
It also adds a kFilePromiseURLMime flavor, with a string containing the source
|
||||
url.
|
||||
|
||||
We map that to the OS drag flavor kDragFlavorTypePromiseHFS, which promises
|
||||
the flavor kDragPromisedFlavor. The OS asks for kDragPromisedFlavor, and we
|
||||
map that back to kFilePromiseMime.
|
||||
|
||||
When asked for kFilePromiseMime data (here), we figure out the drop location from
|
||||
the OS, and set that as an nsILocalFile on the kFilePromiseDirectoryMime flavor. We then
|
||||
call GetTransferData() for the kFilePromiseMime flavor, which triggers
|
||||
the nsIFlavorDataProvider to do the save.
|
||||
*/
|
||||
|
||||
nsCOMPtr<nsILocalFile> dropDirectory;
|
||||
OSErr err = GetHFSPromiseDropDirectory(inDragRef, inItemIndex, inFlavor, getter_AddRefs(dropDirectory));
|
||||
if (err != noErr) return err;
|
||||
|
||||
// now add a flavor to the transferable
|
||||
nsCOMPtr<nsISupports> localFileISupports = do_QueryInterface(dropDirectory);
|
||||
item->SetTransferData(kFilePromiseDirectoryMime, localFileISupports, 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;
|
||||
rv = item->GetTransferData(kFilePromiseMime, getter_AddRefs(fileDataPrimitive), &dataSize);
|
||||
if (NS_FAILED(rv)) return cantGetFlavorErr;
|
||||
|
||||
// if we successfully saved, tell the Drag Manager
|
||||
nsCOMPtr<nsILocalFile> resultFile = do_QueryInterface(fileDataPrimitive);
|
||||
if (resultFile)
|
||||
return SetDropFileInDrag(inDragRef, inItemIndex, inFlavor, resultFile);
|
||||
|
||||
// something went wrong.
|
||||
return cantGetFlavorErr;
|
||||
}
|
||||
else if (strcmp(actualFlavor, kNativeImageMime) == 0)
|
||||
{
|
||||
PRUint32 dataSize = 0;
|
||||
nsCOMPtr<nsISupports> transferSupports;
|
||||
rv = item->GetTransferData(actualFlavor, getter_AddRefs(transferSupports), &dataSize);
|
||||
if (NS_FAILED(rv)) return cantGetFlavorErr;
|
||||
|
||||
nsCOMPtr<nsISupportsInterfacePointer> ptrPrimitive(do_QueryInterface(transferSupports));
|
||||
if (!ptrPrimitive) return cantGetFlavorErr;
|
||||
|
||||
nsCOMPtr<nsISupports> primitiveData;
|
||||
ptrPrimitive->GetData(getter_AddRefs(primitiveData));
|
||||
nsCOMPtr<nsIImageMac> image = do_QueryInterface(primitiveData);
|
||||
if (!image) return cantGetFlavorErr;
|
||||
|
||||
*outDataSize = 0;
|
||||
nsCOMPtr<nsISupports> data;
|
||||
if ( NS_SUCCEEDED(item->GetTransferData(actualFlavor, getter_AddRefs(data), outDataSize)) ) {
|
||||
if ( strcmp(actualFlavor, kNativeImageMime) == 0 ) {
|
||||
// unwrap the image from its nsISupportsPrimitive wrapper
|
||||
nsCOMPtr<nsISupportsInterfacePointer> ptr(do_QueryInterface(data));
|
||||
nsCOMPtr<nsIImage> image;
|
||||
ptr->GetData(getter_AddRefs(image));
|
||||
|
||||
// we have an image, which is in the transferable as an nsIImage. Convert it
|
||||
// to PICT (PicHandle) and put those bits on the clipboard. The actual size
|
||||
// of the picture is the size of the handle, not sizeof(Picture).
|
||||
nsCOMPtr<nsIImageMac> imageMac ( do_QueryInterface(image) );
|
||||
if ( imageMac ) {
|
||||
PicHandle picture = nsnull;
|
||||
imageMac->ConvertToPICT ( &picture );
|
||||
*outDataSize = ::GetHandleSize((Handle)picture);
|
||||
*outData = nsMemory::Alloc(*outDataSize);
|
||||
::HLock((Handle)picture);
|
||||
::BlockMoveData(*picture, *outData, *outDataSize);
|
||||
::HUnlock((Handle)picture);
|
||||
::KillPicture(picture);
|
||||
}
|
||||
else
|
||||
NS_WARNING ( "Image isn't an nsIImageMac in transferable" );
|
||||
}
|
||||
else {
|
||||
nsPrimitiveHelpers::CreateDataFromPrimitive ( actualFlavor, data, outData, *outDataSize );
|
||||
|
||||
// if required, do the extra work to convert unicode to plain text and replace the output
|
||||
// values with the plain text.
|
||||
if ( needToDoConversionToPlainText ) {
|
||||
char* plainTextData = nsnull;
|
||||
PRUnichar* castedUnicode = NS_REINTERPRET_CAST(PRUnichar*, *outData);
|
||||
PRInt32 plainTextLen = 0;
|
||||
nsresult rv =
|
||||
nsPrimitiveHelpers::ConvertUnicodeToPlatformPlainText ( castedUnicode, *outDataSize / 2, &plainTextData, &plainTextLen );
|
||||
PicHandle picture = nsnull;
|
||||
image->ConvertToPICT(&picture);
|
||||
if (!picture) return cantGetFlavorErr;
|
||||
|
||||
ScriptCodeRun *scriptCodeRuns = nsnull;
|
||||
PRInt32 scriptRunOutLen;
|
||||
|
||||
// if characters are not mapped from Unicode then try native API to convert to
|
||||
// available script
|
||||
if (rv == NS_ERROR_UENC_NOMAPPING) {
|
||||
if (plainTextData) {
|
||||
nsMemory::Free(plainTextData);
|
||||
plainTextData = nsnull;
|
||||
}
|
||||
rv = nsMacNativeUnicodeConverter::ConvertUnicodetoScript(castedUnicode,
|
||||
*outDataSize / sizeof(PRUnichar),
|
||||
&plainTextData,
|
||||
&plainTextLen,
|
||||
&scriptCodeRuns,
|
||||
&scriptRunOutLen);
|
||||
}
|
||||
else if (NS_SUCCEEDED(rv)) {
|
||||
// create a single run with the default system script
|
||||
scriptCodeRuns = NS_REINTERPRET_CAST(ScriptCodeRun*,
|
||||
nsMemory::Alloc(sizeof(ScriptCodeRun)));
|
||||
if (scriptCodeRuns) {
|
||||
scriptCodeRuns[0].offset = 0;
|
||||
scriptCodeRuns[0].script = (ScriptCode) ::GetScriptManagerVariable(smSysScript);
|
||||
scriptRunOutLen = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( plainTextData && *outData ) {
|
||||
nsMemory::Free(*outData);
|
||||
*outData = nsnull;
|
||||
*outDataSize = 0;
|
||||
|
||||
if (inFlavor != 'styl') {
|
||||
*outData = plainTextData;
|
||||
*outDataSize = plainTextLen;
|
||||
}
|
||||
else {
|
||||
nsMemory::Free(plainTextData); // discard 'TEXT'
|
||||
|
||||
char *stylData;
|
||||
PRInt32 stylLen;
|
||||
// create 'styl' from the script runs
|
||||
if (scriptCodeRuns) {
|
||||
rv = CreateStylFromScriptRuns(scriptCodeRuns,
|
||||
scriptRunOutLen,
|
||||
&stylData,
|
||||
&stylLen);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*outData = stylData;
|
||||
*outDataSize = stylLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
retVal = cantGetFlavorErr;
|
||||
if (scriptCodeRuns)
|
||||
nsMemory::Free(scriptCodeRuns);
|
||||
}
|
||||
}
|
||||
PRInt32 pictSize = ::GetHandleSize((Handle)picture);
|
||||
char* pictData = nsnull;
|
||||
if (pictSize > 0)
|
||||
pictData = (char*)nsMemory::Alloc(pictSize);
|
||||
if (pictData) {
|
||||
::BlockMoveData(*picture, pictData, pictSize); // doesn't move memory
|
||||
*outData = (void*)pictData;
|
||||
*outDataSize = pictSize;
|
||||
retVal = noErr;
|
||||
}
|
||||
else
|
||||
retVal = cantGetFlavorErr;
|
||||
} // if valid item
|
||||
|
||||
::KillPicture(picture);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> data;
|
||||
if (NS_SUCCEEDED(item->GetTransferData(actualFlavor, getter_AddRefs(data), outDataSize)))
|
||||
{
|
||||
nsPrimitiveHelpers::CreateDataFromPrimitive ( actualFlavor, data, outData, *outDataSize );
|
||||
|
||||
// Convert unix to mac linebreaks, since mac linebreaks are required for clipboard compatibility.
|
||||
// I'm making the assumption here that the substitution will be entirely in-place, since both
|
||||
// types of line breaks are 1-byte.
|
||||
PRUnichar* castedUnicode = NS_REINTERPRET_CAST(PRUnichar*, *outData);
|
||||
nsLinebreakConverter::ConvertUnicharLineBreaksInSitu(&castedUnicode,
|
||||
nsLinebreakConverter::eLinebreakUnix,
|
||||
nsLinebreakConverter::eLinebreakMac,
|
||||
*outDataSize / sizeof(PRUnichar), nsnull);
|
||||
|
||||
// if required, do the extra work to convert unicode to plain text and replace the output
|
||||
// values with the plain text.
|
||||
if ( needToDoConversionToPlainText ) {
|
||||
char* plainTextData = nsnull;
|
||||
PRUnichar* castedUnicode = NS_REINTERPRET_CAST(PRUnichar*, *outData);
|
||||
PRInt32 plainTextLen = 0;
|
||||
nsresult rv =
|
||||
nsPrimitiveHelpers::ConvertUnicodeToPlatformPlainText ( castedUnicode, *outDataSize / 2, &plainTextData, &plainTextLen );
|
||||
|
||||
ScriptCodeRun *scriptCodeRuns = nsnull;
|
||||
PRInt32 scriptRunOutLen;
|
||||
|
||||
// if characters are not mapped from Unicode then try native API to convert to
|
||||
// available script
|
||||
if (rv == NS_ERROR_UENC_NOMAPPING) {
|
||||
if (plainTextData) {
|
||||
nsMemory::Free(plainTextData);
|
||||
plainTextData = nsnull;
|
||||
}
|
||||
rv = nsMacNativeUnicodeConverter::ConvertUnicodetoScript(castedUnicode,
|
||||
*outDataSize / sizeof(PRUnichar),
|
||||
&plainTextData,
|
||||
&plainTextLen,
|
||||
&scriptCodeRuns,
|
||||
&scriptRunOutLen);
|
||||
}
|
||||
else if (NS_SUCCEEDED(rv)) {
|
||||
// create a single run with the default system script
|
||||
scriptCodeRuns = NS_REINTERPRET_CAST(ScriptCodeRun*,
|
||||
nsMemory::Alloc(sizeof(ScriptCodeRun)));
|
||||
if (scriptCodeRuns) {
|
||||
scriptCodeRuns[0].offset = 0;
|
||||
scriptCodeRuns[0].script = (ScriptCode) ::GetScriptManagerVariable(smSysScript);
|
||||
scriptRunOutLen = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( plainTextData && *outData ) {
|
||||
nsMemory::Free(*outData);
|
||||
*outData = nsnull;
|
||||
*outDataSize = 0;
|
||||
|
||||
if (inFlavor != 'styl') {
|
||||
*outData = plainTextData;
|
||||
*outDataSize = plainTextLen;
|
||||
}
|
||||
else {
|
||||
nsMemory::Free(plainTextData); // discard 'TEXT'
|
||||
|
||||
char *stylData;
|
||||
PRInt32 stylLen;
|
||||
// create 'styl' from the script runs
|
||||
if (scriptCodeRuns) {
|
||||
rv = CreateStylFromScriptRuns(scriptCodeRuns,
|
||||
scriptRunOutLen,
|
||||
&stylData,
|
||||
&stylLen);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*outData = stylData;
|
||||
*outDataSize = stylLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
retVal = cantGetFlavorErr;
|
||||
if (scriptCodeRuns)
|
||||
nsMemory::Free(scriptCodeRuns);
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
|
||||
|
@ -901,7 +1012,7 @@ nsDragService :: GetDataForFlavor ( nsISupportsArray* inDragItems, DragReference
|
|||
// Caller is responsible for deleting the memory.
|
||||
//
|
||||
char*
|
||||
nsDragService :: LookupMimeMappingsForItem ( DragReference inDragRef, ItemReference inItemRef )
|
||||
nsDragService::LookupMimeMappingsForItem ( DragReference inDragRef, ItemReference inItemRef )
|
||||
{
|
||||
char* mapperData = nsnull;
|
||||
PRInt32 mapperSize = 0;
|
||||
|
@ -939,7 +1050,7 @@ nsDragService :: LookupMimeMappingsForItem ( DragReference inDragRef, ItemRefere
|
|||
// the data for whatever reason.
|
||||
//
|
||||
nsresult
|
||||
nsDragService :: ExtractDataFromOS ( DragReference inDragRef, ItemReference inItemRef, ResType inFlavor,
|
||||
nsDragService::ExtractDataFromOS ( DragReference inDragRef, ItemReference inItemRef, ResType inFlavor,
|
||||
void** outBuffer, PRInt32* outBuffSize )
|
||||
{
|
||||
if ( !outBuffer || !outBuffSize || !inFlavor )
|
||||
|
@ -985,7 +1096,7 @@ nsDragService :: ExtractDataFromOS ( DragReference inDragRef, ItemReference inIt
|
|||
//
|
||||
|
||||
nsresult
|
||||
nsDragService :: StartDragSession ( )
|
||||
nsDragService::StartDragSession ( )
|
||||
{
|
||||
nsWatchTask::GetTask().Suspend();
|
||||
|
||||
|
@ -993,7 +1104,7 @@ nsDragService :: StartDragSession ( )
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsDragService :: EndDragSession ( )
|
||||
nsDragService::EndDragSession ( )
|
||||
{
|
||||
nsWatchTask::GetTask().Resume();
|
||||
|
||||
|
@ -1008,7 +1119,7 @@ nsDragService :: EndDragSession ( )
|
|||
// drag action changes based on modifier keys
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsDragService :: SetDragAction ( PRUint32 anAction )
|
||||
nsDragService::SetDragAction ( PRUint32 anAction )
|
||||
{
|
||||
const PRInt32 kCopyCursorID = 144;
|
||||
const PRInt32 kLinkCursorID = 145;
|
||||
|
@ -1032,3 +1143,66 @@ nsDragService :: SetDragAction ( PRUint32 anAction )
|
|||
|
||||
return nsBaseDragService::SetDragAction(anAction);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
// Utility routines for dragging files to the Finder
|
||||
|
||||
static OSErr GetDropDirectory(DragReference dragRef, FSSpecPtr fssOut)
|
||||
{
|
||||
OSErr err;
|
||||
|
||||
AEDesc dropLocAlias = { typeNull, nil };
|
||||
err = ::GetDropLocation(dragRef, &dropLocAlias);
|
||||
if (err != noErr) return err;
|
||||
|
||||
if (dropLocAlias.descriptorType != typeAlias)
|
||||
return paramErr;
|
||||
|
||||
AEDesc dropLocFSS = { typeNull, nil };
|
||||
if ((err = ::AECoerceDesc(&dropLocAlias, typeFSS, &dropLocFSS)) == noErr)
|
||||
{
|
||||
err = ::AEGetDescData(&dropLocFSS, fssOut, sizeof(FSSpec));
|
||||
(void)::AEDisposeDesc(&dropLocFSS);
|
||||
}
|
||||
|
||||
if (dropLocAlias.dataHandle)
|
||||
(void)::AEDisposeDesc(&dropLocAlias);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
OSErr nsDragService::GetHFSPromiseDropDirectory(DragReference inDragRef, unsigned int inItemIndex,
|
||||
FlavorType inFlavor, nsILocalFile** outDir)
|
||||
{
|
||||
// get the promise data
|
||||
PromiseHFSFlavor promiseData;
|
||||
Size dataSize = sizeof(promiseData);
|
||||
OSErr err = ::GetFlavorData(inDragRef, inItemIndex, kDragFlavorTypePromiseHFS, &promiseData, &dataSize, 0);
|
||||
if (err != noErr) return err;
|
||||
|
||||
FSSpec dropLocation;
|
||||
err = GetDropDirectory(inDragRef, &dropLocation);
|
||||
if (err != noErr) return err;
|
||||
|
||||
nsCOMPtr<nsILocalFileMac> dropFolderSpec;
|
||||
nsresult rv = NS_NewLocalFileWithFSSpec(&dropLocation, PR_FALSE, getter_AddRefs(dropFolderSpec));
|
||||
if (NS_FAILED(rv)) return fnfErr;
|
||||
|
||||
CallQueryInterface(dropFolderSpec, outDir);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
OSErr
|
||||
nsDragService::SetDropFileInDrag(DragReference inDragRef, unsigned int inItemIndex,
|
||||
FlavorType inFlavor, nsILocalFile* inFile)
|
||||
{
|
||||
nsCOMPtr<nsILocalFileMac> targetFileMac = do_QueryInterface(inFile);
|
||||
if (!targetFileMac) return paramErr;
|
||||
|
||||
FSSpec targetFileSpec;
|
||||
nsresult rv = targetFileMac->GetFSSpec(&targetFileSpec);
|
||||
if (NS_FAILED(rv)) return paramErr;
|
||||
|
||||
return ::SetDragItemFlavorData(inDragRef, inItemIndex, inFlavor, &targetFileSpec, sizeof(FSSpec), 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -54,8 +54,7 @@
|
|||
#include <Drag.h>
|
||||
#include <MacWindows.h>
|
||||
|
||||
class nsNativeDragTarget;
|
||||
|
||||
class nsILocalFile;
|
||||
|
||||
class nsDragService : public nsBaseDragService, public nsIDragSessionMac
|
||||
{
|
||||
|
@ -85,7 +84,7 @@ private:
|
|||
|
||||
char* LookupMimeMappingsForItem ( DragReference inDragRef, ItemReference itemRef ) ;
|
||||
|
||||
void RegisterDragItemsAndFlavors ( nsISupportsArray * inArray ) ;
|
||||
void RegisterDragItemsAndFlavors ( nsISupportsArray * inArray, RgnHandle inDragRgn ) ;
|
||||
PRBool BuildDragRegion ( nsIScriptableRegion* inRegion, nsIDOMNode* inNode, RgnHandle ioDragRgn ) ;
|
||||
OSErr GetDataForFlavor ( nsISupportsArray* inDragItems, DragReference inDragRef, unsigned int inItemIndex,
|
||||
FlavorType inFlavor, void** outData, unsigned int * outSize ) ;
|
||||
|
@ -95,16 +94,22 @@ private:
|
|||
// compute a screen rect from the frame associated with the given dom node
|
||||
PRBool ComputeGlobalRectFromFrame ( nsIDOMNode* aDOMNode, Rect & outScreenRect ) ;
|
||||
|
||||
OSErr GetHFSPromiseDropDirectory(DragReference inDragRef, unsigned int inItemIndex,
|
||||
FlavorType inFlavor, nsILocalFile** outDir);
|
||||
|
||||
OSErr SetDropFileInDrag(DragReference inDragRef, unsigned int inItemIndex,
|
||||
FlavorType inFlavor, nsILocalFile* inFile);
|
||||
|
||||
// callback for the MacOS DragManager when a drop site asks for data
|
||||
static pascal OSErr DragSendDataProc ( FlavorType inFlavor, void* inRefCon,
|
||||
ItemReference theItemRef, DragReference inDragRef ) ;
|
||||
|
||||
PRBool mImageDraggingSupported;
|
||||
DragSendDataUPP mDragSendDataUPP;
|
||||
DragReference mDragRef; // reference to _the_ drag. There can be only one.
|
||||
nsISupportsArray* mDataItems; // cached here for when we start the drag so the
|
||||
// DragSendDataProc has access to them.
|
||||
// ONLY VALID DURING A DRAG STARTED WITHIN THIS APP.
|
||||
PRBool mImageDraggingSupported;
|
||||
|
||||
}; // class nsDragService
|
||||
|
||||
|
|
|
@ -51,7 +51,13 @@
|
|||
#include <Drag.h>
|
||||
#include <Scrap.h>
|
||||
|
||||
nsMimeMapperMac :: nsMimeMapperMac ( const char* inMappings )
|
||||
|
||||
enum {
|
||||
kScrapFlavorTypeURL = FOUR_CHAR_CODE('url '),
|
||||
kScrapFlavorTypeURLDesc = FOUR_CHAR_CODE('urld')
|
||||
};
|
||||
|
||||
nsMimeMapperMac::nsMimeMapperMac ( const char* inMappings )
|
||||
: mCounter(0)
|
||||
{
|
||||
if (inMappings && strlen(inMappings) )
|
||||
|
@ -59,7 +65,7 @@ nsMimeMapperMac :: nsMimeMapperMac ( const char* inMappings )
|
|||
}
|
||||
|
||||
|
||||
nsMimeMapperMac :: ~nsMimeMapperMac ( )
|
||||
nsMimeMapperMac::~nsMimeMapperMac ( )
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -76,7 +82,7 @@ nsMimeMapperMac :: ~nsMimeMapperMac ( )
|
|||
// be exported along with the data.
|
||||
//
|
||||
ResType
|
||||
nsMimeMapperMac :: MapMimeTypeToMacOSType ( const char* aMimeStr, PRBool inAddIfNotPresent )
|
||||
nsMimeMapperMac::MapMimeTypeToMacOSType ( const char* aMimeStr, PRBool inAddIfNotPresent )
|
||||
{
|
||||
ResType format = 0;
|
||||
|
||||
|
@ -101,9 +107,15 @@ nsMimeMapperMac :: MapMimeTypeToMacOSType ( const char* aMimeStr, PRBool inAddIf
|
|||
else if ( PL_strcmp(aMimeStr, kTextMime) == 0 )
|
||||
format = kScrapFlavorTypeText;
|
||||
else if ( PL_strcmp(aMimeStr, kFileMime) == 0 )
|
||||
format = flavorTypeHFS;
|
||||
format = kDragFlavorTypeHFS;
|
||||
else if ( PL_strcmp(aMimeStr, kFilePromiseMime) == 0 )
|
||||
format = kDragFlavorTypePromiseHFS;
|
||||
else if ( PL_strcmp(aMimeStr, kNativeImageMime) == 0 )
|
||||
format = kScrapFlavorTypePicture;
|
||||
else if ( PL_strcmp(aMimeStr, kURLDataMime) == 0 )
|
||||
format = kScrapFlavorTypeURL;
|
||||
else if ( PL_strcmp(aMimeStr, kURLDescriptionMime) == 0 )
|
||||
format = kScrapFlavorTypeURLDesc;
|
||||
#if NOT_YET
|
||||
else if ( PL_strcmp(aMimeStr, kPNGImageMime) == 0 )
|
||||
format = kScrapFlavorTypePicture;
|
||||
|
@ -140,13 +152,17 @@ nsMimeMapperMac :: MapMimeTypeToMacOSType ( const char* aMimeStr, PRBool inAddIf
|
|||
// we probably won't get a match in that case.
|
||||
//
|
||||
void
|
||||
nsMimeMapperMac :: MapMacOSTypeToMimeType ( ResType inMacType, nsCAutoString & outMimeStr )
|
||||
nsMimeMapperMac::MapMacOSTypeToMimeType ( ResType inMacType, nsCAutoString & outMimeStr )
|
||||
{
|
||||
switch ( inMacType ) {
|
||||
|
||||
case kScrapFlavorTypeText: outMimeStr = kTextMime; break;
|
||||
case kScrapFlavorTypeUnicode: outMimeStr = kUnicodeMime; break;
|
||||
case flavorTypeHFS: outMimeStr = kFileMime; break;
|
||||
case kScrapFlavorTypeText: outMimeStr = kTextMime; break;
|
||||
case kScrapFlavorTypeUnicode: outMimeStr = kUnicodeMime; break;
|
||||
case kDragFlavorTypeHFS: outMimeStr = kFileMime; break;
|
||||
case kDragFlavorTypePromiseHFS: outMimeStr = kFilePromiseMime; break;
|
||||
case kDragPromisedFlavor: outMimeStr = kFilePromiseMime; break;
|
||||
case kScrapFlavorTypeURL: outMimeStr = kURLDataMime; break;
|
||||
case kScrapFlavorTypeURLDesc: outMimeStr = kURLDescriptionMime; break;
|
||||
|
||||
// if someone gives us PICT (or we could have put it there), use
|
||||
// the native image mime type.
|
||||
|
@ -191,7 +207,7 @@ nsMimeMapperMac :: MapMacOSTypeToMimeType ( ResType inMacType, nsCAutoString & o
|
|||
// NOTE: we make the assumption that the data is NULL terminated.
|
||||
//
|
||||
void
|
||||
nsMimeMapperMac :: ParseMappings ( const char* inMappings )
|
||||
nsMimeMapperMac::ParseMappings ( const char* inMappings )
|
||||
{
|
||||
if ( !inMappings )
|
||||
return;
|
||||
|
@ -222,7 +238,7 @@ nsMimeMapperMac :: ParseMappings ( const char* inMappings )
|
|||
// the null at the end of the string.
|
||||
//
|
||||
char*
|
||||
nsMimeMapperMac :: ExportMapping ( short * outLength ) const
|
||||
nsMimeMapperMac::ExportMapping ( short * outLength ) const
|
||||
{
|
||||
NS_WARN_IF_FALSE ( outLength, "No out param provided" );
|
||||
if ( outLength )
|
||||
|
|
|
@ -50,13 +50,7 @@ public:
|
|||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIHTMLConverter
|
||||
NS_IMETHOD GetInputDataFlavors(nsISupportsArray **_retval) ;
|
||||
NS_IMETHOD GetOutputDataFlavors(nsISupportsArray **_retval) ;
|
||||
NS_IMETHOD CanConvert(const char *aFromDataFlavor, const char *aToDataFlavor, PRBool *_retval) ;
|
||||
NS_IMETHOD Convert(const char *aFromDataFlavor, nsISupports *aFromData, PRUint32 aDataLen,
|
||||
const char *aToDataFlavor, nsISupports **aToData, PRUint32 *aDataToLen) ;
|
||||
NS_DECL_NSIFORMATCONVERTER
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -318,32 +318,23 @@ nsTransferable::~nsTransferable()
|
|||
// account any converter that may be registered. This list consists of
|
||||
// nsISupportsCString objects so that the flavor list can be accessed from JS.
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsTransferable :: GetTransferDataFlavors(nsISupportsArray ** aDataFlavorList)
|
||||
nsresult
|
||||
nsTransferable::GetTransferDataFlavors(nsISupportsArray ** aDataFlavorList)
|
||||
{
|
||||
if (!aDataFlavorList)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
nsresult rv = NS_NewISupportsArray ( aDataFlavorList );
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
NS_NewISupportsArray ( aDataFlavorList );
|
||||
if ( *aDataFlavorList ) {
|
||||
for ( PRInt32 i=0; i<mDataArray->Count(); ++i ) {
|
||||
DataStruct * data = (DataStruct *)mDataArray->ElementAt(i);
|
||||
nsCOMPtr<nsISupportsCString> flavorWrapper;
|
||||
rv = nsComponentManager::CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, nsnull,
|
||||
NS_GET_IID(nsISupportsCString), getter_AddRefs(flavorWrapper));
|
||||
if ( flavorWrapper ) {
|
||||
flavorWrapper->SetData ( data->GetFlavor() );
|
||||
nsCOMPtr<nsISupports> genericWrapper ( do_QueryInterface(flavorWrapper) );
|
||||
(*aDataFlavorList)->AppendElement( genericWrapper );
|
||||
}
|
||||
for ( PRInt32 i=0; i<mDataArray->Count(); ++i ) {
|
||||
DataStruct * data = (DataStruct *)mDataArray->ElementAt(i);
|
||||
nsCOMPtr<nsISupportsCString> flavorWrapper = do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID);
|
||||
if ( flavorWrapper ) {
|
||||
flavorWrapper->SetData ( data->GetFlavor() );
|
||||
nsCOMPtr<nsISupports> genericWrapper ( do_QueryInterface(flavorWrapper) );
|
||||
(*aDataFlavorList)->AppendElement( genericWrapper );
|
||||
}
|
||||
}
|
||||
else
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -355,27 +346,39 @@ nsTransferable :: GetTransferDataFlavors(nsISupportsArray ** aDataFlavorList)
|
|||
// accessable from JS.
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsTransferable :: GetTransferData(const char *aFlavor, nsISupports **aData, PRUint32 *aDataLen)
|
||||
nsTransferable::GetTransferData(const char *aFlavor, nsISupports **aData, PRUint32 *aDataLen)
|
||||
{
|
||||
if ( !aFlavor || !aData ||!aDataLen )
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
NS_ENSURE_ARG_POINTER(aFlavor && aData && aDataLen);
|
||||
|
||||
PRBool found = PR_FALSE;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// first look and see if the data is present in one of the intrinsic flavors
|
||||
PRInt32 i;
|
||||
for ( i=0; i<mDataArray->Count(); ++i ) {
|
||||
for (i = 0; i < mDataArray->Count(); ++i ) {
|
||||
DataStruct * data = (DataStruct *)mDataArray->ElementAt(i);
|
||||
if ( data->GetFlavor().Equals(aFlavor) ) {
|
||||
data->GetData(aData, aDataLen);
|
||||
if (*aDataLen == kFlavorHasDataProvider) {
|
||||
// do we have a data provider?
|
||||
nsCOMPtr<nsIFlavorDataProvider> dataProvider = do_QueryInterface(*aData);
|
||||
if (dataProvider) {
|
||||
rv = dataProvider->GetFlavorData(this, aFlavor, aData, aDataLen);
|
||||
if (NS_FAILED(rv))
|
||||
break; // the provider failed. fall into the conveter code below.
|
||||
}
|
||||
}
|
||||
if (*aData && *aDataLen > 0)
|
||||
return NS_OK;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool found = PR_FALSE;
|
||||
|
||||
// if not, try using a format converter to get the requested flavor
|
||||
if ( !found && mFormatConv ) {
|
||||
for (i=0;i<mDataArray->Count();i++) {
|
||||
if ( mFormatConv ) {
|
||||
for (i = 0; i < mDataArray->Count(); ++i) {
|
||||
DataStruct * data = (DataStruct *)mDataArray->ElementAt(i);
|
||||
PRBool canConvert = PR_FALSE;
|
||||
mFormatConv->CanConvert(data->GetFlavor().get(), aFlavor, &canConvert);
|
||||
|
@ -383,8 +386,18 @@ nsTransferable :: GetTransferData(const char *aFlavor, nsISupports **aData, PRUi
|
|||
nsCOMPtr<nsISupports> dataBytes;
|
||||
PRUint32 len;
|
||||
data->GetData(getter_AddRefs(dataBytes), &len);
|
||||
if (len == kFlavorHasDataProvider) {
|
||||
// do we have a data provider?
|
||||
nsCOMPtr<nsIFlavorDataProvider> dataProvider = do_QueryInterface(dataBytes);
|
||||
if (dataProvider) {
|
||||
rv = dataProvider->GetFlavorData(this, aFlavor, getter_AddRefs(dataBytes), &len);
|
||||
if (NS_FAILED(rv))
|
||||
break; // give up
|
||||
}
|
||||
}
|
||||
mFormatConv->Convert(data->GetFlavor().get(), dataBytes, len, aFlavor, aData, aDataLen);
|
||||
found = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -401,8 +414,7 @@ nsTransferable :: GetTransferData(const char *aFlavor, nsISupports **aData, PRUi
|
|||
NS_IMETHODIMP
|
||||
nsTransferable::GetAnyTransferData(char **aFlavor, nsISupports **aData, PRUint32 *aDataLen)
|
||||
{
|
||||
if ( !aFlavor || !aData || !aDataLen )
|
||||
return NS_ERROR_FAILURE;
|
||||
NS_ENSURE_ARG_POINTER(aFlavor && aData && aDataLen);
|
||||
|
||||
for ( PRInt32 i=0; i < mDataArray->Count(); ++i ) {
|
||||
DataStruct * data = (DataStruct *)mDataArray->ElementAt(i);
|
||||
|
@ -425,12 +437,11 @@ nsTransferable::GetAnyTransferData(char **aFlavor, nsISupports **aData, PRUint32
|
|||
NS_IMETHODIMP
|
||||
nsTransferable::SetTransferData(const char *aFlavor, nsISupports *aData, PRUint32 aDataLen)
|
||||
{
|
||||
if ( !aFlavor )
|
||||
return NS_ERROR_FAILURE;
|
||||
NS_ENSURE_ARG(aFlavor);
|
||||
|
||||
// first check our intrinsic flavors to see if one has been registered.
|
||||
PRInt32 i = 0;
|
||||
for ( i=0; i<mDataArray->Count(); ++i ) {
|
||||
for (i = 0; i < mDataArray->Count(); ++i) {
|
||||
DataStruct * data = (DataStruct *)mDataArray->ElementAt(i);
|
||||
if ( data->GetFlavor().Equals(aFlavor) ) {
|
||||
data->SetData ( aData, aDataLen );
|
||||
|
@ -440,7 +451,7 @@ nsTransferable::SetTransferData(const char *aFlavor, nsISupports *aData, PRUint3
|
|||
|
||||
// if not, try using a format converter to find a flavor to put the data in
|
||||
if ( mFormatConv ) {
|
||||
for ( i=0; i<mDataArray->Count(); ++i) {
|
||||
for (i = 0; i < mDataArray->Count(); ++i) {
|
||||
DataStruct * data = (DataStruct *)mDataArray->ElementAt(i);
|
||||
PRBool canConvert = PR_FALSE;
|
||||
mFormatConv->CanConvert(aFlavor, data->GetFlavor().get(), &canConvert);
|
||||
|
@ -470,7 +481,7 @@ nsTransferable::SetTransferData(const char *aFlavor, nsISupports *aData, PRUint3
|
|||
// Adds a data flavor to our list with no data. Error if it already exists.
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsTransferable :: AddDataFlavor(const char *aDataFlavor)
|
||||
nsTransferable::AddDataFlavor(const char *aDataFlavor)
|
||||
{
|
||||
if (GetDataForFlavor (mDataArray, aDataFlavor))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -512,11 +523,8 @@ nsTransferable::RemoveDataFlavor(const char *aDataFlavor)
|
|||
NS_IMETHODIMP
|
||||
nsTransferable::IsLargeDataSet(PRBool *_retval)
|
||||
{
|
||||
if ( !_retval )
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
*_retval = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -527,7 +535,7 @@ nsTransferable::IsLargeDataSet(PRBool *_retval)
|
|||
*/
|
||||
NS_IMETHODIMP nsTransferable::SetConverter(nsIFormatConverter * aConverter)
|
||||
{
|
||||
mFormatConv = dont_QueryInterface(aConverter);
|
||||
mFormatConv = aConverter;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -538,15 +546,9 @@ NS_IMETHODIMP nsTransferable::SetConverter(nsIFormatConverter * aConverter)
|
|||
*/
|
||||
NS_IMETHODIMP nsTransferable::GetConverter(nsIFormatConverter * *aConverter)
|
||||
{
|
||||
if ( !aConverter )
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if ( mFormatConv ) {
|
||||
*aConverter = mFormatConv;
|
||||
NS_ADDREF(*aConverter);
|
||||
} else
|
||||
*aConverter = nsnull;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aConverter);
|
||||
*aConverter = mFormatConv;
|
||||
NS_IF_ADDREF(*aConverter);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -558,10 +560,9 @@ NS_IMETHODIMP nsTransferable::GetConverter(nsIFormatConverter * *aConverter)
|
|||
// intrinsic knowledge or input data converters.
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsTransferable :: FlavorsTransferableCanImport(nsISupportsArray **_retval)
|
||||
nsTransferable::FlavorsTransferableCanImport(nsISupportsArray **_retval)
|
||||
{
|
||||
if ( !_retval )
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
|
||||
// Get the flavor list, and on to the end of it, append the list of flavors we
|
||||
// can also get to through a converter. This is so that we can just walk the list
|
||||
|
@ -602,10 +603,9 @@ nsTransferable :: FlavorsTransferableCanImport(nsISupportsArray **_retval)
|
|||
// intrinsic knowledge or output data converters.
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsTransferable :: FlavorsTransferableCanExport(nsISupportsArray **_retval)
|
||||
nsTransferable::FlavorsTransferableCanExport(nsISupportsArray **_retval)
|
||||
{
|
||||
if ( !_retval )
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
|
||||
// Get the flavor list, and on to the end of it, append the list of flavors we
|
||||
// can also get to through a converter. This is so that we can just walk the list
|
||||
|
|
|
@ -62,23 +62,12 @@ public:
|
|||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsITransferable
|
||||
NS_IMETHOD FlavorsTransferableCanExport(nsISupportsArray **_retval) ;
|
||||
NS_IMETHOD GetTransferData(const char *aFlavor, nsISupports **aData, PRUint32 *aDataLen);
|
||||
NS_IMETHOD GetAnyTransferData(char **aFlavor, nsISupports **aData, PRUint32 *aDataLen);
|
||||
NS_IMETHOD IsLargeDataSet(PRBool *_retval);
|
||||
NS_IMETHOD FlavorsTransferableCanImport(nsISupportsArray **_retval) ;
|
||||
NS_IMETHOD SetTransferData(const char *aFlavor, nsISupports *aData, PRUint32 aDataLen);
|
||||
NS_IMETHOD AddDataFlavor(const char *aDataFlavor) ;
|
||||
NS_IMETHOD RemoveDataFlavor(const char *aDataFlavor) ;
|
||||
NS_IMETHOD GetConverter(nsIFormatConverter * *aConverter);
|
||||
NS_IMETHOD SetConverter(nsIFormatConverter * aConverter);
|
||||
NS_DECL_NSITRANSFERABLE
|
||||
|
||||
protected:
|
||||
|
||||
// get flavors w/out converter
|
||||
NS_IMETHOD GetTransferDataFlavors(nsISupportsArray** aDataFlavorList);
|
||||
nsresult GetTransferDataFlavors(nsISupportsArray** aDataFlavorList);
|
||||
|
||||
nsVoidArray * mDataArray;
|
||||
nsCOMPtr<nsIFormatConverter> mFormatConv;
|
||||
|
|
Загрузка…
Ссылка в новой задаче