• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
NSBrowser with NSTreeController
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


  • Follow-Ups:
    • Repost: NSBrowser with NSTreeController
      • From: Hamish Allan <email@hidden>
  • Prev by Date: Re: NSTask and unicode arguments
  • Next by Date: Re: Silly question. Is iTunes Cocoa application?
  • Previous by thread: RE: NSScrollView problems when scaling an NSTextView
  • Next by thread: Repost: NSBrowser with NSTreeController
  • Index(es):
    • Date
    • Thread