QuickLookプラグイン作成を断念

印刷用表示 |テキストサイズ 小 |中 |大 |

Repeating Motif Wonderland

更新日 2011-10-02 | 作成日 2007-12-12

QuickLookプラグイン作成を断念

2007.11.18



 OSをLeopardに更新しました。新しいOSでもRepeating Motif GeneratorやRepeating Motif Saverはちゃんと動いており、まずは一安心です。

QuickLookプラグイン作成にチャレンジ

 せっかくOSが新しくなったので、Leopardの新機能に何か対応できないかと考えてみました。QuickLookプラグインなどは割と手軽そうです。
 
 そこでQuickLookプラグイン作成にトライしてみたのですが、見事に失敗しました。まったくうまくいかず、しかも何がいけないのかさっぱり手がかりがつかめません。もう少し情報が出てくるまで待つしかなさそうです。

サンプルをたよりに作ってみる

 そもそもあまり情報がないのですが、サンプルプログラムQuickLookSketchLinkIconをたよりに、これをまねしながら作ってみました。

 デバッグもアップルの情報LinkIconに従って、qlmanageを使って動かしてみました。するとコンソールに以下の様に出力されます。

[QL] Preview test for /users/<username>/Documents/test.rmgdoc. 
Content type UTI: dyn.ah62d4rv4ge81e5phqv10g

(QuickLookプラグインの登録情報が延々と続く)

[QL] Previewing /users/<username>/Documents/test.rmgdoc. 
Content type UTI: dyn.ah62d4rv4ge81e5phqv10g. Generator used: None
[QL] Thumbnailing file://localhost/users/<username>/Documents/test.rmgdoc
 (512 x 512). Content type UTI: dyn.ah62d4rv4ge81e5phqv10g. 
Generator used: None
[QL] Thumbnailing for file://localhost/users/<username>/Documents/test.rmgdoc
 done (No image created).

 Generator used: Noneとあるのが変です。本来はNoneではなく作成したプラグインの名前がここに来る筈です。プラグインが認識されていないという事でしょうか?そうなるとプラグインのソースコードがおかしいのではなくUTIの書き方に問題があるような気もします。

 "dyn.ah62d4rv4ge81e5phqv10g"も本来は"com.novemberkou.rmgdoc"でないといけないような気もします。

動的型識別子の情報LinkIcon

 Repeating Motif GeneratorのInfo.plistは太字の部分を追加しました。ちなみにLSItemContentTypesを入れるとアイコンが白紙になりますがQuickLookSketchでは入れているのでまねしました。

Info.plist(Repeating Motif Generator)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/
DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>English</string>
    <key>CFBundleDocumentTypes</key>
    <array>
        <dict>
            <b><key>LSItemContentTypes</key>
            <array>
                <string>com.novemberkou.rmgdoc</string>
            </array></b>
            <key>CFBundleTypeExtensions</key>
            <array>
                <string>rmgdoc</string>
            </array>
            <key>CFBundleTypeIconFile</key>
            <string>RMGDocIcon</string>
            <key>CFBundleTypeName</key>
            <string>Repeating Motif Generator Document</string>
            <key>CFBundleTypeRole</key>
            <string>Editor</string>
            <key>LSTypeIsPackage</key>
            <false/>
            <key>NSDocumentClass</key>
            <string>RMGDocument</string>
            <key>NSPersistentStoreTypeKey</key>
            <string>Binary</string>
        </dict>
    </array>
    <key>CFBundleExecutable</key>
    <string>${EXECUTABLE_NAME}</string>
    <key>CFBundleIconFile</key>
    <string>RepeatingMotifGenerator</string>
    <key>CFBundleIdentifier</key>
    <string><b>com.novemberkou.</b>RepeatingMotifGenerator</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>${PRODUCT_NAME}</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>Version 3.0.4</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>3.0.4</string>
    <key>NSMainNibFile</key>
    <string>MainMenu</string>
    <key>NSPrincipalClass</key>
    <string>NSApplication</string>
    <b><key>UTExportedTypeDeclarations</key>
    <array>
        <dict>
            <key>UTTypeDescription</key>
            <string>Repeating Motif Generator Document</string>
            <key>UTTypeIconFile</key>
            <string>RMGDocIcon</string>
            <key>UTTypeIdentifier</key>
            <string>com.novemberkou.rmgdoc</string>
            <key>UTTypeConformsTo</key>
            <array>
                <string>public.composite-content</string>
            </array>
            <key>UTTypeTagSpecification</key>
            <dict>
                <key>public.filename-extension</key>
                <array>
                    <string>rmgdoc</string>
                </array>
            </dict>
        </dict>
    </array></b>
