BathyScaphe

BathyScapheWiki

開発覚え書き

ここには、BathyScaphe の開発作業中に学んだことをだらだらと書き連ねていこうと思います。

目次

Help Indexer との付き合い方

Mac OS X 10.4 では、以前の Apple Help Index Tool に替わって、Help Indexer というアプリケーションでヘルプファイルの索引を作成するようになった。重要なことをいくつかメモしておく:

  • ヘルプのフォルダに「CVS」ディレクトリが混入していると索引作成中に Help Indexer が強制終了してしまう(もちろん、索引は正しく生成されない)。一時的にヘルプフォルダ内にあるすべての「CVS」フォルダを退避させてから索引を作成すること。ついでに本文と関係ないスタイルシートのディレクトリとかも外した方がいいかも。
  • Help Indexer の Preferences を索引作成前に必ずチェックすること。とくに Panther 以前と互換の索引を生成する場合、トークナイザを「Japanese」に設定しておく必要がある。どういうわけか、Help Indexer はこのトークナイザの設定をすぐに忘れてしまい、デフォルトの「English」に戻ってしまっていることが多いので注意。
  • 索引は本文の内容などを解析して作っているのだろうが、確実に特定のキーワードをヒットさせるようにしたいなら、該当するヘルプページに、以下のように meta タグを書き込んでおくべし。
<meta name="keywords" content="キーワード,複数可,…" />

Escape キーを捕まえろ!

Escape キーが押された事を検知したり、それで何かアクションを起こすには、NSResponder の cancelOperation: を捕まえれば良い。ただし、Mac OS X 10.3 以降でのみ使える。

NSEvent の KeyDown などで捕まえるのは、面倒か、もしくは、うまく捕まえられない場合もある。modifierFlags:で使える定数にも Escape キーはない。keyCode を調べるしかないらしい。

参考:http://www.cocoadev.com/index.pl?EscapeKeyEvent

スプリットビューの入れ子

BathyScaphe 1.0.1 以降では、掲示板リストを Drawer からメインのウインドウ内に押し込んで、Split View で包み込んだ。これは見た目の変化以上に、View の階層関係に大きな変化をもたらしている訳だ。

とくに、この変更によって「Split View の中に、もう一つ Split View」という、ややこしい関係が生じた。こういうことをすると、ビューのリサイズ時の挙動がなんとなく不安になるものだが、やっぱりどうもうまくいかない。当初、NSSplitView(のサブクラスである KFSplitView)で単純に入れ子を組んでみたのだが…

スプリットビューのリサイズに関して言えば、NSSplitView の思考回路はほとんど役に立たないと言っていいらしい。きちんとやろうとすると、すぐに自分で resizeSubviewsWithOldSize:adjustSubviews: をオーバーライドして、コツコツ計算する羽目になる。KFSplitView のサンプルコードは堅実明快にそれを実現する方法を示唆してくれているし、実際一つのスプリットビューでは申し分無く動作するが(1.0-v29を見よ!)が、どうも入れ子にするとどこかで何かが不具合を生じるらしく、外側のスプリットビューでは畳んだ状態がきちんと認識されなかったり、内側のスプリットビューでは分割幅がきちんと記憶できなかったりするトラブルが見られた。

そこで目を付けたのが RBSplitView だった。これは付属のサンプルアプリを見ればわかるように、入れ子のスプリットビュードンと来い!!という頼もしい奴だ。あるサブビューのサイズを保ったまま他のサブビューだけ伸縮、みたいな芸当もメソッド一発*1 でできる。とにかく色んな「スプリットビューにやらせたい動作」を豊富にサポートしてくれる。こりゃありがたい!と飛びついたのだった。

しかし、なんとまぁ、こいつは「入れ子になった RBSplitView は、常に親のスプリットビューと互い違いに分割されます」と書いてあるではないか。つまり、一番外側の RBSplitView が vertical なら、その中の RBSplitView は強制的に horizontal 。さらにその中に RBSplitView を入れると、そいつは強制的に vertical になってしまうのだ。これは普通は困らないと思うが*2、BathyScaphe の「縦分割、横分割を切り替える」機能を実現するためには、相当面倒なことになる*3

結局、最終的には「外側の Split View には RBSplitView を使い、中に押し込む Split View には KFSplitView を使う」という、やや強引というか、贅沢というか、そんな方法をとることにした。RBSplitView から見れば、中にある KFSplitView はただのサブビューであり*4、KFSplitView が縦分割になっていようが横分割になっていようが関係ないので、これでうまくいくという訳である。

「GURL」と「gurl」は違う

Launch Services は、URL から書類を開くためにそのアプリケーションに「GURL」AppleEvent を送信する。これは言うまでもなく「gurl」イベントとは別物である。うっかり

NSAppleEventManager	*aeMgr = [NSAppleEventManager sharedAppleEventManager];

[aeMgr setEventHandler : self
           andSelector : @selector(handleGetURLEvent:withReplyEvent:)
         forEventClass : 'gurl'
            andEventID : 'gurl'];

