ページ

2009年10月30日金曜日

Safari用独自プラグインを作る(13) - ツールバーを追加する #2

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

(前回)Cocoaの日々: Safari用独自プラグインを作る(12) - ツールバーを追加する #1

Safariのツールバーへボタンを追加する。

ツールバーに関しては過去の検証を参考にした。
Cocoaの日々: ツールバー(その4)
Cocoaの日々: ツールバー(その5)


まずメソッド置換を行うクラスを用意する。コンテキストメニューの時と同じ構成にした。

SXSafariToolbarSwizzler.h

@interface SXSafariToolbarSwizzler : NSObject {
}
+ (void)setup;

@end


次に実装。


SXSafariToolbarSwizzler.m



+ (void)setup
{
if (!_shared_instance) {
_shared_instance = [[SXSafariToolbarSwizzler alloc] init];

[_shared_instance swizzleMethodForClass:objc_getClass("ToolbarController")
orginalSelector:@selector(toolbarDefaultItemIdentifiers:)
alternativeSelector:@selector(_sx_toolbarDefaultItemIdentifiers:)];

[_shared_instance swizzleMethodForClass:objc_getClass("ToolbarController")
orginalSelector:@selector(toolbarAllowedItemIdentifiers:)
alternativeSelector:@selector(_sx_toolbarAllowedItemIdentifiers:)];

[_shared_instance swizzleMethodForClass:objc_getClass("ToolbarController")
orginalSelector:@selector(toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar:)
alternativeSelector:@selector(_sx_toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar:)];
}
}


swizzleMethodForClass:originalSelector:alternativeSelector: はコンテキストメニューの時と同じ。
Cocoaの日々: Safari用独自プラグインを作る(8) - コンテキストメニューにメニュー追加


- (NSArray *)_sx_toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar
{
NSArray* ids = [self _sx_toolbarDefaultItemIdentifiers:toolbar];
NSLog(@"1:%@", ids);
return ids;
}

- (NSArray *)_sx_toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar
{
NSArray* ids = [self _sx_toolbarAllowedItemIdentifiers:toolbar];
NSLog(@"2:%@", ids);
return ids;
}

- (NSToolbarItem *)_sx_toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag
{
NSToolbarItem* item = [self _sx_toolbar:toolbar
 itemForItemIdentifier:itemIdentifier
  willBeInsertedIntoToolbar:flag];
NSLog(@"item: %@", item);
return item;
}


最初は動作を見るために代替メソッドでは単純に元のメソッドを呼び出し、内容をログ出力するだけにしてある。


実行してログ出力を(コンソール.app)で見てみよう。


まず実行直後。



toolbar:itemForItemIdentifier:willBeInsertedToolbar: だけが呼び出された。ボタンの数からして呼び出されるのは Safariのツールバーの初期化が終わった後のようだ。

試しに新規ウィンドウを開くと今度は表示アイコンの数だけ呼び出された。



次にツールバーのあたりで右クリックしてコンテキストメニューから「ツールバーをカスタマイズ...」を選ぶ。


すると最初に toolbarDefaultItemIdentifiers: が呼ばれ、続いて toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar: 、 toolbarAllowedItemIdentifiers: と続く。
"com.evernote.SafariClipperPlugin.ClipToEvernote" が Evernoteの象アイコン。ちゃっかりデフォルト構成にも入っている(コンソール上 1:( ) の箇所)。





アプリケーションを初めて起動した場合は toolbarDefaultItemIdentifiers: が呼ばれ、そこで返されるボタンが初期表示される。その後、カスタマイズが行われるとその状態が保存され、次回起動時は toolbarDefaultItemIdentifiers: は呼び出されない、とリファレンスからは読み取れた。
Mac Dev Center: NSToolbarDelegate Protocol Reference

今回の動作はそんな感じになっている。


Evernote のアイコンは前回も書いた様に、Safari起動後少し間を置いてから表示される。ここだけ見ると、プラグインがロードされたタイミングで Evernote プラグインが後からツールバーに自力でボタンを追加しているように思える。

試しに Evernoteボタンを右の方へ移してみた。そして Safariを再起動する。


元にもどっている。さすがにこのあたり(位置の復元)は難しいか。




(続く)