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];
}
@end
treeControllerのbindingなどはこうなっている。
これでほぼ考えていた動作が実現できた。次はEseに組み込んでみる。これはちょっと苦労するところがあると予想している。@"/"を期待した動作、などを書いているので。



0 件のコメント:
コメントを投稿