Перетаскивание файлов

При перетаскивании файлов область монтажа перетаскивания может передать файлы четырьмя различными способами. Область монтажа может содержать список путей к файлам, единственного URL, полного содержания файла или обещания создать файлы в расположении, которое будет определено местом назначения. Каждый стиль соответствует отдельному типу данных NSPasteboard и имеет различный метод для чтения и записи перетащенных данных. Следующие разделы описывают каждый стиль и как обработать их, являетесь ли Вы источником перетаскивания или местом назначения.

Перетаскивание файла URLs

Файлы могут также быть указаны их URLs. URL Файла сохранен в области монтажа с типом NSURLPboardType. В отличие от этого NSFilenamesPboardType, который содержит массив путей к файлам, NSURLPboardType введите содержит единственный объект NSURL. Не возможно сохранить больше чем один URL на области монтажа с помощью этого типа области монтажа, таким образом, Вы не можете перетащить больше чем один файл с URL.

Для инициирования работы перетаскивания на файле с помощью его URL необходимо использовать NSView или метод NSWindow dragImage:at:offset:event:pasteboard:source:slideBack:. Необходимо поместить URL файла на область монтажа сами, с помощью метода NSURL writeToPasteboard:. Необходимо объявить NSURLPboardType прежде, чем вызвать этот метод, все же. Это позволяет Вам помещать и путь к файлу и файл URL на область монтажа. Работа перетаскивания может тогда быть отброшена на местах назначения, зарегистрировавшихся, или для перетащите тип или для обоих. Следующий пример кода показывает возможную реализацию для записи данных к области монтажа.

// Write data to the pasteboard
NSURL *fileURL; // Assume this exists
NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
[pboard declareTypes:[NSArray arrayWithObject:NSURLPboardType] owner:nil];
[fileURL writeToPasteboard:pboard];

Посмотрите Пути к файлам Перетаскивания для большего количества кода полной выборки запуска работы перетаскивания.

После того, как работа перетаскивания отбрасывается, место назначения перетаскивания получает a performDragOperation: сообщение. Извлечь NSURLPboardType данные от области монтажа, используйте метод класса NSURL URLFromPasteboard:.

- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
    NSPasteboard *pboard = [sender draggingPasteboard];
 
    if ( [[pboard types] containsObject:NSURLPboardType] ) {
        NSURL *fileURL = [NSURL URLFromPasteboard:pboard];
        // Perform operation using the file’s URL
    }
    return YES;
}

Перетаскивание содержания файла

Файлы не должны быть перетащены с помощью ссылок на файл только; содержание файла может быть помещено непосредственно на область монтажа и перетащило использование NSFileContentsPboardType. Используйте этот тип области монтажа, когда Вы захотите предоставить содержание файла вместо его расположения в файловой системе. Место назначения может принять решение извлечь данные непосредственно к расположению в файловой системе, которую они указывают или в обертку файла в памяти.

Для инициирования работы перетаскивания на содержании файла необходимо использовать NSView или метод NSWindow dragImage:at:offset:event:pasteboard:source:slideBack:. Необходимо поместить содержание файла на область монтажа сами. Можно записать данные в область монтажа с помощью любого writeFileContents: метод, считывающий данные непосредственно из файловой системы, или writeFileWrapper: метод, считывающий данные из NSFileWrapper, возражает, что Вы уже создали. Следующий пример кода показывает возможную реализацию для записи данных к области монтажа.

// Write data to the pasteboard
NSString *filename; // Assume this exists
NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
[pboard writeFileContents:filename];

Посмотрите Пути к файлам Перетаскивания для большего количества кода полной выборки запуска работы перетаскивания.

В дополнение к записи содержания файла к области монтажа с общим типом NSFileContentsPboardType, writeFileContents: и writeFileWrapper: методы пишут данные с более определенным типом на основе расширения файла файла, если это существует. Место назначения перетаскивания может зарегистрироваться для этого более определенного типа вместо универсального типа для ограничения, перетаскивает к файлам определенного типа, такой как mp3 или mov файлы. Можно получить имя этого определенного типа области монтажа путем передачи расширения файла NSCreateFileContentsPboardType функция, возвращающая NSString. Следующий пример кода показывает, как представление могло зарегистрироваться для получения только файлов фильма в формате QuickTime.

