Re: Bug in 10.6 NSPasteboard API? (was: Sending a list of path strings to the Finder via Scripting Bridge)

2012-05-27 Thread Ken Thomases
On May 26, 2012, at 4:41 AM, Peter wrote:

 thank you very much for your enlightening and in-depth explanation!

You're welcome.


 With the old API I could (and still do) put a list of path strings with empty 
 elements on the pasteboard, e.g. four paths, the third one empty as in
 
 /path1/item1
 /path2/item1
 
 /path2/item2
 
 but since the new API moved to NSURLs I don't see a way to accomplish this. I 
 could not find something like an empty NSURL. I use this for copying data 
 from a table area to another table or table area, meaning the empty element 
 is a valid piece of data. Any ideas?

I'm not certain.  You can try putting an NSPasteboardItem to which you haven't 
added any data in the list of items.  You can try adding some other type of 
data, perhaps a custom type which indicates to your app that there's no data.  
You can put a different kind of NSURL, rather than a file URL, perhaps with a 
custom scheme meaningful only to your app.  Etc.

The main thing is to think of the pasteboard contents as multiple items, each 
with its own types/representations, which can be (but doesn't have to be) 
different from all of the other items.

Regards,
Ken


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Bug in 10.6 NSPasteboard API? (was: Sending a list of path strings to the Finder via Scripting Bridge)

2012-05-26 Thread Ken Thomases
On May 26, 2012, at 2:42 AM, Peter wrote:

 One more half-baked technology from Apple (as is the new pasteboard API in 
 its current implementation even if it looks very elegant on the surface - I 
 guess quite a good deal of people will be bitten by it if it becomes 
 compulsory, since it prevents you from doing some simple things possible with 
 the current API; see my inquiry on this list a couple of weeks ago).

This led me to look up your earlier messages, quoted below:

On February 27, 2012, at 2:44 AM, Peter wrote:

 I am still very much puzzled by the issue I described below, so I still hope 
 to find a taker for it.
 
 While the OS 10.5 API cleanly separated pasteboard types, the 10.6 API 
 converts NSURL data to strings and adds it to any existing string data - i.e. 
 when pasting the data into e.g. a text view in 10.6 I get
 
 file://localhost/Users/peterjhartmann/Desktop/Eigene Bilder/jan.jpg
 file://localhost/Users/peterjhartmann/Desktop/Eigene Bilder/Nob.jpg
 jan
 Nob
 
 instead of
 
 jan
 Nob
 
 which is the result using the 10.5 API. As described, this happens no matter 
 wether I use writeObjects: or setString: and no matter wether I write the 
 URLs before or after the strings.
 
 I consider this to be a bug. Am I wrong? If so, what am I doing wrong?
 
 Does anybody use the 10.6 pasteboard API? Judging from my web searches it 
 seems that almost nobody does.
 
 One member contacted my privately stating ...
 
  Not sure if you've fixed this or had any other replies, but in reading it 
  through, I notice you're not declaring the pasteboard type ([pb 
  declareTypes:...]) within this block.  Does this explain the symptoms?
 
 but declareTypes belongs to the old API. Mixing this with the new API is 
 discouraged on p. 33 of Apple's PasteboardGuide106.pdf.
 
 I'd be very happy about any pointers into the right direction.
 
 My original post is here:
 
 Am 19.02.2012 um 21:24 schrieb Peter:
 
  I am using the following code:
 
   NSPasteboard *pb = [NSPasteboard generalPasteboard];
 
   if (floor(NSAppKitVersionNumber) = NSAppKitVersionNumber10_5) {
  //linesArray contains file paths as NSStrings
  //namesArray contains file names as NSStrings
  [pb declareTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, 
  NSStringPboardType, nil] owner:nil];
  [pb setPropertyList:linesArray forType:NSFilenamesPboardType];
  [pb setString:[namesArray componentsJoinedByString:@\n] 
  forType:NSStringPboardType];
   }
   else { // = 10.6
  //linesArray contains NSURLs
  //namesArray contains file names as NSStrings
  [pb clearContents];
  [pb setString:[namesArray componentsJoinedByString:@\n] 
  forType:NSPasteboardTypeString];
//[pb writeObjects:namesArray];
  [pb writeObjects:linesArray]; // write the URLs
  }

I think you are failing to understand the nature of the change introduced with 
10.6.  Prior to 10.6, there was always a single pasteboard item.  It could have 
multiple types/representations.

Since it is clearly sometimes desirable to have multiple things on the 
pasteboard, there was a hack.  Some of the types were plural, like 
NSFilenamesPboardType.  So, with your 10.5 code path, there's a single item.  
One of its types/representations is an array of filenames, the other is a 
string (which you've constructed by joining multiple strings with newlines).

From 10.6, the pasteboard supports multiple items.  _Each_ item can have 
multiple types/representations.  Because of that, it's no longer necessary to 
use plural types like NSFilenamesPboardType.  You can just add an array of 
NSURLs.

However, if you add NSURLs and you add strings, you have established that _all_ 
of those items are on the pasteboard _individually_.  Given how you've done it, 
the URLs and the strings are not alternative representations of the same items, 
they are all separate items on the pasteboard.  It is not a bug for TextEdit to 
paste them all; it would be a bug for it to not do so.

If what you want is a number of items, where each item has two 
types/representations – a URL or a string – then that's what you have to put on 
the pasteboard.  Create an NSPasteboardItem for each item.  For each item, for 
each type/representation, set the data.  So, if an item is supposed to have an 
NSURL representation and a string representation, do something like:

for (NSString* type in [someURL writableTypesForPasteboard:pb])
[item setPropertyList:[someURL pasteboardPropertyListForType:type] 
forType:type];
[item setString:someString forType:NSPasteboardTypeString];

Put all of the pasteboard items constructed in this manner into an array and 
write that array to the pasteboard using -writeObject:. Then you will have set 
up the pasteboard in a manner that's analogous to what you were doing with the 
10.5 API.

Regards,
Ken


___

Cocoa-dev mailing list 

Re: Bug in 10.6 NSPasteboard API? (was: Sending a list of path strings to the Finder via Scripting Bridge)

2012-05-26 Thread Peter
Ken,

thank you very much for your enlightening and in-depth explanation! This is 
what I hoped somehow to receive back in February...

Over the next days I will try and put your approach to practice. If it works as 
I hope I will certainly withdraw my comment about the new API being a 
half-baken technology.

Since you are at it ;-), I remember having one more problem back then:

