Mozilla/mozilla/widget/src/mac/nsClipboard.cpp
pinkerton%netscape.com f84c3fe428 move mapping of mime type -> OS type to nsMimeMapperMac instead of implementing it here. THis way drag and drop can use it to.
git-svn-id: svn://10.0.0.236/trunk@29567 18797224-902f-48f8-a5cc-f745e15eee43
1999-04-27 22:50:44 +00:00

235 lines
7.1 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
//
// Mike Pinkerton
// Netscape Communications
//
// See header file for details.
//
// Remaining Work:
// * only convert data to clipboard on an app switch.
// * better mime type --> OS type conversion needed. Only a few formats supported now.
//
#include "nsCOMPtr.h"
#include "nsClipboard.h"
#include "nsISupportsArray.h"
#include "nsIClipboardOwner.h"
#include "nsIDataFlavor.h"
#include "nsIFormatConverter.h"
#include "nsIGenericTransferable.h"
#include "nsMimeMapper.h"
#include "nsIComponentManager.h"
#include "nsWidgetsCID.h"
#include <Scrap.h>
NS_IMPL_ADDREF_INHERITED(nsClipboard, nsBaseClipboard)
NS_IMPL_RELEASE_INHERITED(nsClipboard, nsBaseClipboard)
//
// nsClipboard constructor
//
nsClipboard::nsClipboard() : nsBaseClipboard()
{
}
//
// nsClipboard destructor
//
nsClipboard::~nsClipboard()
{
}
/**
* @param aIID The name of the class implementing the method
* @param _classiiddef The name of the #define symbol that defines the IID
* for the class (e.g. NS_ISUPPORTS_IID)
*
*/
nsresult nsClipboard::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
nsresult rv = NS_NOINTERFACE;
static NS_DEFINE_IID(kIClipboard, NS_ICLIPBOARD_IID);
if (aIID.Equals(kIClipboard)) {
*aInstancePtr = (void*) ((nsIClipboard*)this);
NS_ADDREF_THIS();
return NS_OK;
}
return rv;
}
//
// SetNativeClipboardData
//
// Take data off the transferrable and put it on the clipboard in as many formats
// as are registered.
//
// NOTE: This code could all live in ForceDataToClipboard() and this could be a NOOP.
// If speed and large data sizes are an issue, we should move that code there and only
// do it on an app switch.
//
NS_IMETHODIMP
nsClipboard :: SetNativeClipboardData()
{
nsresult errCode = NS_OK;
mIgnoreEmptyNotification = PR_TRUE;
// make sure we have a good transferable
if ( !mTransferable )
return NS_ERROR_INVALID_ARG;
::ZeroScrap();
// get flavor list that includes all flavors that can be written (including ones
// obtained through conversion)
nsCOMPtr<nsISupportsArray> flavorList;
errCode = mTransferable->FlavorsTransferableCanExport ( getter_AddRefs(flavorList) );
if ( errCode != NS_OK )
return NS_ERROR_FAILURE;
// For each flavor present (either directly in the transferable or that its
// converter knows about) put it on the clipboard. Luckily, GetTransferData()
// handles conversions for us, so we really don't need to know if a conversion
// is required or not.
for ( int i = 0; i < flavorList->Count(); ++i ) {
nsCOMPtr<nsISupports> temp = getter_AddRefs(flavorList->ElementAt(i));
nsCOMPtr<nsIDataFlavor> currentFlavor ( do_QueryInterface(temp) );
if ( currentFlavor ) {
// find MacOS flavor
nsAutoString mimeType;
currentFlavor->GetMimeType(mimeType);
ResType macOSFlavor = nsMimeMapperMac::MapMimeTypeToMacOSType(mimeType);
// get data. This takes converters into account. We don't own the data
// so make sure not to delete it.
void* data = nsnull;
PRUint32 dataSize = 0;
errCode = mTransferable->GetTransferData ( currentFlavor, &data, &dataSize );
#ifdef NS_DEBUG
if ( errCode != NS_OK ) printf("nsClipboard:: Error getting data from transferable\n");
#endif
// stash on clipboard
long numBytes = ::PutScrap ( dataSize, macOSFlavor, data );
if ( numBytes != dataSize )
errCode = NS_ERROR_FAILURE;
}
} // foreach flavor in transferable
return errCode;
} // SetNativeClipboardData
//
// GetNativeClipboardData
//
// Take data off the native clip and put it on the transferable.
//
NS_IMETHODIMP
nsClipboard :: GetNativeClipboardData(nsITransferable * aTransferable)
{
nsresult errCode = NS_OK;
// make sure we have a good transferable
if ( !aTransferable )
return NS_ERROR_INVALID_ARG;
nsCOMPtr<nsIGenericTransferable> genericTrans = do_QueryInterface(aTransferable);
if (!genericTrans) {
return NS_ERROR_FAILURE;
}
// get flavor list that includes all acceptable flavors (including ones obtained through
// conversion)
nsCOMPtr<nsISupportsArray> flavorList;
errCode = genericTrans->FlavorsTransferableCanImport ( getter_AddRefs(flavorList) );
if ( errCode != NS_OK )
return NS_ERROR_FAILURE;
// Now walk down the list of flavors. When we find one that is actually on the
// clipboard, copy out the data into the transferable in that format. SetTransferData()
// implicitly handles conversions.
for ( int i = 0; i < flavorList->Count(); ++i ) {
nsCOMPtr<nsISupports> temp = getter_AddRefs(flavorList->ElementAt(i));
nsCOMPtr<nsIDataFlavor> currentFlavor ( do_QueryInterface(temp) );
if ( currentFlavor ) {
// find MacOS flavor
nsAutoString mimeType;
currentFlavor->GetMimeType(mimeType);
ResType macOSFlavor = nsMimeMapperMac::MapMimeTypeToMacOSType(mimeType);
// check if it is on the clipboard
long offsetUnused;
if ( ::GetScrap(NULL, macOSFlavor, &offsetUnused) > 0 ) {
// we have it, get it off the clipboard. Put it into memory that we allocate
// with new[] so that the tranferable can own it (and then later use delete[]
// on it).
Handle dataHand = ::NewHandle(0);
if ( !dataHand )
return NS_ERROR_OUT_OF_MEMORY;
long dataSize = ::GetScrap ( dataHand, macOSFlavor, &offsetUnused );
if ( dataSize > 0 ) {
char* dataBuff = new char[dataSize];
if ( !dataBuff )
return NS_ERROR_OUT_OF_MEMORY;
::HLock(dataHand);
::BlockMoveData ( *dataHand, dataBuff, dataSize );
::HUnlock(dataHand);
// put it into the transferable
errCode = genericTrans->SetTransferData ( currentFlavor, dataBuff, dataSize );
#ifdef NS_DEBUG
if ( errCode != NS_OK ) printf("nsClipboard:: Error setting data into transferable\n");
#endif
::DisposeHandle(dataHand);
}
else {
#ifdef NS_DEBUG
printf("nsClipboard: Error getting data off the clipboard, #%d\n", dataSize);
#endif
errCode = NS_ERROR_FAILURE;
}
// we found one, get out of this loop!
break;
} // if a flavor found
}
} // foreach flavor
return errCode;
}