NSString *pboardType = NSCreateFileContentsPboardType(@"mov");
NSArray *dragTypes = [NSArray arrayWithObject:pboardType];
[self registerForDraggedTypes:dragTypes];

После того, как работа перетаскивания отбрасывается, место назначения перетаскивания получает a performDragOperation: сообщение. Для извлечения содержания файла из области монтажа используйте любого readFileContentsType:toFile: метод, копирующий данные с области монтажа и пишущий его в путь к файлу, который Вы указываете, или readFileWrapper метод, создающий объект NSFileWrapper из данных области монтажа.

- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
    NSPasteboard *pboard = [sender draggingPasteboard];
 
    if ( [[pboard types] containsObject:NSFileContentsPboardType] ) {
        NSFileWrapper *fileContents = [pboard readFileWrapper];
        // Perform operation using the file’s contents
    }
    return YES;
}

Перетаскивание обещаний файла

В некоторых случаях можно хотеть перетащить файл, прежде чем он фактически будет существовать в файловой системе. У Вас может быть новый документ, не сохраненный, еще, или возможно файл существует в удаленной системе, такой как веб-сервер, к которому у места назначения перетаскивания может не быть доступа. (Как правило, местом назначения является Средство поиска.) В этих случаях работа перетаскивания служит методом для указания расположения, в котором можно сохранить новый файл. Когда работа перетаскивания отбрасывается, место назначения перетаскивания говорит источник, где это хочет сохраненные файлы, и источник перетаскивания создает файлы. Этот тип перетаскивания файла вызывают обещанием HFS, потому что в сущности работа перетаскивания содержит обещание от источника до места назначения, что источник создаст указанные файлы, если будет принята работа перетаскивания. Данные по области монтажа имеют тип NSFilesPromisePboardType.

Для инициирования обещания HFS перетаскивают работу на одном или более файлах, необходимо использовать метод NSView dragPromisedFilesOfTypes:fromRect:source:slideBack:event:. Первым параметром является массив, перечисляющий типы файлов всех файлов, которые источник обещает создать. Типы могут быть указаны как расширения файла или поскольку типы файлов HFS закодировали использование NSFileTypeForHFSTypeCode функция. Если иерархия каталогов перетаскивается, только файлы верхнего уровня и каталоги должны быть перечислены в массиве типа. dragPromisedFiles... метод помещает массив типа файла на область монтажа перетаскивания с NSFilesPromisePboardType тип области монтажа и запускает работу перетаскивания.

- (void)mouseDown:(NSEvent *)theEvent
{
    NSPoint dragPosition;
    NSRect imageLocation;
 
    dragPosition = [self convertPoint:[theEvent locationInWindow]
                        fromView:nil];
    dragPosition.x -= 16;
    dragPosition.y -= 16;
    imageLocation.origin = dragPosition;
    imageLocation.size = NSMakeSize(32,32);
    [self dragPromisedFilesOfTypes:[NSArray arrayWithObject:@"pdf"]
            fromRect:imageLocation
            source:self
            slideBack:YES
            event:theEvent];
}

При перетаскивании обещаний HFS источник перетаскивания должен также реализовать namesOfPromisedFilesDroppedAtDestination: метод. Когда место назначения принимает работу перетаскивания, этот метод вызывается. Отдельный аргумент является объектом NSURL, идентифицирующим расположение в файловой системе, что источник должен создать файлы. Метод возвращает список имен файлов (не полные пути) всех файлов, которые источник обещал создать. Если иерархия каталогов перетаскивается, только объекты верхнего уровня должны быть перечислены в возвращенном массиве.

Для коротких операций можно создать обещанные файлы в namesOfPromisedFilesDroppedAtDestination: метод. Для длинных операций, однако, необходимо задержать создание файлов до позже, чтобы избежать блокировать целевое приложение. Один метод должен кэшировать целевой URL и создать файлы в Вашем источнике draggedImage:endedAt:operation: метод. Также Вы могли породить фоновый поток, чтобы создать файлы или задержать действие с текущим потоком с помощью NSTimer, NSNotificationQueue или метода NSObject performSelector:withObject:afterDelay:.

