2008-01-05

辞書その3

Problem:
Some applications do about 90% of what I want.
Solution:
Develop my own applications.
Better Solution:
Patch the application myself... ← いまココ


RubyInjectは早々にあきらめ、SIMBLを使ってみます。


com.apple.Dictionary をフックするbundleを作ります。右上の検索入力欄はどうみてもNSTextFieldなので、NSTextFieldをposeAsClassでのっとります。NSTextFieldは、ふつうdelegateで変更を通知するはずなので、setDelegateをのっとって検索文字列変更時にどのインスタンスに通知するか覗いてみます。どうやら BrowserWindowController が相手のもよう。のでNSTextFieldインスタンスをもったNSWindowControllerの子クラスを作って、そのインスタンスをNSTextFieldのdelegateに設定してみます。

これで検索文字列決定時にcontrolTextDidEndEditingが呼ばれるようになりました!

#import 

@interface MyNSTextField : NSTextField
{
}
@end

@interface MyNSWindowController : NSWindowController
{
id _textField;
}
@end

@implementation MyNSTextField

+ (void)load
{
[self poseAsClass:[NSTextField class]];
NSLog(@"MyNSTextField::load");
}

- (void)setDelegate:(id)anObject
{
if ([@"BrowserWindowController" isEqualToString:[anObject className]]) {
MyNSWindowController *windowController =
[[MyNSWindowController alloc] init];
[windowController set:self];
[super setDelegate:windowController];
}
}

@end

@implementation MyNSWindowController

- (void)set:(id)textField
{
NSLog(@"MyNSWindowController set");
_textField = textField;
}

- (void)controlTextDidEndEditing:(NSNotification *)aNotification
{
NSLog(@"controlTextDidEndEditing");
NSLog([_textField stringValue]);
}

@end


こんな感じですね。setDelegateを奪い取ってる気がしますが、一応動いてます。

あとは検索文字列をオンライン辞書ででも検索して発音音声を返せば念願達成。こっから先はRubyCocoaで繋ぐつもり。