2011-07-13 8 views
8

Stworzyłem aplikację, która ma NSTableView, który reprezentuje serię plików. Z tego chcę móc przeciągnąć wiersz (tj. Nazwę pliku) z mojego NSTableView do Findera, a plik zostanie utworzony w tym folderze. Jednak nie mogę zrozumieć, że muszę zmodyfikować zawartość oryginalnego pliku, zanim zostanie on skopiowany do Findera.Problem z Drag-Drop z NSTableView do Findera

Dodałem następujący wiersz więc mogę przeciągnąć poza moim NSTableView:

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

I mogę je skopiować rzeczywisty plik, pod warunkiem dodać aktualną lokalizację plików na stole montażowym, używając :

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

jednak, ponieważ chcę, aby zmodyfikować zawartość pliku, nie chcę umieścić filepaths na stole montażowym. Próbowałem używać NSFileWrapper, ale Finder nie wydaje się, aby zaakceptować to jako prawidłowy format.

Sprawdziłem Google i znalazłem kilka sugestii, że możesz utworzyć tymczasowy plik i użyć tej ścieżki do pliku. Ale to jest brzydkie.

Czy można wysłać dane do Findera? Czy istnieje sposób na rozwiązanie tego problemu?

Odpowiedz

17

Najprawdopodobniej będziesz chciał użyć plików obietnicy lub NSFilesPromisePboardType zamiast NSFilenamesPboardType. (Uwaga: metody plików obietnic są dostępne w przypadku metod, o których mowa w tym dokumencie: są to metody generyczne, które są bardziej wygodne niż standardowe, co powinno dostarczyć informacji na temat przeciągania pliku obietnicy. praca). NSTableView używa tableView:namesOfPromisedFilesDroppedAtDestination:forDraggedRowsWithIndexes:, gdzie można wykonywać przetwarzanie plików. W swojej metodzie tableView:writeRowsWithIndexes:toPasteboard: zadeklarujesz NSFilesPromisePboardType, a następnie ustawisz tablicę rozszerzeń plików dla typów plików, które zamierzasz zapisać. Poniżej znajduje pseudo-kod, który określa w jaki sposób można go podejść:

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

Następnie w swoich nazwach-of-promisedFiles metody:

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

Powinieneś być w stanie obliczyć oryginalną ścieżkę do pliku (nie pewnie, jak to określasz, więc zostawiłem to w kodzie powyżej) i ścieżkę pliku docelowego (używając czegoś podobnego do powyższego kodu).

+0

Awesome. Wielkie dzięki. Czy to działało 5 minut po przeczytaniu tego (po 3 godzinach próbowania dostać coś działającego ostatniej nocy). W moim błędzie brakowało znaczenia rozszerzeń plików dla początkowej obietnicy. Dzięki jeszcze raz. – RichS

+0

+1 Doskonała i rzadka odpowiedź! – trojanfoe

5

Coś, na co należy uważać.

W NSPasteboard.h nie jest komentarz, który mówi:

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

i po definicji NSFilesPromisePboardType mówi:

// Use (NSString *)kPasteboardTypeFileURLPromise 

Właśnie spędziłem kilka godzin walić głową w mur, bo byłem przechodzi w (NSString *)kPasteboardTypeFileURLPromise zamiast NSFilesPromisePboardType w kilku miejscach.

Wygląda na to, że nie robią dokładnie tego samego. Nie mogłem się domyślić, dlaczego:

tableView:namesOfPromisedFilesDroppedAtDestination:forDraggedRowsWithIndexes 

nie został wywołany.Kiedy przełączyłem się ponownie na NSFilesPromisePboardType,
nagle został wywołany.

+4

'NSFilesPromisePboardType' oczekuje rozszerzeń plików; 'kPasteboardTypeFileURLPromise' oczekuje adresów URL plików; 'kPasteboardTypeFilePromiseContent' (wspomniane tylko w Pasteboard.h, AFAIK) oczekuje terminali UTI. Ostatni jest nowoczesnym zamiennikiem pierwszego. –

+0

Dzięki za te cenne wskazówki, ale w jaki sposób podajesz adresy URL do kPasteboardTypeFileURLPromise? NSURL nie jest typem obszaru roboczego. – Nickkk

Powiązane problemy