拖放从NSTableView到Finder的问题 [英] Problem with Drag-Drop from NSTableView to Finder

查看:227
本文介绍了拖放从NSTableView到Finder的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个应用程序,它有一个NSTableView,代表一系列文件。从这里,我想能够从我的NSTableView拖动一行(即文件名)到Finder,并在该文件夹中创建文件。但是,我无法解决的是,我需要修改原始文件的内容,之前它被复制到Finder。



我添加了下面这行,所以我可以拖出我的NSTableView:

  [self.tableView setDraggingSourceOperationMask:NSDragOperationCopy forLocal:NO]; 

我可以让它复制实际的文件,前提是我将当前文件位置添加到粘贴板,使用:

   - (BOOL)tableView:(NSTableView *)aTableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard: )pboard {
[pboard declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:nil];
NSMutableArray * dragfiles = [[NSMutableArray alloc] init];
NSString * file = [self.files objectAtIndex:row];
NSString * filepath = [[[self.pathControl URL] path] stringByAppendingPathComponent:file];
[dragfiles addObject:filepath];
[pboard setPropertyList:dragfiles forType:NSFilenamesPboardType];
[dragfiles release];
}

但是,因为我想修改文件的内容,我想把文件路径放在粘贴板上。我已经尝试使用NSFileWrapper,但Finder似乎不接受这是一个有效的格式。



我已经检查谷歌,我发现几个建议,你可以创建一个临时文件并使用该文件路径。但是,这感觉很丑陋。



是否可以向Finder发送数据?有没有办法解决这个问题?

解决方案

你最有可能想使用promise文件,或 NSFilesPromisePboardType ,而不是 NSFilenamesPboardType 。 (注意:promise文件方法 dragPromisedFilesOfTypes:fromRect:source:slideBack:event: namesOfPromisedFilesDroppedAtDestination: NSTableView 定义了更方便的方法,而不是通用的方法。说,应该仍然提供信息如何promise文件拖动工作)。 NSTableView 使用 tableView:namesOfPromisedFilesDroppedAtDestination:forDraggedRowsWithIndexes:,您可以在其中处理文件。在 tableView:writeRowsWithIndexes:toPasteboard:方法中,您将声明 NSFilesPromisePboardType ,然后设置一个文件扩展名计划写入的文件类型。下面是一个伪代码,概述你如何处理它:

   - (BOOL)tableView:(NSTableView *)aTableView 
writeRowsWithIndexes:(NSIndexSet *)rowIndexes
toPasteboard:(NSPasteboard *)pboard {
[pboard declareTypes:[NSArray arrayWithObjects:NSFilesPromisePboardType,nil]];

NSMutableArray * filenameExtensions = [NSMutableArray array];
NSArray * draggedFilenames = [self.files objectsAtIndexes:rowIndexes];
for(NSString * filename in draggedFilenames){
NSString * filenameExtension = [filename pathExtension];
if(filenameExtension.length){
[filenameExtensions addObject:filenameExtension];
}
}
[pboard setPropertyList:filenameExtensions
forType:NSFilesPromisePboardType];
return YES;
}

然后在您的promiseFiles名称方法中:



- (NSArray *)tableView:(NSTableView *)aTableView
namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination
forDraggedRowsWithIndexes:(NSIndexSet * )indexSet {

NSArray * draggedFilenames = [self.files objectsAtIndexes:indexSet];

for(NSString * filename in draggedFilenames){
//在这里处理文件
//如果可能需要很长时间,你可能需要做在背景
//线程

NSString * fullPathToOriginal = nil;
NSString * destPath =
[[dropDestination path] stringByAppendingPathComponent:filename];


}
return draggedFilenames;
}

您应该能够计算原始文件路径重新确定它,所以我离开它 nil 在上面的代码)和目标文件路径(使用类似上面的代码)。


I've created an app that has a NSTableView which represents a series of files. From this, I want to be able to drag a row (i.e. a filename) from my NSTableView to Finder, and the file be created in that folder. However, the bit I can't work out is that I need to modify the contents of the original file, before it gets copied to Finder.

I've added the following line so I can drag outside of my NSTableView:

[self.tableView setDraggingSourceOperationMask:NSDragOperationCopy forLocal:NO];    

And I can get it to copy the actual file, provided I add a current files location to the pasteboard, using:

- (BOOL)tableView:(NSTableView *)aTableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard {
    [pboard declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:nil];        
    NSMutableArray* dragfiles = [[NSMutableArray alloc] init];
    NSString* file = [self.files objectAtIndex:row];
    NSString* filepath = [[[self.pathControl URL] path] stringByAppendingPathComponent:file];
    [dragfiles addObject:filepath];
    [pboard setPropertyList:dragfiles forType: NSFilenamesPboardType];
    [dragfiles release];
} 

But, because I want to modify the contents of the file, I don't want to put filepaths onto the pasteboard. I've tried using NSFileWrapper, but Finder doesnt seem to accept this as a valid format.

I've checked Google, and I've found several suggestions that you can create a temporary file and use that filepath. But, this feels ugly.

Is it possible to send data to Finder? Is there a way to solve this?

解决方案

You will most likely want to use promise files, or NSFilesPromisePboardType rather than NSFilenamesPboardType. (Note: the promise file methods dragPromisedFilesOfTypes:fromRect:source:slideBack:event: and namesOfPromisedFilesDroppedAtDestination: that that documentation talks about are the generic NSView methods. NSTableView defines more convenient methods that you'll use instead of the generic ones. That said, that should still provide info on how promise file drags work). NSTableView uses tableView:namesOfPromisedFilesDroppedAtDestination:forDraggedRowsWithIndexes:, which is where you can do the processing of your files. In your tableView:writeRowsWithIndexes:toPasteboard: method, you'll declare NSFilesPromisePboardType, then set an array of filename extensions for the types of files you plan to write. The following is pseudo-code that outlines how you might approach it:

- (BOOL)tableView:(NSTableView *)aTableView
     writeRowsWithIndexes:(NSIndexSet *)rowIndexes
        toPasteboard:(NSPasteboard *)pboard {
     [pboard declareTypes:[NSArray arrayWithObjects:NSFilesPromisePboardType, nil]];

     NSMutableArray *filenameExtensions = [NSMutableArray array];
     NSArray *draggedFilenames = [self.files objectsAtIndexes:rowIndexes];
     for (NSString *filename in draggedFilenames) {
          NSString *filenameExtension = [filename pathExtension];
          if (filenameExtension.length) {
              [filenameExtensions addObject:filenameExtension];
          }
     }
     [pboard setPropertyList:filenameExtensions
                 forType:NSFilesPromisePboardType];
     return YES;
}

Then in your names-of-promisedFiles method:

- (NSArray *)tableView:(NSTableView *)aTableView
       namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination
       forDraggedRowsWithIndexes:(NSIndexSet *)indexSet {

     NSArray *draggedFilenames = [self.files objectsAtIndexes:indexSet];

     for (NSString *filename in draggedFilenames) {
           // do your processing of files in here
          // if it may take a long time, you might need to do it on a background
          // thread

         NSString *fullPathToOriginal = nil;
          NSString *destPath =
         [[dropDestination path] stringByAppendingPathComponent:filename];


     }
     return draggedFilenames;
}

You should be able to calculate the original file path (not sure how you're determining it, so I left it nil in the code above) and the destination file path (using something like in the code above).

这篇关于拖放从NSTableView到Finder的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