更新情報
広告
PRサイト
関連サイト
< 2007/11/18 >

QuickLookプラグイン作成を断念

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

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

せっかくOSが新しくなったので、Leopardの新機能に何か対応できないかと考えてみました。QuickLookプラグインなどは割と手軽そうです。

そこでQuickLookプラグイン作成にトライしてみたのですが、見事に失敗しました。まったくうまくいかず、しかも何がいけないのかさっぱり手がかりがつかめません。もう少し情報が出てくるまで待つしかなさそうです。

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

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

デバッグもアップルの情報に従って、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"でないといけないような気もします。

動的型識別子の情報

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>
			<key>LSItemContentTypes</key>
			<array>
				<string>com.novemberkou.rmgdoc</string>
			</array>
			<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>com.novemberkou.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>
	<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>
</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];
}

ページの先頭へ戻る