/** GormClassInspector allow user to select custom classes Copyright (C) 2003 Free Software Foundation, Inc. Author: Gregory John Casamento Date: March 2003 This file is part of GNUstep. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* All Rights reserved */ #include #include "GormClassInspector.h" #include "GormPrivate.h" #include "GormClassManager.h" #include "GormDocument.h" #include NSNotificationCenter *nc = nil; // interfaces @interface GormDocument (GormClassInspectorAdditions) - (void) collapseClass: (NSString *)className; @end // the data source classes for each of the tables... @interface GormOutletDataSource : NSObject { id inspector; } - (void) setInspector: (id)ins; @end @interface GormActionDataSource : NSObject { id inspector; } - (void) setInspector: (id)ins; @end @interface GormClassesDataSource : NSObject { id inspector; } - (void) setInspector: (id)ins; @end // implementation @implementation GormDocument (GormClassInspectorAdditions) - (void) collapseClass: (NSString *)className { NSDebugLog(@"%@",className); [classesView expandItem: className]; [classesView collapseItem: className]; } @end @implementation GormOutletDataSource - (int) numberOfRowsInTableView: (NSTableView *)tv { NSArray *list = [[(Gorm *)NSApp classManager] allOutletsForClassNamed: [inspector _currentClass]]; return [list count]; } - (id) tableView: (NSTableView *)tv objectValueForTableColumn: (NSTableColumn *)tc row: (int)rowIndex { NSArray *list = [[(Gorm *)NSApp classManager] allOutletsForClassNamed: [inspector _currentClass]]; id value = nil; if([list count] > 0) { value = [list objectAtIndex: rowIndex]; } return value; } - (void) tableView: (NSTableView *)tv setObjectValue: (id)anObject forTableColumn: (NSTableColumn *)tc row: (int)rowIndex { NSArray *list = [[(Gorm *)NSApp classManager] allOutletsForClassNamed: [inspector _currentClass]]; NSString *name = [list objectAtIndex: rowIndex]; NSString *formattedOutlet = [GormDocument formatOutlet: anObject]; // RETAIN(anObject); [[(Gorm *)NSApp classManager] replaceOutlet: name withOutlet: formattedOutlet forClassNamed: [inspector _currentClass]]; } // set methods - (void) setInspector: (id)ins { ASSIGN(inspector, ins); } @end @implementation GormActionDataSource - (int) numberOfRowsInTableView: (NSTableView *)tv { NSArray *list = [[(Gorm *)NSApp classManager] allActionsForClassNamed: [inspector _currentClass]]; return [list count]; } - (id) tableView: (NSTableView *)tv objectValueForTableColumn: (NSTableColumn *)tc row: (int)rowIndex { NSArray *list = [[(Gorm *)NSApp classManager] allActionsForClassNamed: [inspector _currentClass]]; return [list objectAtIndex: rowIndex]; } - (void) tableView: (NSTableView *)tv setObjectValue: (id)anObject forTableColumn: (NSTableColumn *)tc row: (int)rowIndex { NSArray *list = [[(Gorm *)NSApp classManager] allActionsForClassNamed: [inspector _currentClass]]; NSString *name = [list objectAtIndex: rowIndex]; NSString *formattedAction = [GormDocument formatAction: anObject]; // RETAIN(anObject); [[(Gorm *)NSApp classManager] replaceAction: name withAction: formattedAction forClassNamed: [inspector _currentClass]]; } // set method - (void) setInspector: (id)ins { ASSIGN(inspector, ins); } @end @implementation GormClassesDataSource - (int) numberOfRowsInTableView: (NSTableView *)tv { NSArray *list = [[(Gorm *)NSApp classManager] allClassNames]; return [list count]; } - (id) tableView: (NSTableView *)tv objectValueForTableColumn: (NSTableColumn *)tc row: (int)rowIndex { NSArray *list = [[(Gorm *)NSApp classManager] allClassNames]; id value = nil; if([list count] > 0) { value = [list objectAtIndex: rowIndex]; } return value; } - (void) tableView: (NSTableView *)tv setObjectValue: (id)anObject forTableColumn: (NSTableColumn *)tc row: (int)rowIndex { // cannot replace any values for this data source... } // set methods - (void) setInspector: (id)ins { ASSIGN(inspector, ins); } @end @implementation GormClassInspector + (void) initialize { if (self == [GormClassInspector class]) { nc = [NSNotificationCenter defaultCenter]; } } - (id) init { self = [super init]; if (self != nil) { // initialize all member variables... actionTable = nil; addAction = nil; addOutlet = nil; classField = nil; outletTable = nil; removeAction = nil; removeOutlet = nil; tabView = nil; currentClass = nil; actionData = nil; outletData = nil; parentClassData = nil; // load the gui... if (![NSBundle loadNibNamed: @"GormClassInspector" owner: self]) { NSLog(@"Could not open gorm GormClassInspector"); return nil; } [nc addObserver: self selector: @selector(handleNotification:) name: GormDidModifyClassNotification object: nil]; } return self; } - (void) awakeFromNib { // instantiate.. actionData = [[GormActionDataSource alloc] init]; outletData = [[GormOutletDataSource alloc] init]; parentClassData = [[GormClassesDataSource alloc] init]; // initialize.. [actionData setInspector: self]; [outletData setInspector: self]; [parentClassData setInspector: self]; // use.. [actionTable setDataSource: actionData]; [outletTable setDataSource: outletData]; [parentClass setDataSource: parentClassData]; [parentClass setDoubleAction: @selector(selectClass:)]; // delegate... [actionTable setDelegate: self]; [outletTable setDelegate: self]; [parentClass setDelegate: self]; } - (void) _refreshView { id addActionCell = [addAction cell]; id removeActionCell = [removeAction cell]; id addOutletCell = [addOutlet cell]; id removeOutletCell = [removeOutlet cell]; id selectClassCell = [selectClass cell]; id searchCell = [search cell]; BOOL isCustom = [classManager isCustomClass: [self _currentClass]]; BOOL isFirstResponder = [[self _currentClass] isEqualToString: @"FirstResponder"]; NSArray *list = [classManager allClassNames]; NSString *superClass = [classManager parentOfClass: [self _currentClass]]; int index = [list indexOfObject: superClass]; [classField setStringValue: [self _currentClass]]; [outletTable reloadData]; [actionTable reloadData]; [parentClass reloadData]; // activate for actions... [addActionCell setEnabled: isCustom]; [removeActionCell setEnabled: isCustom]; // activate for outlet... [addOutletCell setEnabled: (isCustom && !isFirstResponder)]; [removeOutletCell setEnabled: (isCustom && !isFirstResponder)]; // activate select class... [selectClassCell setEnabled: (isCustom && !isFirstResponder)]; [parentClass setEnabled: (isCustom && !isFirstResponder)]; [searchCell setEnabled: (isCustom && !isFirstResponder)]; // select the parent class if(index != NSNotFound) { [parentClass selectRow: index byExtendingSelection: NO]; [parentClass scrollRowToVisible: index]; } } - (void) addAction: (id)sender { [classManager addNewActionToClassNamed: [self _currentClass]]; [nc postNotificationName: IBInspectorDidModifyObjectNotification object: classManager]; [actionTable reloadData]; } - (void) addOutlet: (id)sender { [classManager addNewOutletToClassNamed: [self _currentClass]]; [nc postNotificationName: IBInspectorDidModifyObjectNotification object: classManager]; [outletTable reloadData]; } - (void) removeAction: (id)sender { int i = [actionTable selectedRow]; NSString *className = [self _currentClass]; NSArray *list = [classManager allActionsForClassNamed: className]; BOOL removed = NO; NSString *name = nil; // check the count... if([list count] > 0) { name = [list objectAtIndex: i]; removed = [(GormDocument *)[(id )NSApp activeDocument] removeConnectionsWithLabel: name forClassNamed: currentClass isAction: YES]; } if(removed) { [classManager removeAction: name fromClassNamed: className]; [nc postNotificationName: IBInspectorDidModifyObjectNotification object: classManager]; [actionTable reloadData]; } } - (void) removeOutlet: (id)sender { int i = [outletTable selectedRow]; NSString *className = [self _currentClass]; NSArray *list = [classManager allOutletsForClassNamed: className]; BOOL removed = NO; NSString *name = nil; // check the count... if([list count] > 0) { name = [list objectAtIndex: i]; removed = [(GormDocument *)[(id )NSApp activeDocument] removeConnectionsWithLabel: name forClassNamed: currentClass isAction: NO]; } if(removed) { [classManager removeOutlet: name fromClassNamed: className]; [nc postNotificationName: IBInspectorDidModifyObjectNotification object: classManager]; [outletTable reloadData]; } } - (void) select: (id)sender { NSLog(@"select..."); } - (void) searchForClass: (id)sender { NSArray *list = [classManager allClassNames]; NSString *stringValue = [searchText stringValue]; int index = [list indexOfObject: stringValue]; NSLog(@"Search... %@",[searchText stringValue]); if(index != NSNotFound && [stringValue isEqualToString: @"FirstResponder"] == NO) { // select the parent class [parentClass selectRow: index byExtendingSelection: NO]; [parentClass scrollRowToVisible: index]; } } - (void) selectClass: (id)sender { NSArray *list = [classManager allClassNames]; int row = [parentClass selectedRow]; NSString *newParent = [list objectAtIndex: row]; NSString *name = [self _currentClass]; BOOL removed = NO; // check to see if the user wants to do this and remove the connections. removed = [(GormDocument *)[(id )NSApp activeDocument] removeConnectionsForClassNamed: name]; // if removed, move the class and notify... if(removed) { NSString *oldSuper = [classManager superClassNameForClassNamed: name]; [classManager setSuperClassNamed: newParent forClassNamed: name]; [nc postNotificationName: IBInspectorDidModifyObjectNotification object: classManager]; [(GormDocument *)[(id )NSApp activeDocument] collapseClass: oldSuper]; [(GormDocument *)[(id )NSApp activeDocument] collapseClass: name]; } } - (void) clickOnClass: (id)sender { NSLog(@"Click on class %@",sender); } - (void) setObject: (id)anObject { ASSIGN(theobject,anObject); ASSIGN(classManager, [(Gorm *)NSApp classManager]); RETAIN(theobject); [self _refreshView]; } - (NSString *) _currentClass { return [theobject className]; } - (void) handleNotification: (NSNotification *)notification { if([notification object] == classManager) { [self _refreshView]; } } // table delegate/data source methods... - (BOOL) tableView: (NSTableView *)tableView shouldEditTableColumn: (NSTableColumn *)aTableColumn row: (int)rowIndex { BOOL result = NO; if(tableView != parentClass) { NSArray *list = nil; NSString *name = nil; NSTabViewItem *tvi = [tabView selectedTabViewItem]; BOOL isAction = [[tvi identifier] isEqualToString: @"Actions"]; NSString *className = [self _currentClass]; // id classManager = [(Gorm *)NSApp classManager]; if(isAction) { list = [classManager allActionsForClassNamed: className]; name = [list objectAtIndex: rowIndex]; } else { list = [classManager allOutletsForClassNamed: className]; name = [list objectAtIndex: rowIndex]; } if([classManager isCustomClass: className]) { if (isAction) { result = [classManager isAction: name ofClass: className]; } else { result = [classManager isOutlet: name ofClass: className]; } } } return result; } - (BOOL) tableView: (NSTableView *)tv shouldSelectRow: (int)rowIndex { BOOL result = YES; if(tv == parentClass) { NSArray *list = [classManager allClassNames]; NSString *className = [list objectAtIndex: rowIndex]; NSString *name = [self _currentClass]; BOOL isFirstResponder = [className isEqualToString: @"FirstResponder"]; BOOL isCurrentClass = [className isEqualToString: name]; BOOL isSubClass = [classManager isSuperclass: name linkedToClass: className]; if(isFirstResponder || isCurrentClass || isSubClass) { NSBeep(); result = NO; } } return result; } @end