</dict>
</plist>

 プラグインの方のInfo.plistはこんな感じです。

Info.plist(RMGQuickLook)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/
DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>English</string>
    <key>CFBundleDocumentTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeRole</key>
            <string>QLGenerator</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>com.novemberkou.rmgdoc</string>
            </array>
        </dict>
    </array>
    <key>CFBundleExecutable</key>
    <string>${EXECUTABLE_NAME}</string>
    <key>CFBundleIconFile</key>
    <string></string>
    <key>CFBundleIdentifier</key>
    <string>com.novemberkou.rmgquicklookgenerator</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>${PRODUCT_NAME}</string>
    <key>CFBundleShortVersionString</key>
    <string>1</string>
    <key>CFBundleVersion</key>
    <string>1.0</string>
    <key>CFPlugInDynamicRegisterFunction</key>
    <string></string>
    <key>CFPlugInDynamicRegistration</key>
    <string>NO</string>
    <key>CFPlugInFactories</key>
    <dict>
        <key>76CFDE54-ED2B-4D3C-979C-1EA049E18AE6</key>
        <string>QuickLookGeneratorPluginFactory</string>
    </dict>
    <key>CFPlugInTypes</key>
    <dict>
        <key>5E2D9680-5022-40FA-B806-43349622E5B9</key>
        <array>
            <string>76CFDE54-ED2B-4D3C-979C-1EA049E18AE6</string>
        </array>
    </dict>
    <key>CFPlugInUnloadFunction</key>
    <string></string>
    <key>QLNeedsToBeRunInMainThread</key>
    <false/>
    <key>QLPreviewHeight</key>
    <real>600</real>
    <key>QLPreviewWidth</key>
    <real>800</real>
    <key>QLSupportsConcurrentRequests</key>
    <false/>
    <key>QLThumbnailMinimumSize</key>
    <real>17</real>
    <key>UTImportedTypeDeclarations</key>
    <array>
        <dict>
            <key>UTTypeDescription</key>
            <string>Repeating Motif Generator Document</string>
            <key>UTTypeIconFile</key>
            <string>RMGDocIcon</string>
            <key>UTTypeIdentifier</key>
            <string>com.novemberkou.RepeatingMotifGenerator</string>
            <key>UTTypeConformsTo</key>
            <array>
                <string>public.composite-content</string>
            </array>
            <key>UTTypeTagSpecification</key>
            <dict>
                <key>public.filename-extension</key>
                <array>
                    <string>rmgdoc</string>
                </array>
            </dict>
        </dict>
    </array>
</dict>
</plist>

 プラグインのソースコードはこんな感じです。

GeneratePreviewForURL.m

OSStatus GeneratePreviewForURL(
    void *thisInterface,
    QLPreviewRequestRef preview,
    CFURLRef url,
    CFStringRef contentTypeUTI,
    CFDictionaryRef options)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

    // Create and read the document file
    RMGDocument* document = [[RMGDocument alloc] init];

    if(![document readFromURL:(NSURL *)url
                       ofType:(NSString *)contentTypeUTI])
    {
        [document release];
        [pool release];
        return noErr;
    }

    NSSize canvasSize = NSMakeSize(
        [document pictureWidth],
        [document pictureHeight]);

    // Preview will be drawn in a vectorized context
    CGContextRef cgContext = QLPreviewRequestCreateContext(
        preview,
        *(CGSize *)&canvasSize,
        false,
        NULL);
    if(cgContext)
    {
        NSGraphicsContext* context =
            [NSGraphicsContext
                graphicsContextWithGraphicsPort:(void *)cgContext
                                        flipped:YES];
        if(context)
            [document drawDocumentInContext:context];

        QLPreviewRequestFlushContext(preview, cgContext);

        CFRelease(cgContext);
    }

    [pool release];
    return noErr;
}

 RMGDocumentには以下のメソッドを追加しました。

RMGDocument.m

- (void)drawDocumentInContext:(NSGraphicsContext *)context
{
    NSRect theRect = NSMakeRect(0.0, 0.0, pictureWidth, pictureHeight);
    RepeatingMotifView *renderingView =
        [[RepeatingMotifView alloc] initWithFrame:theRect];

    [NSGraphicsContext saveGraphicsState];
    [NSGraphicsContext setCurrentContext:context];

    [context saveGraphicsState];

    [renderingView setRepeatingMotif:[repeatingMotifs objectAtIndex:0]];
    [renderingView displayRectIgnoringOpacity:theRect
                                    inContext:context];

    [context restoreGraphicsState];

    [NSGraphicsContext restoreGraphicsState];

    [renderingView release];
}