트리의 노드를 변경 한 후 rearrangeObjects을 NSTreeController로 보내려면 적절한 방법은 무엇입니까? NSOutlineView와 NSTreeController를 Node 객체의 간단한 트리와 함께 사용하는 샘플 애플리케이션 (아래 전체 코드)이 있습니다.트리에서 노드를 변경 한 후 NSTreeController로 보낸 rearrangeObjects를 얻는 올바른 방법은 무엇입니까?
응용 프로그램의 버전 1에서 노드 이름을 편집 할 때 열 머리글을 클릭하거나 메뉴에서 "재정렬"항목을 사용할 때까지 트리가 사용되지 않습니다. 후자는 rearrangeObject를 NSTreeController에 직접 보내도록 설정됩니다.
버전 2에서 노드의 setName : 메소드에서 rearrangeObjects를 보내 보았습니다. 이것은 모델이 뷰/컨트롤러에 대한 지식을 가지고 있다는 것을 의미하기 때문에 좋은 해결책처럼 보이지 않습니다. 또한 이름 바꾸기가 끝나면 윤곽선보기가 포커스를 잃는 부작용이 있습니다 (노드를 선택하고 이름을 편집하면 선택 막대가 파란색에서 회색으로 바뀝니다) (이유는 무엇입니까?).
NSArrayController에는 setAutomaticallyRearrangesObjects: 메서드가 있지만 NSTreeController는 없습니까? 그래서 이것을 해결할 수있는 적절한 방법은 무엇입니까?
/* example.m
Compile version 1:
gcc -framework Cocoa -o Version1 example.m
Compile version 2:
gcc -framework Cocoa -o Version2 -D REARRANGE_FROM_SETNAME example.m
*/
#import <Cocoa/Cocoa.h>
NSTreeController *treeController;
NSOutlineView *outlineView;
NSScrollView *scrollView;
@interface Node : NSObject {
NSString *name;
NSArray *children;
}
@end
@implementation Node
- (id) initWithName: (NSString*) theName children: (id) theChildren
{
if (self = [super init]) {
name = [theName retain];
children = [theChildren retain];
}
return self;
}
- (void) setName: (NSString*) new
{
[name autorelease];
name = [new retain];
#ifdef REARRANGE_FROM_SETNAME
[treeController rearrangeObjects];
#endif
}
@end
NSArray *createSortDescriptors()
{
return [NSArray arrayWithObject: [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]];
}
void createTheTreeController()
{
Node *childNode1 = [[[Node alloc] initWithName:@"B" children:[NSArray array]] autorelease];
Node *childNode2 = [[[Node alloc] initWithName:@"C" children:[NSArray array]] autorelease];
Node *childNode3 = [[[Node alloc] initWithName:@"D" children:[NSArray array]] autorelease];
Node *topNode1 = [[[Node alloc] initWithName:@"A" children:[NSArray arrayWithObjects:childNode1,childNode2,childNode3,nil]] autorelease];
Node *topNode2 = [[[Node alloc] initWithName:@"E" children:[NSArray array]] autorelease];
Node *topNode3 = [[[Node alloc] initWithName:@"F" children:[NSArray array]] autorelease];
NSArray *topNodes = [NSArray arrayWithObjects:topNode1,topNode2,topNode3,nil];
treeController = [[[NSTreeController alloc] initWithContent:topNodes] autorelease];
[treeController setAvoidsEmptySelection:NO];
[treeController setChildrenKeyPath:@"children"];
[treeController setSortDescriptors:createSortDescriptors()];
}
void createTheOutlineView()
{
outlineView = [[[NSOutlineView alloc] initWithFrame:NSMakeRect(0, 0, 284, 200)] autorelease];
[outlineView bind:@"content" toObject:treeController withKeyPath:@"arrangedObjects" options:nil];
[outlineView bind:@"sortDescriptors" toObject:treeController withKeyPath:@"sortDescriptors" options:nil];
[outlineView bind:@"selectionIndexPaths" toObject:treeController withKeyPath:@"selectionIndexPaths" options:nil];
NSTableColumn *column = [[[NSTableColumn alloc] initWithIdentifier:@"NameColumn"] autorelease];
[[column headerCell] setStringValue:@"Name"];
[outlineView addTableColumn:column];
[outlineView setOutlineTableColumn:column];
[column bind:@"value" toObject:treeController withKeyPath:@"arrangedObjects.name" options:nil];
[column setWidth:250];
scrollView = [[[NSScrollView alloc] initWithFrame:NSMakeRect(0, 0, 300, 200)] autorelease];
[scrollView setDocumentView:outlineView];
[scrollView setHasVerticalScroller:YES];
}
void createTheWindow()
{
id window = [[[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 300, 200)
styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO]
autorelease];
[window cascadeTopLeftFromPoint:NSMakePoint(20,20)];
[window setTitle:@"Window"];
[window makeKeyAndOrderFront:nil];
[[window contentView] addSubview:scrollView];
}
void createTheMenuBar()
{
id menubar = [[NSMenu new] autorelease];
id appMenuItem = [[NSMenuItem new] autorelease];
[menubar addItem:appMenuItem];
[NSApp setMainMenu:menubar];
id appMenu = [[NSMenu new] autorelease];
#ifndef REARRANGE_FROM_SETNAME
id rearrangeMenuItem = [[[NSMenuItem alloc] initWithTitle:@"Rearrange"
action:@selector(rearrangeObjects) keyEquivalent:@"r"] autorelease];
[rearrangeMenuItem setTarget: treeController];
[appMenu addItem:rearrangeMenuItem];
#endif
id quitMenuItem = [[[NSMenuItem alloc] initWithTitle:@"Quit"
action:@selector(terminate:) keyEquivalent:@"q"] autorelease];
[appMenu addItem:quitMenuItem];
[appMenuItem setSubmenu:appMenu];
}
void setUpAutoReleasePoolAndApplication()
{
[NSAutoreleasePool new];
[NSApplication sharedApplication];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
}
void activateAppAndRun()
{
[NSApp activateIgnoringOtherApps:YES];
[NSApp run];
}
int main(int argc, const char * argv[])
{
setUpAutoReleasePoolAndApplication();
createTheTreeController();
createTheOutlineView();
createTheWindow();
createTheMenuBar();
activateAppAndRun();
return 0;
}