Document-based アプリケーションを作る その3

Document-based アプリケーションはいろいろとそのままで機能するのであんまりいじらなくてもいいんだけど、多少はいじりたいときもでてくる。そのあたり、ちょっとずつメモしていきたいと思う。正しいかどうかはおいておいて、やってみたことをメモすることから始める。正しい方法、というか、もっといい方法が見つかればその都度書き換えていくつもり。

まずは、ファイルを開くときに Open Panel に文字コードを選択できるように Pop-up ボタンをつけたい場合。Open Panel は NSDocumentController で管理されている(?)ので、これのサブクラスを作ってそこでいじる。

Interface Builder で MainMenu.nib に NSObject を追加して、名前をつけてみた。

次に、Xcode でファイルを追加して、MyDocumentController.rb という名前の NSDocumentController のサブクラスを作る。

include OSX

class MyDocumentController < NSDocumentController

end

できたら、Interface Builder に戻り、Inspector で、上で作った My Document Controller の Class を MyDocumentController にする。

できたら、同じ nib ファイルに Custom View をそこに Pop-up ボタンを追加する。詳しい方法は、Accessory View を Interface Builder で作るを参照。

この View と Pop-up ボタンの outlet を MyDocumentController で作って結びつける。View は encodeView、Pop-up ボタンは encodeChoice としてみた。

さて、本番。NSDocumentController では、runModalOpenPanel_forTypes(panel,extensions) というメソッドで Open Panel を表示するので、これをオーバーライドして、作った Pop-up ボタンの乗った View を Accessory View として追加する。追加したら、その他の機能はそのままじゃないと困るので、super_runModalOpenPanel_forTypes(panel,extensions) として、追加した以外の機能はそのまま渡す。

def runModalOpenPanel_forTypes(panel,extensions)

panel.setAccessoryView(@encodeView)

return super_runModalOpenPanel_forTypes(panel,extensions)

end

これだけだと、encodeChoice にアクセスできないので、なんとかする。あるクラスから別のクラスの outlet というか、クラスインスタンス変数にアクセスする方法がわからないので、とりあえずグローバル変数に入れて他からアクセスできるようにしてみる。

def awakeFromNib

$encodeChoice = @encodeChoice

end

これで、MyDocument でプレインテキストファイルを開くときの処理のところでこの Pop-up ボタンの情報が得られるので、それを使って文字コードを変られるようにできる。

これとは別の方法も考えた。

MyDocumentController.rb に次のメソッドを追加する。

def fileEncoding(sender)

return @encodeChoice

end

これは何をしているかというと、このメソッドが呼び出されたときに、上の Pop-up ボタンを返している。

これを呼び出すには、MyDocumentController.sharedDocumentController で、MyDocumentController クラスにアクセスして、この fileEncoding(sender) を呼び出す。

encodeChoice = MyDocumentController.sharedDocumentController.fileEncoding(nil)

これで、encodeChoice に上でつくった Pop-up ボタンが入る。もっといい方法があるかもしれないけど、また見つかればメモをする。