NSTreeControllerでFileSystemを表示しようとする場合、NSTreeNodeを使わないで直接modelのArrayをNSTreeControllerのContentにしたほうがよいみたいだ、というのが昨日の結論。それなら、さらにNSTreeControllerも使わずにOutlineViewのdatasourceでコードを書いてしまえばいいのでは、となんとなく思ったが、bindingを使ったほうがやはり何かと便利そうだ。コードの量が少なければbugも少なくなるはずだし。
というわけで、本日は昨日の状態からさらに
1,[[NSFileManager defaultManager] mountedVolumeURLsIncludingResourceValuesForKeys:nil options:NSVolumeEnumerationSkipHiddenVolumes]でマウントされたVolumesを取得する。(そうするとHide属性のVolumeを拾わないですむ)
2,volumesというNSMutableArrayをメンバにして、読み書き可能なプロバティにしてNSTreeControllerのcontentにbindingさせる
3,NSWorkspaceDidMountNotification、NSWorkspaceDidUnmountNotificationを使ってマウント時、アンマウント時の処理をしてみる
以上をやってみた。
この状態から外付けHDD「for_mac」をマウントすると、
最後尾に追加される。
コードはこうなった。
#import "Controller.h" #import "FileSystemItem.h" @implementation Controller @synthesize volumes; - (id)init { self = [super init]; if (self) { // Initialization code here. volumes=[NSMutableArray array]; } return self; } - (void)dealloc { [volumes release]; [super dealloc]; } -(void)setVolume{ NSArray* mountedVols=[[NSFileManager defaultManager] mountedVolumeURLsIncludingResourceValuesForKeys:nil options:NSVolumeEnumerationSkipHiddenVolumes]; NSMutableArray *roots=[NSMutableArray array]; if ([mountedVols count] > 0){ for (NSURL *element in mountedVols){ FileSystemItem* item,*parent; if([[element path ]isEqualToString:@"/"]){ item=[[FileSystemItem alloc] initWithPath:[element path] parent:nil]; } else{ parent=[[FileSystemItem alloc]initWithPath:[[element path] stringByDeletingLastPathComponent] parent:nil]; item=[[FileSystemItem alloc] initWithPath:[element path] parent:parent]; [parent release]; } [roots addObject:item]; [item release]; } [self setVolumes:roots]; } } -(void)awakeFromNib{ [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(didMount:) name:NSWorkspaceDidMountNotification object:nil]; [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(didUnmount:) name:NSWorkspaceDidUnmountNotification object:nil]; [self setVolume]; } -(void)didMount:(id)sender{ NSLog(@"Mount! %@",sender); NSDictionary* info=[sender userInfo]; NSURL* url=[info objectForKey:NSWorkspaceVolumeURLKey]; FileSystemItem* parent=[[FileSystemItem alloc]initWithPath:[[url path] stringByDeletingLastPathComponent] parent:nil]; FileSystemItem* item=[[FileSystemItem alloc] initWithPath:[url path] parent:parent]; [parent release]; [volumes addObject:item]; [item release]; [treeController rearrangeObjects]; } -(void)didUnmount:(id)sender{ NSLog(@"UnMount! %@",sender); NSDictionary* info=[sender userInfo]; NSURL* url=[info objectForKey:NSWorkspaceVolumeURLKey]; NSUInteger deleteNo; for (NSInteger i=0; i<[volumes count]; i++) { FileSystemItem* item=[volumes objectAtIndex:i]; if ([[item fullPath] isEqualToString:[url path]]) { deleteNo=i; } } [volumes removeObjectAtIndex:deleteNo]; [treeController rearrangeObjects]; } @endtreeControllerのbindingなどはこうなっている。
これでほぼ考えていた動作が実現できた。次はEseに組み込んでみる。これはちょっと苦労するところがあると予想している。@"/"を期待した動作、などを書いているので。
0 件のコメント:
コメントを投稿