Bug 326743: add find clipboard to the list of available clipboard on OSX. r=joshmoz

This commit is contained in:
Mike de Boer 2014-02-28 16:07:30 +01:00
parent dad01b9ccd
commit 3b5ec7db6a
9 changed files with 125 additions and 28 deletions

View File

@ -109,3 +109,9 @@ nsClipboard::SupportsSelectionClipboard(bool *aIsSupported)
return NS_OK;
}
NS_IMETHODIMP
nsClipboard::SupportsFindClipboard(bool* _retval)
{
*_retval = false;
return NS_OK;
}

View File

@ -23,6 +23,7 @@ public:
// nsIClipboard
NS_IMETHOD HasDataMatchingFlavors(const char** aFlavorList, uint32_t aLength,
int32_t aWhichClipboard, bool *_retval);
NS_IMETHOD SupportsFindClipboard(bool *_retval);
// Helper methods, used also by nsDragService
static NSDictionary* PasteboardDictFromTransferable(nsITransferable *aTransferable);
@ -37,7 +38,12 @@ protected:
NS_IMETHOD GetNativeClipboardData(nsITransferable * aTransferable, int32_t aWhichClipboard);
private:
int mChangeCount; // this is always set to the native change count after any clipboard modifications
// This is always set to the native change count after any modification of the
// general clipboard.
int mChangeCountGeneral;
// This is always set to the native change count after any modification of the
// find clipboard.
int mChangeCountFind;
};

View File

