2011-07-13 15 views
8

一連のファイルを表すNSTableViewを持つアプリケーションを作成しました。これで、NSTableViewからFinderに行(ファイル名)をドラッグして、そのフォルダにファイルを作成できるようにしたいと考えています。しかし、私がうまくいかないのは、Finderにコピーされる前に元のファイルの内容を変更する必要があることです。NSTableViewからFinderへのドラッグドロップの問題

私は私が私のNSTableViewの外にドラッグすることができるように次の行を追加しました:

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

をそして、私はそれが実際のファイルをコピーするために取得することができ、私が使用して、ペーストボードに現在のファイルの場所を追加提供:

- (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]; 
} 

しかし、私はファイルの内容を変更したいので、私はペーストボードにファイルパスを入れたくありません。私はNSFileWrapperを使ってみましたが、Finderはこれを有効なフォーマットとして受け入れていないようです。

私はGoogleをチェックしましたが、一時ファイルを作成してそのファイルパスを使用できるといういくつかの提案があります。しかし、これは醜いと感じます。

Finderにデータを送信することはできますか?これを解決する方法はありますか?

答えて

17

おそらく約束ファイル、またはNSFilenamesPboardTypeではなくNSFilesPromisePboardTypeを使用することをお勧めします。 (注:promiseファイルのメソッドdragPromisedFilesOfTypes:fromRect:source:slideBack:event:namesOfPromisedFilesDroppedAtDestination:は、そのドキュメントでは一般的なNSViewメソッドです。NSTableViewは、より一般的なメソッドではなく、より便利なメソッドを定義しています。作業)。 NSTableViewtableView: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; 
} 

次に、あなたの名前・オブ・promisedFiles方法で:

- (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; 
} 

あなたは、元のファイルのパスを計算することができるはずです(ありませんどのようにそれを決定しているので、上のコードでnil)と目的ファイルのパス(上のコードのようなものを使用)を残しました。

+0

驚くばかりです。とても感謝しています。それを読んだ後5分で作業していた(昨晩働くために3時間を費やしていた)。私の間違いは、最初の約束のためのファイル拡張子の関連性を見逃していました。再度、感謝します。 – RichS

+0

+1すばらしく珍しい答え! – trojanfoe

5

何か注意してください。

/* Use of pboard types should be replaced with use of UTIs. 
    Pboard types will be deprecated in a future release. */ 

そしてNSFilesPromisePboardType定義した後、こう述べています:

// Use (NSString *)kPasteboardTypeFileURLPromise 

は、私はちょうど私があったので、レンガの壁に頭を叩いて数時間を過ごしたのNSPasteboard.h

氏は述べていますコメントありいくつかの場所でNSFilesPromisePboardTypeの代わりに(NSString *)kPasteboardTypeFileURLPromiseを渡します。

彼らはまったく同じことをしていないようです。私は理由を理解できませんでした:

tableView:namesOfPromisedFilesDroppedAtDestination:forDraggedRowsWithIndexes 

は呼び出されていませんでした。NSFilesPromisePboardTypeに戻ったときに、突然、
と呼ばれました。

+4

'NSFilesPromisePboardType'はファイル拡張子を要求します。 'kPasteboardTypeFileURLPromise'はファイルURLを要求します。 'kPasteboardTypeFilePromiseContent'(Pasteboard.h、AFAIKでのみ言及されています)ではUTIが必要です。最後は最初のものの現代的な置き換えです。 –

+0

これらの貴重なヒントをいただきありがとうございますが、どのようにURLをkPasteboardTypeFileURLPromiseに提供しますか? NSURLはペーストボードタイプではありません。 – Nickkk

関連する問題