Прежде чем перетаскивание фактически отбрасывается, у потенциального места назначения перетаскивания нет доступа к именам файлов файлов обещанным. Только типы файлов доступны от области монтажа. Место назначения может получить типы файлов путем запроса области монтажа NSFilesPromisePboardType данные с помощью propertyListForType: метод. Возвращенный массив содержит типы файлов, которые источник передал dragPromisedFiles... метод. Место назначения может тогда принять или отклонить работу перетаскивания на основе содержания массива типов.

После того, как работа перетаскивания отбрасывается, место назначения перетаскивания получает a performDragOperation: сообщение. Чтобы указать расположение отбрасывания и получить имена файлов обещанных файлов, используйте информационный объект перетаскивания namesOfPromisedFilesDroppedAtDestination: метод, передавая NSURL для расположения отбрасывания как один параметр. Возвращаемое значение является массивом имен файлов (не полные пути) файлов, которые создаст источник. Место назначения перетаскивания должно вызвать этот метод только в performDragOperation: или иначе источник может создать файлы в неправильном расположении.

NSURL *dropLocation; // Assume this exists
 
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
    NSPasteboard *pboard = [sender draggingPasteboard];
 
    if ( [[pboard types] containsObject:NSFilesPromisePboardType] ) {
        NSArray *filenames = [sender
                namesOfPromisedFilesDroppedAtDestination:dropLocation];
        // Perform operation using the files’ names, but without the
        // files actually existing yet
    }
    return YES;
}

Перетаскивание путей к файлам

Исторически, некоторые приложения поддерживали перетаскивание файлов путем передачи списка путей файлов. Источник перетаскивания создает NSArray, содержащий объекты NSString всех путей файлов, которые будут перетащены, и помещает массив на область монтажа с типом данных NSFilenamesPboardType. Место назначения перетаскивания тогда читает массив из области монтажа и выполняет требуемую работу с помощью путей, которые это содержит.

Для инициирования работы перетаскивания для единственного файла можно использовать метод NSView dragFile:fromRect:slideBack:event: когда пользователь щелкает в представлении, представляющем файл. Первым параметром является путь файла для перетаскивания. Этот метод помещает путь файла на область монтажа перетаскивания с NSFilenamesPboardType тип области монтажа и запускает работу перетаскивания.

Для инициирования работы перетаскивания на многократных файлах необходимо использовать NSView или метод NSWindow dragImage:at:offset:event:pasteboard:source:slideBack:. Необходимо поместить массив путей к файлам на область монтажа сами, с помощью метода NSPasteboard setPropertyList:forType:. Следующий пример кода показывает возможную реализацию.

NSString *filePath1, *filePath2; // Assume these exist
 
- (void)mouseDown:(NSEvent *)theEvent
{
    NSImage *dragImage;
    NSPoint dragPosition;
 
    // Write data to the pasteboard
    NSArray *fileList = [NSArray arrayWithObjects:filePath1, filePath2, nil];
    NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
    [pboard declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType]
            owner:nil];
    [pboard setPropertyList:fileList forType:NSFilenamesPboardType];
 
    // Start the drag operation
    dragImage = [[NSWorkspace sharedWorkspace] iconForFile:filePath1];
    dragPosition = [self convertPoint:[theEvent locationInWindow]
                        fromView:nil];
    dragPosition.x -= 16;
    dragPosition.y -= 16;
    [self dragImage:dragImage
            at:dragPosition
            offset:NSZeroSize
            event:theEvent
            pasteboard:pboard
            source:self
            slideBack:YES];
}

После того, как работа перетаскивания отбрасывается, место назначения перетаскивания получает a performDragOperation: сообщение. Извлечь NSFilenamesPboardType данные от области монтажа, используйте propertyListForType: метод. Даже если только один файл перетаскивается, путь файла сохранен в NSArray.

- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
    NSPasteboard *pboard = [sender draggingPasteboard];
 
    if ( [[pboard types] containsObject:NSFilenamesPboardType] ) {
        NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];
        int numberOfFiles = [files count];
        // Perform operation using the list of files
    }
    return YES;
}