@ -35,7 +35,8 @@ extern void EnsureLogInitialized();
nsClipboard::nsClipboard() : nsBaseClipboard()
{
mChangeCount = 0;
mChangeCountGeneral = 0;
mChangeCountFind = 0;
EnsureLogInitialized();
}
@ -65,7 +66,7 @@ nsClipboard::SetNativeClipboardData(int32_t aWhichClipboard)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
if ((aWhichClipboard != kGlobalClipboard) || !mTransferable)
if ((aWhichClipboard != kGlobalClipboard && aWhichClipboard != kFindClipboard) || !mTransferable)
return NS_ERROR_FAILURE;
mIgnoreEmptyNotification = true;
@ -74,28 +75,44 @@ nsClipboard::SetNativeClipboardData(int32_t aWhichClipboard)
if (!pasteboardOutputDict)
return NS_ERROR_FAILURE;
// write everything out to the general pasteboard
unsigned int outputCount = [pasteboardOutputDict count];
NSArray* outputKeys = [pasteboardOutputDict allKeys];
NSPasteboard* generalPBoard = [NSPasteboard generalPasteboard];
[generalPBoard declareTypes:outputKeys owner:nil];
NSPasteboard* cocoaPasteboard;
if (aWhichClipboard == kFindClipboard) {
cocoaPasteboard = [NSPasteboard pasteboardWithName:NSFindPboard];
[cocoaPasteboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
} else {
// Write everything else out to the general pasteboard.
cocoaPasteboard = [NSPasteboard generalPasteboard];
[cocoaPasteboard declareTypes:outputKeys owner:nil];
}
for (unsigned int i = 0; i < outputCount; i++) {
NSString* currentKey = [outputKeys objectAtIndex:i];
id currentValue = [pasteboardOutputDict valueForKey:currentKey];
if (currentKey == NSStringPboardType ||
currentKey == kCorePboardType_url ||
currentKey == kCorePboardType_urld ||
currentKey == kCorePboardType_urln) {
[generalPBoard setString:currentValue forType:currentKey];
} else if (currentKey == NSHTMLPboardType) {
[generalPBoard setString:(nsClipboard::WrapHtmlForSystemPasteboard(currentValue))
forType:currentKey];
if (aWhichClipboard == kFindClipboard) {
if (currentKey == NSStringPboardType)
[cocoaPasteboard setString:currentValue forType:currentKey];
} else {
[generalPBoard setData:currentValue forType:currentKey];
if (currentKey == NSStringPboardType ||
currentKey == kCorePboardType_url ||
currentKey == kCorePboardType_urld ||
currentKey == kCorePboardType_urln) {
[cocoaPasteboard setString:currentValue forType:currentKey];
} else if (currentKey == NSHTMLPboardType) {
[cocoaPasteboard setString:(nsClipboard::WrapHtmlForSystemPasteboard(currentValue))
forType:currentKey];
} else {
[cocoaPasteboard setData:currentValue forType:currentKey];
}
}
}
mChangeCount = [generalPBoard changeCount];
if (aWhichClipboard == kFindClipboard) {
mChangeCountFind = [cocoaPasteboard changeCount];
} else {
mChangeCountGeneral = [cocoaPasteboard changeCount];
}
mIgnoreEmptyNotification = false;
@ -238,10 +255,15 @@ nsClipboard::GetNativeClipboardData(nsITransferable* aTransferable, int32_t aWhi
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
if ((aWhichClipboard != kGlobalClipboard) || !aTransferable)
if ((aWhichClipboard != kGlobalClipboard && aWhichClipboard != kFindClipboard) || !aTransferable)
return NS_ERROR_FAILURE;
NSPasteboard* cocoaPasteboard = [NSPasteboard generalPasteboard];
NSPasteboard* cocoaPasteboard;
if (aWhichClipboard == kFindClipboard) {
cocoaPasteboard = [NSPasteboard pasteboardWithName:NSFindPboard];
} else {
cocoaPasteboard = [NSPasteboard generalPasteboard];
}
if (!cocoaPasteboard)
return NS_ERROR_FAILURE;
@ -254,9 +276,10 @@ nsClipboard::GetNativeClipboardData(nsITransferable* aTransferable, int32_t aWhi
uint32_t flavorCount;
flavorList->Count(&flavorCount);
int changeCount = (aWhichClipboard == kFindClipboard) ? mChangeCountFind : mChangeCountGeneral;
// If we were the last ones to put something on the pasteboard, then just use the cached
// transferable. Otherwise clear it because it isn't relevant any more.
if (mChangeCount == [cocoaPasteboard changeCount]) {
if (changeCount == [cocoaPasteboard changeCount]) {
if (mTransferable) {
for (uint32_t i = 0; i < flavorCount; i++) {
nsCOMPtr<nsISupports> genericFlavor;
@ -277,9 +300,8 @@ nsClipboard::GetNativeClipboardData(nsITransferable* aTransferable, int32_t aWhi
}
}
}
}
else {
nsBaseClipboard::EmptyClipboard(kGlobalClipboard);
} else {
nsBaseClipboard::EmptyClipboard(aWhichClipboard);
}
// at this point we can't satisfy the request from cache data so let's look
@ -358,6 +380,14 @@ nsClipboard::HasDataMatchingFlavors(const char** aFlavorList, uint32_t aLength,
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
NS_IMETHODIMP
nsClipboard::SupportsFindClipboard(bool *_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
*_retval = true;
return NS_OK;
}
// This function converts anything that other applications might understand into the system format
// and puts it into a dictionary which it returns.
// static

View File

@ -448,6 +448,13 @@ nsClipboard::SupportsSelectionClipboard(bool *_retval)
return NS_OK;
}
NS_IMETHODIMP
nsClipboard::SupportsFindClipboard(bool* _retval)
{
*_retval = false;
return NS_OK;
}
/* static */
GdkAtom
nsClipboard::GetSelectionAtom(int32_t aWhichClipboard)

View File

@ -11,11 +11,12 @@
interface nsIArray;
[scriptable, uuid(38984945-8674-4d04-b786-5c0ca9434457)]
[scriptable, uuid(ceaa0047-647f-4b8e-ad1c-aff9fa62aa51)]
interface nsIClipboard : nsISupports
{
const long kSelectionClipboard = 0;
const long kGlobalClipboard = 1;
const long kFindClipboard = 2;
/**
* Given a transferable, set the data on the native clipboard
@ -73,6 +74,14 @@ interface nsIClipboard : nsISupports
* @result NS_OK if successful.
*/
boolean supportsSelectionClipboard ( ) ;
/**
* Allows clients to determine if the implementation supports the concept of a
* separate clipboard for find search strings.
*
* @result NS_OK if successful.
*/
boolean supportsFindClipboard ( ) ;
};

View File

@ -556,3 +556,12 @@ nsClipboard::SupportsSelectionClipboard(bool *_retval)
return NS_OK;
}
NS_IMETHODIMP
nsClipboard::SupportsFindClipboard(bool* _retval)
{
NS_ENSURE_ARG_POINTER(_retval);
*_retval = false;
return NS_OK;
}

View File

@ -22,6 +22,7 @@ nsBaseClipboard::~nsBaseClipboard()
{
EmptyClipboard(kSelectionClipboard);
EmptyClipboard(kGlobalClipboard);
EmptyClipboard(kFindClipboard);
}
NS_IMPL_ISUPPORTS1(nsBaseClipboard, nsIClipboard)
@ -39,7 +40,9 @@ NS_IMETHODIMP nsBaseClipboard::SetData(nsITransferable * aTransferable, nsIClipb
return NS_OK;
bool selectClipPresent;
SupportsSelectionClipboard(&selectClipPresent);
if ( !selectClipPresent && aWhichClipboard != kGlobalClipboard )
bool findClipPresent;
SupportsFindClipboard(&findClipPresent);
if ( !selectClipPresent && !findClipPresent && aWhichClipboard != kGlobalClipboard )
return NS_ERROR_FAILURE;
mEmptyingForSetData = true;
@ -78,7 +81,9 @@ NS_IMETHODIMP nsBaseClipboard::GetData(nsITransferable * aTransferable, int32_t
bool selectClipPresent;
SupportsSelectionClipboard(&selectClipPresent);
if ( !selectClipPresent && aWhichClipboard != kGlobalClipboard )
bool findClipPresent;
SupportsFindClipboard(&findClipPresent);
if ( !selectClipPresent && !findClipPresent && aWhichClipboard != kGlobalClipboard )
return NS_ERROR_FAILURE;
if ( aTransferable )
@ -91,7 +96,9 @@ NS_IMETHODIMP nsBaseClipboard::EmptyClipboard(int32_t aWhichClipboard)
{
bool selectClipPresent;
SupportsSelectionClipboard(&selectClipPresent);
if ( !selectClipPresent && aWhichClipboard != kGlobalClipboard )
bool findClipPresent;
SupportsFindClipboard(&findClipPresent);
if ( !selectClipPresent && !findClipPresent && aWhichClipboard != kGlobalClipboard )
return NS_ERROR_FAILURE;
if (mIgnoreEmptyNotification)
@ -123,3 +130,10 @@ nsBaseClipboard::SupportsSelectionClipboard(bool* _retval)
*_retval = false; // we don't support the selection clipboard by default.
return NS_OK;
}
NS_IMETHODIMP
nsBaseClipboard::SupportsFindClipboard(bool* _retval)
{
*_retval = false; // we don't support the find clipboard by default.
return NS_OK;
}

View File

@ -51,16 +51,25 @@ nsClipboardHelper::CopyStringToClipboard(const nsAString& aString,
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(clipboard, NS_ERROR_FAILURE);
bool clipboardSupported;
// don't go any further if they're asking for the selection
// clipboard on a platform which doesn't support it (i.e., unix)
if (nsIClipboard::kSelectionClipboard == aClipboardID) {
bool clipboardSupported;
rv = clipboard->SupportsSelectionClipboard(&clipboardSupported);
NS_ENSURE_SUCCESS(rv, rv);
if (!clipboardSupported)
return NS_ERROR_FAILURE;
}
// don't go any further if they're asking for the find clipboard on a platform
// which doesn't support it (i.e., non-osx)
if (nsIClipboard::kFindClipboard == aClipboardID) {
rv = clipboard->SupportsFindClipboard(&clipboardSupported);
NS_ENSURE_SUCCESS(rv, rv);
if (!clipboardSupported)
return NS_ERROR_FAILURE;
}
// create a transferable for putting data on the clipboard
nsCOMPtr<nsITransferable>
trans(do_CreateInstance("@mozilla.org/widget/transferable;1", &rv));

View File

@ -91,3 +91,10 @@ nsClipboardProxy::SupportsSelectionClipboard(bool *aIsSupported)
return NS_OK;
}
NS_IMETHODIMP
nsClipboardProxy::SupportsFindClipboard(bool *aIsSupported)
{
*aIsSupported = false;
return NS_OK;
}