With the old API I could (and still do) put a list of path strings with empty 
elements on the pasteboard, e.g. four paths, the third one empty as in

/path1/item1
/path2/item1

/path2/item2

but since the new API moved to NSURLs I don't see a way to accomplish this. I 
could not find something like an empty NSURL. I use this for copying data from 
a table area to another table or table area, meaning the empty element is a 
valid piece of data. Any ideas?

Thank you!

Am 26.05.2012 um 11:13 schrieb Ken Thomases:

 On May 26, 2012, at 2:42 AM, Peter wrote:
 
 One more half-baked technology from Apple (as is the new pasteboard API in 
 its current implementation even if it looks very elegant on the surface - I 
 guess quite a good deal of people will be bitten by it if it becomes 
 compulsory, since it prevents you from doing some simple things possible 
 with the current API; see my inquiry on this list a couple of weeks ago).
 
 This led me to look up your earlier messages, quoted below:
 
 On February 27, 2012, at 2:44 AM, Peter wrote:
 
 I am still very much puzzled by the issue I described below, so I still hope 
 to find a taker for it.
 
 While the OS 10.5 API cleanly separated pasteboard types, the 10.6 API 
 converts NSURL data to strings and adds it to any existing string data - 
 i.e. when pasting the data into e.g. a text view in 10.6 I get
 
 file://localhost/Users/peterjhartmann/Desktop/Eigene Bilder/jan.jpg
 file://localhost/Users/peterjhartmann/Desktop/Eigene Bilder/Nob.jpg
 jan
 Nob
 
 instead of
 
 jan
 Nob
 
 which is the result using the 10.5 API. As described, this happens no matter 
 wether I use writeObjects: or setString: and no matter wether I write the 
 URLs before or after the strings.
 
 I consider this to be a bug. Am I wrong? If so, what am I doing wrong?
 
 Does anybody use the 10.6 pasteboard API? Judging from my web searches it 
 seems that almost nobody does.
 
 One member contacted my privately stating ...
 
 Not sure if you've fixed this or had any other replies, but in reading it 
 through, I notice you're not declaring the pasteboard type ([pb 
 declareTypes:...]) within this block.  Does this explain the symptoms?
 
 but declareTypes belongs to the old API. Mixing this with the new API is 
 discouraged on p. 33 of Apple's PasteboardGuide106.pdf.
 
 I'd be very happy about any pointers into the right direction.
 
 My original post is here:
 
 Am 19.02.2012 um 21:24 schrieb Peter:
 
 I am using the following code:
 
 NSPasteboard *pb = [NSPasteboard generalPasteboard];
 
 if (floor(NSAppKitVersionNumber) = NSAppKitVersionNumber10_5) {
//linesArray contains file paths as NSStrings
//namesArray contains file names as NSStrings
[pb declareTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, 
 NSStringPboardType, nil] owner:nil];
[pb setPropertyList:linesArray forType:NSFilenamesPboardType];
[pb setString:[namesArray componentsJoinedByString:@\n] 
 forType:NSStringPboardType];
 }
 else { // = 10.6
//linesArray contains NSURLs
//namesArray contains file names as NSStrings
[pb clearContents];
[pb setString:[namesArray componentsJoinedByString:@\n] 
 forType:NSPasteboardTypeString];
  //[pb writeObjects:namesArray];
[pb writeObjects:linesArray]; // write the URLs
}
 
 I think you are failing to understand the nature of the change introduced 
 with 10.6.  Prior to 10.6, there was always a single pasteboard item.  It 
 could have multiple types/representations.
 
 Since it is clearly sometimes desirable to have multiple things on the 
 pasteboard, there was a hack.  Some of the types were plural, like 
 NSFilenamesPboardType.  So, with your 10.5 code path, there's a single item.  
 One of its types/representations is an array of filenames, the other is a 
 string (which you've constructed by joining multiple strings with newlines).
 
 From 10.6, the pasteboard supports multiple items.  _Each_ item can have 
 multiple types/representations.  Because of that, it's no longer necessary to 
 use plural types like NSFilenamesPboardType.  You can just add an array of 
 NSURLs.
 
 However, if you add NSURLs and you add strings, you have established that 
 _all_ of those items are on the pasteboard _individually_.  Given how you've 
 done it, the URLs and the strings are not alternative representations of the 
 same items, they are all separate items on the pasteboard.  It is not a bug 
 for TextEdit to paste them all; it would be a bug for it to not do so.
 
 If what you want is a number of items, where