NSBrowser with NSTreeController
NSBrowser with NSTreeController
- Subject: NSBrowser with NSTreeController
- From: Hamish Allan <email@hidden>
- Date: Sun, 6 Nov 2005 14:04:01 +0000
Hi,
I'm currently making my first attempts at binding an NSBrowser. From
searching the archives and the web, I gather this is not a well-
trodden path.
I'm trying to make a selector for multiple files with a master-detail
interface. On the left is an NSTableView with a single column, and
add and remove buttons. On the right is an NSBrowser. Pressing "add"
should append a selected null placeholder to the table and show the
contents of the root of the filesystem in the first column of the
browser. Browsing the filesystem should cause the the selected item
in the table view to reflect the pathname, e.g., if I browse to
"Users" then "hamish" in the browser, the selected table entry would
read "/Users/hamish/".
The minimal code I've written looks like this:
@implementation MyDocument
- (id)init
{
self = [super init];
if (self)
pathnames = [[NSMutableArray alloc] init];
return self;
}
- (void)dealloc
{
[pathnames release];
[super dealloc];
}
- (NSString *)windowNibName
{
return @"MyDocument";
}
@end
@implementation Pathname
- (id)init
{
if ((self = [super init]))
{
name = [[NSString alloc] init];
root = [[PathComponent alloc] initWithPath:@"/"];
}
return self;
}
- (void)dealloc
{
[name release];
[root release];
[super dealloc];
}
@end
@implementation PathComponent
- (id)initWithPath:(NSString *)path
{
self = [super init];
if (self)
myPath = [path retain];
return self;
}
- (void)dealloc
{
[myPath release];
[mySubpaths release];
[super dealloc];
}
- (NSString *)name
{
return [myPath lastPathComponent];
}
- (NSArray *)subpaths
{
if (mySubpaths == nil)
{
mySubpaths = [[NSMutableArray alloc] init];
NSArray *contents = [[NSFileManager defaultManager]
directoryContentsAtPath:myPath];
NSEnumerator *e = [contents objectEnumerator];
NSString *s;
while ((s = [e nextObject]))
[mySubpaths addObject:[[[PathComponent alloc] initWithPath:
[NSString stringWithFormat:@"%s/%s", myPath, s]] autorelease]];
// TODO: proper handling for files rather than directories
}
NSLog(@"mySubpaths = %@", mySubpaths);
return mySubpaths;
}
- (unsigned int)countOfSubpaths
{
return [[self subpaths] count];
}
- (PathComponent *)objectInSubpathsAtIndex:(unsigned int)index
{
return [[self subpaths] objectAtIndex:index];
}
@end
My bindings are as follows (I haven't changed the name of any of the
Nib objects):
NSArrayController contentArray = pathnames [File's Owner (MyDocument)]
NSTableColumn value = arrangedObjects.name [NSArrayController
(NSArrayController)]
NSTreeController contentArray = selection.root [NSArrayController
(NSArrayController)]
NSBrowser content = arrangedObjects [NSTreeController
(NSTreeController)]
NSBrowser contentValues = arrangedObjects.name [NSTreeController
(NSTreeController)]
The NSArrayController's Object Class Name is "Pathname" (keys:
"name" and "root").
The NSTreeController's Object Class Name is "PathComponent" (key:
"name") and has a Children key path of "subpaths".
The target of the + and - buttons is the NSArrayController with
actions "add:" and "remove:" as you would expect.
I haven't even got to the point of binding the NSArrayController's
selected name to the NSTreeController's selected path because I'm
already having problems. When any item is selected in the table view,
I get the following error message:
2005-11-06 13:20:30.256 BindTest[24082] Cannot create NSArray from
object <PathComponent: 0x3a6e70> of class PathComponent
Presumably the array in question is the one which NSTreeController
would require of PathComponent to determine its children. But as far
as I can tell I have implemented all the appropriate KVC methods for
"subpaths" (no setters because it should be read-only). -
[PathComponent subpaths] is never called.
What am I doing wrong?
Also, is there a better way to do this? (at some stage I am going to
want to do more complex things such as registering for kernel
notifications so that newly-created files and folders appear in the
NSBrowser without a refresh).
Also, is there any way to get better error reporting? It would be
really nice if in addition to "Cannot create NSArray from object" we
got "PathComponent must implement -(id) objectInSubpathsAtIndex:
(unsigned int)index" or whatever.
Thanks,
Hamish
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden