BathyScaphe ネタ(その31)

「ファイル」>「Finder で表示」について考えていた。Cocoa で「Finder で表示」するには、NSWorkspace の -selectFile:inFileViewerRootedAtPath: が簡単でふさわしい。BathyScaphe でもこれを使っている。


じゃあ何を今更考えていたかというと、-selectFile:inFileViewerRootedAtPath: では一度に一つのファイルしか「Finder で表示」できないという問題だ。このために、スレッド一覧で複数の行を選択して「Finder で表示」しても、選択された行のうち、一番上の行のログファイルだけが「Finder で表示」される。本来なら、選択された全てのログファイルを「Finder で表示」したいではないか。


そこで複数のファイルをまとめて「Finder で表示」する方法を探したのだが、どうも Finder に AppleEvent を送るアプローチしか無いようだ。幸い、BathyScaphe (の中にある SGAppKit)には「Finder に AppleEvent を送ってファイル(複数可)をゴミ箱に入れる」メソッドが既にある*1ので、これをちょっとだけ変更して「Finder に AppleEvent を送ってファイルを Reveal する」メソッドをこしらえて使うことにした。実際、イベントクラスを kAECoreSuite から kAEMiscStandards に、イベントIDをkAEDelete から kAEMakeObjectsVisible に書き換えれば後は全部ゴミ捨て用のコードが流用できた。ああ、こうして既存のコードを再活用できると少し嬉しくなるね*2


最後に一つ落とし穴があったのでメモしておく。-selectFile:inFileViewerRootedAtPath: では Finder が自動的にアクティブになるが、自分で Finder に「reveal」の AppleEvent を送っても Finder は勝手にアクティブになる訳では無いことに注意。つまり reveal 後*3、Finder をアクティベートする AppleEvent も一緒に送っておかないと良い挙動が得られないのだった。


Finder(ないし任意のアプリケーション)をアクティベートする AppleEvent を送信するのには、このナイスなチュートリアルのコードを流用したよ。quit のかわりに activate させるには、イベントクラスを kCoreEventClass から kAEMiscStandards に、イベントIDを kAEQuitApplication から kAEActivate に書き換えるだけです。


正直、送信したいイベントのクラスやIDを表す定数を調べるのが一番面倒な気がしている今日この頃です。

*1:-[NSWorkspace(BSExtensions) moveFilesToTrash:]

*2:とりわけ、昔の自分によって書かれたコードだったときは!;-) まぁ今回は違うが

*3:もしくは reveal 直前?どっちがいいのかな?