などとしてしまうと、URL から書類を開くことができず悩むことになる。ちなみに「kAEInternetSuite」定数、「kAEISGetURL」定数も「gurl」を指すもので、「GURL」ではない。「GURL」を表す定数は「kInternetEventClass」と「kAEGetURL」であり、これらは InternetConfig.h(← Carbon/Carbon.h)に書かれている。まぁ直接 'GURL' と書いてしまっていいだろう。

なお、以上は「Get URL のドンピシャな例だ!」と早合点してCocoa Scripting Guide中の例をそのまま書き写して、うまく動作しないことに悩んだ体験に基づくメモである。

念のため付け加えると、別に 'gurl' イベントが悪い訳ではなく、このイベントだって価値のある存在である(多分)。ただ、Launch Services が発射するのは 'GURL' イベントなのである。

AppleScript - Developer 向け参考リンク

Apple

Technical Q&A

Calling an AppleScript and providing parameters from an Application
http://developer.apple.com/qa/qa2001/qa1111.html
日本語訳
http://developer.apple.com/ja/qa/qa2001/qa1111.html

Technical Notes

Scripting Interface Guidelines
http://developer.apple.com/technotes/tn2002/tn2106.html
日本語訳
http://developer.apple.com/ja/technotes/tn2106.html
AEBuild*, AEPrint* and Friends
http://developer.apple.com/technotes/tn/tn2045.html
日本語訳
http://developer.apple.com/ja/technotes/tn2045.html

Others

O'REILLY macdevcenter.com

An Introduction to AppleScript on Mac OS X
http://www.macdevcenter.com/pub/a/mac/2001/12/11/applescript_intro.html
Integrating AppleScript and Cocoa
http://www.macdevcenter.com/pub/a/mac/2002/02/22/applescript.html

Sdef Editor

Mac OS X 10.3 以上で利用できる scripting definition 編集ツール。AppleScript 用語辞書(.scriptSuite/.scriptTerminology)ファイルを簡単に作成できる。http://chezjd.free.fr/index.php

素敵なソースコード達

BathyScaphe では、外部のよく出来たソースコードやフレームワークを積極的に採用していくことで、機能の強化とメンテナンスフリーを実現することを目指している。

今のところ以下のものを取り入れさせてもらっています。

RBSplitView

これは KFSplitView とはまた違い、NSSplitView のサブクラスではなく NSView のサブクラスの形を採る強力な代替スプリット・ビューである。コイツは本当に強力で、リサイズ、入れ子(ただし、入れ子にする際スプリッターの縦横が必ず互い違いでなければならない制限があるが)、スプリッターのデザイン、どれをとっても NSSplitView を遥かに凌ぐ。しかも Interface Builder の Palette が付属するので、強力なビューを簡単に配置、設定することができるのがありがたい。

KFSplitView

NSSplitView に NSWindow のような Frame AutoSave 機能や、スプリットバーのダブルクリックの通知機能などを追加し、かつオリジナルより軽快に動くという素晴らしいモノ。ドキュメントや付属のサンプルがしっかりしているし、非常に役に立つ。

Keychain Framework

キーチェーンを取り扱うためには、Carbon というか、CoreFoundation レベルの API しか用意されていないため、なかなかとっつきにくいのだが、このフレームワークはキーチェーンアクセス API の Cocoa ラッパーであり、Cocoa で Obj-C な世界からスッと呼び出して使うことができる。とてもありがたい。

追記

ありがたかったのだが、BathyScaphe 1.2 からはこのフレームワークの力を借りず、自力でキーチェーンと戦うようにしたので、このフレームワークとはお別れ。

FontWell

これは以前からずっと使ってみたいと思っていたパーツだ。カラーウェルとくれば、やっぱりフォントウェルだと思う。このサンプルコードをベースにしたものを、環境設定パネルのフォント選択に使用している。

この Wiki について

BathyScapheWiki は、FreeStyleWikiLite 0.0.11 をベースに、BathyScaphe プロジェクトが独自に機能強化・不具合修正したもので構築しています。FreeStyleWikiLite は、perl ベースのとてもシンプルな Wiki で、構成ファイルが少ないため設置が容易で処理が速いというメリットがありますが、機能的にはやや物足りない面もあります。そこで、RSS の生成機能編集前後の差分を表示する機能等が追加されました。

オリジナルの FreeStyleWikiLite 0.0.11 にこれらの機能を追加するためのパッチは、パッチトラッキングシステムに登録されていますので*5、必要な方は自由にダウンロードすることができます。

fn, include, comment の各プラグインについては、Qz氏による FSWikiLite プラグイン集を利用しています。

カテゴリ: Development


  • *1 adjustSubviewsExcepting: を使う。
  • *2 たとえば、縦二分割の中に縦二分割を押し込みたいなら、最初から縦三分割を作ればいいからね。
  • *3 例えば、Interface Builder で nib ファイルにあらかじめ仕込むのをあきらめて、コード中で initWithFrame:andSubviews: などで適切に生成するとか…でも、面倒だし難解だよね。
  • *4 正確には、RBSplitView のサブビューになれるのは RBSplitSubview だけであり、この RBSplitSubview が KFSplitView をラップしている
  • *5 パッチの状態が「closed」になっているため、そのままではパッチ一覧ページに表示されていないかもしれません。「状態:」ポップアップメニューから「any」または「closed」を選んで、「表示」ボタンを押すと、見つけることができます。

Last Modified: