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では入れているのでまねしました。
<?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はこんな感じです。
<?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>
プラグインのソースコードはこんな感じです。
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には以下のメソッドを追加しました。
- (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];
}