特定のドットファイルがあるフォルダーを選択するには

はじめに

コマンドラインツールには、ファイル名の先頭に”.”がついたファイルを作成する物がある。所謂ドットファイルだ。

このドットファイルは、Finder上では不可視ファイルになっていて通常は見る事は出来ない。

Cocoaでこのファイルを選択するには、通常

- [NSOpenPanel setShowsHiddenFiles:(BOOL)flag];

にYESを渡して使用する。

しかしこの方法では、全ての不可視ファイルが Open Panel に表示されてしまう。不可視ファイルは想像以上に多いので、ユーザーは混乱するだろう。

../../../_images/selecting_dot_File_Folder_1.tiff

こんな画面は誰も見たくないでしょう?

解決策として、

  1. 混乱を避ける為に不可視ファイルは表示させない
  2. 特定のドットファイルが存在するフォルダーだけを読込み可能にする

以上の2点を満たす方法を考えてみた。

開発環境

開発環境は以下の通りです

MacOSX:10.8.2
XCode:4.5.2

基本方針

NSOpnePanelのdelegateを使う。

- [NSOpenSavePanelDelegate panel:(id)sender
         didChangeToDirectoryURL:(NSURL *)url];

このdelegatメソッドは、OpenPaneで注目中のディレクトリが変更される毎に呼出される。 呼出された時に、ディレクトリを走査し、目的のドットファイルが有るか確認する。

目的のドットファイルが存在した場合だけ

- [NSOpenPanel setCanChooseDirectories:(BOOL)flag];

にYESに設定してフォルダーを読込み可能にする。

実装

OpenPanelを表示してドットファイル”.ditz-config”が存在するフォルダーを読込み可能にするコードを示す。 ここで、”.ditz-config”はditzの設定ファイル名なので、各自の目的に合わせて変更してください。

- (IBAction)openPanel:(id)sender;
{
    NSOpenPanel* theOpenPanel = [NSOpenPanel openPanel];

    [theOpenPanel setAllowsMultipleSelection:NO];
    [theOpenPanel setCanChooseFiles:NO];
    [theOpenPanel setDelegate:self];

    [theOpenPanel beginWithCompletionHandler:^(NSInteger result)
     {
         if (result == NSFileHandlingPanelOKButton)
         {
             NSURL* thePath = [[theOpenPanel URLs] objectAtIndex:0];
             NSLog(@" thePath: %@\n", thePath);
         }
     }
    ];
}

- (void)panel:(id)inSender didChangeToDirectoryURL:(NSURL *)inURL
{
    NSOpenPanel*   theOpenPanel   = inSender;
    NSFileManager* theFileManager = [NSFileManager defaultManager];
    NSString*      theFilePath    = [inURL path];

    NSArray*       theFileLists;
    BOOL           theFlag;

    theFileLists  = [theFileManager contentsOfDirectoryAtPath:theFilePath
                                                        error:nil];
    theFlag       = [theFileLists containsObject:@".ditz-config"];

    [theOpenPanel setCanChooseDirectories:theFlag];
}

実装はコレだけです。