Какао QuickLook по инициативе NSTableView Cell - PullRequest
1 голос
/ 25 декабря 2010

У меня есть NSTableView, который содержит 2 разных столбца - один представляет собой NSImageCell, который показывает значок файла, а второй - это собственный подкласс NSTextFieldCell, который содержит кнопку быстрого просмотра справа от текста. Когда я нажимаю кнопку «Быстрый просмотр», вызывается следующий код:

[[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFront:nil];

Это делает свою работу и показывает пустую панель быстрого просмотра с надписью "Нет выбранных элементов". После небольшого исследования Интернета я реализовал собственный подкласс NSTableView, который будет делегатом и источником данных для панели быстрого просмотра. Я получаю уведомление, что Беглый взгляд спрашивает, хочу ли я быть делегатом, и я отвечаю, возвращая ДА. Несмотря на то, что я реализую все методы в QLPreviewPanelDataSource и QLPreviewPanelDelegate, во время выполнения я получаю эту ошибку на консоли:

2010-12-24 15:32:17.235 BackMeUp[4763:80f] clicked: ~/Desktop/HUDTape.mov
2010-12-24 15:32:17.489 BackMeUp[4763:80f] [QL] QLError(): -[QLPreviewPanel setDelegate:] called while the panel has no controller - Fix this or this will raise soon.
See comments in QLPreviewPanel.h for -acceptsPreviewPanelControl:/-beginPreviewPanelControl:/-endPreviewPanelControl:.
2010-12-24 15:32:17.490 BackMeUp[4763:80f] [QL] QLError(): -[QLPreviewPanel setDataSource:] called while the panel has no controller - Fix this or this will raise soon.
See comments in QLPreviewPanel.h for -acceptsPreviewPanelControl:/-beginPreviewPanelControl:/-endPreviewPanelControl:.
2010-12-24 15:32:17.491 BackMeUp[4763:80f] We can now receive QL Events.
2010-12-24 15:32:18.291 BackMeUp[4763:80f] -[NSPathStore2 stringValue]: unrecognized selector sent to instance 0x5ecb10
2010-12-24 15:32:18.292 BackMeUp[4763:80f] -[NSPathStore2 stringValue]: unrecognized selector sent to instance 0x5ecb10

И панель быстрого просмотра не отображается, что я нахожу довольно странным. Первая строка выше только что я знаю, что ячейка была нажата. В любом случае, вот .m файл подкласса пользовательского табличного представления:

//
//  BackupListTableView.m
//  BackMeUp
//
//  Created by Tristan Seifert on 12/24/10.
//  Copyright 2010 24/7 Server. All rights reserved.
//

#import "BackupListTableView.h"


@implementation BackupListTableView

- (void) awakeFromNib {

}

// Quick Look Delegates

- (BOOL)acceptsPreviewPanelControl:(QLPreviewPanel *)panel;
{
    [QLPreviewPanel sharedPreviewPanel].delegate = self;
    [QLPreviewPanel sharedPreviewPanel].dataSource = self;

    NSLog(@"We can now receive QL Events.");

    return YES;
}

- (void)beginPreviewPanelControl:(QLPreviewPanel *)panel
{
    // This document is now responsible of the preview panel
    // It is allowed to set the delegate, data source and refresh panel.
    [QLPreviewPanel sharedPreviewPanel].delegate = self;
    [QLPreviewPanel sharedPreviewPanel].dataSource = self;
}

- (void)endPreviewPanelControl:(QLPreviewPanel *)panel
{
    // This document loses its responsisibility on the preview panel
    // Until the next call to -beginPreviewPanelControl: it must not
    // change the panel's delegate, data source or refresh it.
    return;
}

// Quick Look panel data source

- (NSInteger)numberOfPreviewItemsInPreviewPanel:(QLPreviewPanel *)panel
{
    return 1;
}

- (id <QLPreviewItem>)previewPanel:(QLPreviewPanel *)panel previewItemAtIndex:(NSInteger)index
{
    int selectedRow = [self selectedRow];


    return [NSURL URLWithString:[[[self dataSource] tableView:self objectValueForTableColumn:fileColumn row:selectedRow] stringValue]];
}

// Quick Look panel delegate

- (BOOL)previewPanel:(QLPreviewPanel *)panel handleEvent:(NSEvent *)event
{
    // redirect all key down events to the table view

    return NO;
}

// This delegate method provides the rect on screen from which the panel will zoom.
- (NSRect)previewPanel:(QLPreviewPanel *)panel sourceFrameOnScreenForPreviewItem:(id <QLPreviewItem>)item
{

    NSRect iconRect = [self rectOfColumn:1];
    /*
     // check that the icon rect is visible on screen
     NSRect visibleRect = [self visibleRect];


     // convert icon rect to screen coordinates
     iconRect = [self convertRectToBase:iconRect];
     iconRect.origin = [[self window] convertBaseToScreen:iconRect.origin];
     */
    return iconRect;
}

// This delegate method provides a transition image between the table view and the preview panel
- (id)previewPanel:(QLPreviewPanel *)panel transitionImageForPreviewItem:(id <QLPreviewItem>)item contentRect:(NSRect *)contentRect
{
    int selectedRow = [self selectedRow];

    NSImage *fileIcon = [[NSWorkspace sharedWorkspace] iconForFile:[[[self dataSource] tableView:self objectValueForTableColumn:fileColumn row:selectedRow] stringValue]];

    return fileIcon;
}

@end

Спасибо за любую помощь.

Ответы [ 2 ]

8 голосов
/ 25 декабря 2010

Документация не самая лучшая для этого, так как это новая функция, которая была добавлена ​​в 10.6. (Ну, очевидно, есть ссылки на классы и протоколы, но по своему опыту я всегда обнаружил, что Руководства для компаньонов более полезны для понимания того, как объекты предназначены для использования в реальном сценарии).

Справочник по протоколу QLPreviewPanelController определяет 3 метода:

Справочник по протоколу QLPreviewPanelController

Панель предварительного просмотра Беглого взгляда показывает предварительные просмотры для элементов, предоставленных первым объектом в цепочке респондента, который реализует методы в этом протоколе. Вы обычно реализуете эти методы в своем оконном контроллере или делегате. Никогда не пытайтесь изменить состояние панели предварительного просмотра, если вы не управляете панелью.

- (BOOL)acceptsPreviewPanelControl:(QLPreviewPanel *)panel;

- (BOOL)beginPreviewPanelControl:(QLPreviewPanel *)panel;

- (void)endPreviewPanelControl:(QLPreviewPanel *)panel;

Я предполагаю, что ваш код должен выглядеть следующим образом:

- (BOOL)acceptsPreviewPanelControl:(QLPreviewPanel *)panel
{
    return YES;
}

Вы не должны ничего делать в этом методе, кроме возврата YES. acceptsPreviewPanelControl: отправляется каждому объекту в цепочке респондента, пока что-то не вернет ДА. Возвращая YES, этот объект фактически становится «контроллером». Последние 2 метода вызываются для объекта контроллера после того, как он возвращает YES из первого метода. Поэтому вы должны устанавливать делегат и источник данных только в методе beginPreviewPanelControl: (в этот момент вы будете считаться текущим контроллером).

- (void)beginPreviewPanelControl:(QLPreviewPanel *)panel
{

    // This document is now responsible of the preview panel
    // It is allowed to set the delegate, data source and refresh panel.

    [QLPreviewPanel sharedPreviewPanel].delegate = self;
    [QLPreviewPanel sharedPreviewPanel].dataSource = self;

    NSLog(@"We can now receive QL Events.");
}
3 голосов
/ 25 декабря 2010

Первый:

-acceptsPreviewPanelControl должен только возвращать YES, а не пытаться установить делегат и источник данных.

Затем проблема заключается в том, что вы получаете исключение, нарушающее панель:

2010-12-24 15: 32: 18.291 BackMeUp [4763: 80f] - [NSPathStore2 stringValue]: нераспознанный селектор, отправленный экземпляру 0x5ecb10

Исключительная ситуация, вероятно, вызванная этими вызовами:

[[[self dataSource] tableView:self objectValueForTableColumn:fileColumn row:selectedRow] stringValue]

Скорее всего, [[self dataSource] tableView: self objectValueForTableColumn: fileColumn строка: selectedRow] - это путь к файлу (экземпляр NSPathStore, который является подклассом NSString), поэтому он не отвечает на -stringValue

Замените:

[NSURL URLWithString:[[[self dataSource] tableView:self objectValueForTableColumn:fileColumn row:selectedRow] stringValue]]

на:

[NSURL fileURLWithPath:[[self dataSource] tableView:self objectValueForTableColumn:fileColumn row:selectedRow]]

Также удалите вызов -stringValue в transitionImageForPreviewItem.

В качестве примечания, похоже,Неоптимально загружать изображение при каждом вызове transitionImageForPreviewItem.Я предполагаю, что у вас уже есть изображение, вычисленное в другом месте (отображаемое в табличном представлении), попробуйте использовать его.

...