Revision: 25412
http://sourceforge.net/p/bibdesk/svn/25412
Author: hofman
Date: 2021-01-16 15:40:15 +0000 (Sat, 16 Jan 2021)
Log Message:
-----------
Use cocoa to read and write URLs on pasteboard
Modified Paths:
--------------
trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.m
trunk/bibdesk_vendorsrc/amaxwell/FileView/FVUtilities.h
trunk/bibdesk_vendorsrc/amaxwell/FileView/FVUtilities.m
Modified: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.m
===================================================================
--- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.m 2021-01-16
15:23:26 UTC (rev 25411)
+++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.m 2021-01-16
15:40:15 UTC (rev 25412)
@@ -2722,7 +2722,8 @@
- (void)dragSelectionForEvent:(NSEvent *)event;
{
NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
- if (FVWriteURLsToPasteboard([self _selectedURLs], pboard) == NO)
+ [pboard clearContents];
+ if (NO == [pboard writeObjects:[self _selectedURLs]])
return;
NSUInteger r, c, cMin = NSUIntegerMax, cMax = 0, rMin = NSUIntegerMax,
rMax = 0;
@@ -2797,7 +2798,7 @@
NSUInteger insertIndex, firstIndex, endIndex;
// !!! this is quite expensive to call repeatedly in -draggingUpdated
- BOOL hasURLs = FVPasteboardHasURL([sender draggingPasteboard]);
+ BOOL hasURLs = [[sender draggingPasteboard]
canReadObjectForClasses:[NSArray arrayWithObject:[NSURL class]] options:nil];
// First determine the drop location, drop between rows in column mode,
and between columns otherwise
if (_fvFlags.displayMode == FVDisplayModeColumn)
@@ -2900,7 +2901,7 @@
BOOL isCopy = [self allowsDownloading] && dragOp == NSDragOperationCopy;
BOOL isMove = [self _isLocalDraggingInfo:sender] && isCopy == NO;
BOOL didPerform = NO;
- NSArray *draggedURLs = isMove ? nil : FVURLsFromPasteboard(pboard);
+ NSArray *draggedURLs = isMove ? nil : [pboard
readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]] options:nil];
NSArray *allURLs = draggedURLs;
NSMutableArray *downloads = nil;
NSUInteger insertIndex = 0;
@@ -3804,7 +3805,9 @@
- (IBAction)copy:(id)sender;
{
- if (NO == FVWriteURLsToPasteboard([self _selectedURLs], [NSPasteboard
generalPasteboard]))
+ NSPasteboard *pboard = [NSPasteboard generalPasteboard];
+ [pboard clearContents];
+ if (NO == [pboard writeObjects:[self _selectedURLs]])
NSBeep();
}
@@ -3817,7 +3820,7 @@
- (IBAction)paste:(id)sender;
{
if ([self isEditable]) {
- NSArray *URLs = FVURLsFromPasteboard([NSPasteboard generalPasteboard]);
+ NSArray *URLs = [[NSPasteboard generalPasteboard]
readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]] options:nil];
if ([URLs count])
[[self dataSource] fileView:self insertURLs:URLs
atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange([self
numberOfIcons], [URLs count])] forDrop:nil dropOperation:FVDropOn];
else
Modified: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVUtilities.h
===================================================================
--- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVUtilities.h 2021-01-16
15:23:26 UTC (rev 25411)
+++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVUtilities.h 2021-01-16
15:40:15 UTC (rev 25412)
@@ -61,25 +61,6 @@
FV_PRIVATE_EXTERN void FVLog(NSString *format, ...);
/** @internal
- Checks the pasteboard for any URL data. Converts an NSPasteboard to a Carbon
PasteboardRef.
- @param pboard Any NSPasteboard instance.
- @return YES if pboard has a URL type or a string that can be converted to a
URL. */
-FV_PRIVATE_EXTERN BOOL FVPasteboardHasURL(NSPasteboard *pboard);
-
-/** @internal
- Reads URLs from the pasteboard, whether file: or other scheme. Finder puts
multiple URLs on the pasteboard, and also webloc files. Converts an
NSPasteboard to a Carbon PasteboardRef in order to work around NSPasteboard's
terrible URL support.
- @param pboard Any NSPasteboard instance.
- @return An array of URLs from the pasteboard. */
-FV_PRIVATE_EXTERN NSArray *FVURLsFromPasteboard(NSPasteboard *pboard);
-
-/** @internal
- Writes URLs to the pasteboard as UTF-8 data. Converts an NSPasteboard to a
Carbon PasteboardRef in order to work around NSPasteboard's terrible URL
support.
- @param URLs An array of URLs to write to the pasteboard.
- @param pboard Any NSPasteboard instance.
- @return YES if all URLs were written successfully. */
-FV_PRIVATE_EXTERN BOOL FVWriteURLsToPasteboard(NSArray *URLs, NSPasteboard
*pboard);
-
-/** @internal
Creates an NSGraphicsContext using an NSWindow as backing. Intended for use
in +initialize when +[NSGraphicsContext currentContext] may be nil.
@param size Size of the window to create.
@return A new, autoreleased instance of NSGraphicsContext. */
Modified: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVUtilities.m
===================================================================
--- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVUtilities.m 2021-01-16
15:23:26 UTC (rev 25411)
+++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVUtilities.m 2021-01-16
15:40:15 UTC (rev 25412)
@@ -116,214 +116,8 @@
va_end(list);
}
-#pragma mark Pasteboard URL functions
+#pragma mark Graphics context
-BOOL FVPasteboardHasURL(NSPasteboard *pboard)
-{
- NSArray *types = [pboard types];
-
- // quicker test than URLsFromPasteboard(); at least on 10.5, NSPasteboard
has the UTI types
- if ([types containsObject:(id)kUTTypeURL] || [types
containsObject:(id)kUTTypeFileURL] || [types containsObject:NSURLPboardType])
- return YES;
-
- // also catches case of file URL, which conforms to kUTTypeURL, and
strings that might be URLs
- return [FVURLsFromPasteboard(pboard) count] > 0;
-}
-
-// NSPasteboard only lets us read a single webloc or NSURL instance from the
pasteboard, which isn't very considerate of it. Fortunately, we can create a
Carbon pasteboard that isn't as fundamentally crippled (except in its
moderately annoying API).
-NSArray *FVURLsFromPasteboard(NSPasteboard *pboard)
-{
- OSStatus err;
-
- PasteboardRef carbonPboard;
- err = PasteboardCreate((CFStringRef)[pboard name], &carbonPboard);
-
- if (noErr == err)
- (void)PasteboardSynchronize(carbonPboard);
-
- ItemCount itemCount, itemIndex;
- if (noErr == err)
- err = PasteboardGetItemCount(carbonPboard, &itemCount);
-
- if (noErr != err)
- itemCount = 0;
-
- NSMutableArray *toReturn = [NSMutableArray arrayWithCapacity:itemCount];
-
- // this is to avoid duplication in the last call to NSPasteboard
- NSMutableSet *allURLsReadFromPasteboard = [NSMutableSet
setWithCapacity:itemCount];
-
- // Pasteboard has 1-based indexing!
-
- for (itemIndex = 1; itemIndex <= itemCount; itemIndex++) {
-
- PasteboardItemID itemID;
- CFArrayRef flavors = NULL;
- CFIndex flavorIndex, flavorCount = 0;
-
- err = PasteboardGetItemIdentifier(carbonPboard, itemIndex, &itemID);
- if (noErr == err)
- err = PasteboardCopyItemFlavors(carbonPboard, itemID, &flavors);
-
- if (noErr == err)
- flavorCount = CFArrayGetCount(flavors);
-
- // webloc has file and non-file URL, and we may only have a string type
- CFURLRef destURL = NULL;
- CFURLRef fileURL = NULL;
- CFURLRef textURL = NULL;
-
- // flavorCount will be zero in case of an error...
- for (flavorIndex = 0; flavorIndex < flavorCount; flavorIndex++) {
-
- CFStringRef flavor;
- CFDataRef data;
-
- flavor = CFArrayGetValueAtIndex(flavors, flavorIndex);
-
- // !!! I'm assuming that the URL bytes are UTF-8, but that should
be checked...
-
- // UTIs determined with PasteboardPeeker
-
- /*
- UTIs determined with PasteboardPeeker
- Assert NULL URL on each branch; this will always be true since
the pasteboard can only contain
- one flavor per type. Using UTTypeConforms instead of UTTypeEqual
could lead to a memory
- leak if there were multiple flavors conforming to kUTTypeURL
(other than kUTTypeFileURL).
- The assertion silences a clang warning.
- */
- if (UTTypeEqual(flavor, kUTTypeFileURL)) {
-
- err = PasteboardCopyItemFlavorData(carbonPboard, itemID,
flavor, &data);
- if (noErr == err && NULL != data) {
- FVAPIParameterAssert(NULL == fileURL);
- fileURL = CFURLCreateWithBytes(NULL,
CFDataGetBytePtr(data), CFDataGetLength(data), kCFStringEncodingUTF8, NULL);
- CFRelease(data);
- }
-
- } else if (UTTypeEqual(flavor, kUTTypeURL)) {
-
- err = PasteboardCopyItemFlavorData(carbonPboard, itemID,
flavor, &data);
- if (noErr == err && NULL != data) {
- FVAPIParameterAssert(NULL == destURL);
- destURL = CFURLCreateWithBytes(NULL,
CFDataGetBytePtr(data), CFDataGetLength(data), kCFStringEncodingUTF8, NULL);
- CFRelease(data);
- }
-
- } else if (UTTypeEqual(flavor, kUTTypeUTF8PlainText)) {
-
- // this is a string that may be a URL; FireFox and other apps
don't use any of the standard URL pasteboard types
- err = PasteboardCopyItemFlavorData(carbonPboard, itemID,
kUTTypeUTF8PlainText, &data);
- if (noErr == err && NULL != data) {
- FVAPIParameterAssert(NULL == textURL);
- textURL = CFURLCreateWithBytes(NULL,
CFDataGetBytePtr(data), CFDataGetLength(data), kCFStringEncodingUTF8, NULL);
- CFRelease(data);
-
- // CFURLCreateWithBytes will create a URL from any
arbitrary string
- if (NULL != textURL && nil == [(NSURL *)textURL scheme]) {
- CFRelease(textURL);
- textURL = NULL;
- }
- }
-
- }
-
- // ignore any other type; we don't care
-
- }
-
- // only add the textURL if the destURL or fileURL were not found
- if (NULL != textURL) {
- if (NULL == destURL && NULL == fileURL)
- [toReturn addObject:(id)textURL];
-
- [allURLsReadFromPasteboard addObject:(id)textURL];
- CFRelease(textURL);
- }
- // only add the fileURL if the destURL (target of a remote URL or
webloc) was not found
- if (NULL != fileURL) {
- if (NULL == destURL)
- [toReturn addObject:(id)fileURL];
-
- [allURLsReadFromPasteboard addObject:(id)fileURL];
- CFRelease(fileURL);
- }
- // always add this if it exists
- if (NULL != destURL) {
- [toReturn addObject:(id)destURL];
- [allURLsReadFromPasteboard addObject:(id)destURL];
- CFRelease(destURL);
- }
-
- if (NULL != flavors)
- CFRelease(flavors);
- }
-
- if (carbonPboard) CFRelease(carbonPboard);
-
- // NSPasteboard only allows a single NSURL for some idiotic reason, and
NSURLPboardType isn't automagically coerced to a Carbon URL pboard type. This
step handles a program like BibDesk which presently adds a webloc promise +
NSURLPboardType, where we want the NSURLPboardType data and ignore the HFS
promise. However, Finder puts all of these on the pboard, so don't add
duplicate items to the array...since we may have already added the content
(remote URL) if this is a webloc file.
- if ([[pboard types] containsObject:NSURLPboardType]) {
- NSURL *nsURL = [NSURL URLFromPasteboard:pboard];
- if (nsURL && [allURLsReadFromPasteboard containsObject:nsURL] == NO)
- [toReturn addObject:nsURL];
- }
-
- // ??? On 10.5, NSStringPboardType and kUTTypeUTF8PlainText point to the
same data, according to pasteboard peeker; if that's the case on 10.4, we can
remove this and the registration for NSStringPboardType.
- if ([[pboard types] containsObject:NSStringPboardType]) {
- // this can (and does) return nil under some conditions, so avoid an
exception
- NSString *stringURL = [pboard stringForType:NSStringPboardType];
- NSURL *nsURL = stringURL ? [NSURL URLWithString:stringURL] : nil;
- if ([nsURL scheme] != nil && [allURLsReadFromPasteboard
containsObject:nsURL] == NO)
- [toReturn addObject:nsURL];
- }
-
- return toReturn;
-}
-
-// Once we treat the NSPasteboard as a Carbon pboard, bad things seem to
happen on Tiger (-types doesn't work), so return the PasteboardRef by reference
to allow the caller to add more types to it or whatever.
-BOOL FVWriteURLsToPasteboard(NSArray *URLs, NSPasteboard *pboard)
-{
- OSStatus err;
-
- PasteboardRef carbonPboard;
- err = PasteboardCreate((CFStringRef)[pboard name], &carbonPboard);
-
- if (noErr == err)
- err = PasteboardClear(carbonPboard);
-
- if (noErr == err)
- (void)PasteboardSynchronize(carbonPboard);
-
- NSUInteger i, iMax = [URLs count];
-
- for (i = 0; i < iMax && noErr == err; i++) {
-
- NSURL *theURL = [URLs objectAtIndex:i];
- NSString *string = [theURL absoluteString];
- CFDataRef utf8Data = (CFDataRef)[string
dataUsingEncoding:NSUTF8StringEncoding];
-
- // any pointer type; private to the creating application
- PasteboardItemID itemID = (void *)theURL;
-
- // Finder adds a file URL and destination URL for weblocs, but only a
file URL for regular files
- // could also put a string representation of the URL, but Finder
doesn't do that
-
- if ([theURL isFileURL]) {
- err = PasteboardPutItemFlavor(carbonPboard, itemID,
kUTTypeFileURL, utf8Data, kPasteboardFlavorNoFlags);
- }
- else {
- err = PasteboardPutItemFlavor(carbonPboard, itemID, kUTTypeURL,
utf8Data, kPasteboardFlavorNoFlags);
- }
- }
-
- if (carbonPboard)
- CFRelease(carbonPboard);
-
- return noErr == err;
-}
-
-#pragma mark -
-
NSGraphicsContext *FVWindowGraphicsContextWithSize(NSSize size)
{
NSRect rect = NSZeroRect;
@@ -333,7 +127,7 @@
return [NSGraphicsContext graphicsContextWithWindow:window];
}
-#pragma mark -
+#pragma mark file mapping
#if defined(MAC_OS_X_VERSION_10_7) && MAC_OS_X_VERSION_MIN_REQUIRED >=
MAC_OS_X_VERSION_10_7
bool FVCanMapFileAtURL(NSURL *fileURL)
@@ -422,6 +216,8 @@
}
#endif
+#pragma mark Dark mode support
+
#if !defined(MAC_OS_X_VERSION_10_9) || MAC_OS_X_VERSION_MAX_ALLOWED <
MAC_OS_X_VERSION_10_9
@interface NSAppearance : NSObject <NSCoding>
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
_______________________________________________
Bibdesk-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bibdesk-commit