iCustom class modifications

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/apps/gorm/trunk@9897 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-Macdonald 2001-05-08 09:43:11 +00:00
parent 96d4705bbf
commit 9a45909aab
11 changed files with 1011 additions and 111 deletions

View file

@ -1,3 +1,20 @@
2001-05-08 Richard Frith-Macdonald <rfm@gnu.org>
Applied patch by Raphael Sebbe to add support for custom objects.
Went through the code and tried to make it conform to GNUstep
coding standards.
* GNUmakefile: Custom class modifications
* Gorm.h: ditto
* Gorm.m: ditto
* GormClassManager.h: ditto
* GormClassManager.m: ditto
* GormDocument.h: ditto
* GormDocument.m: ditto
* GormInspectorsManager.m: ditto
* GormObjectEditor.m: ditto
* GormPrivate.h: ditto
* GormWindowEditor.m: ditto
2001-04-24 Adam Fedor <fedor@gnu.org>
* Version: 0.0.2 snapshot

View file

@ -84,6 +84,7 @@ Gorm_OBJC_FILES = \
IBPalette.m \
GormViewKnobs.m \
GormFilesOwner.m \
GormClassEditor.m \
GormObjectEditor.m \
GormObjectInspector.m \
GormWindowEditor.m \

1
Gorm.h
View file

@ -71,6 +71,7 @@ extern NSString *IBWillBeginTestingInterfaceNotification;
extern NSString *IBDidBeginTestingInterfaceNotification;
extern NSString *IBWillEndTestingInterfaceNotification;
extern NSString *IBDidEndTestingInterfaceNotification;
extern NSString *IBClassNameChangedNotification;

130
Gorm.m
View file

@ -38,6 +38,78 @@ NSString *GormLinkPboardType = @"GormLinkPboardType";
@class InfoPanel;
@implementation GSNibItem (GormAdditions)
- initWithClassName: (NSString*)className frame: (NSRect)frame
{
self = [super init];
theClass = [className copy];
theFrame = frame;
return self;
}
- (NSString*) className
{
return theClass;
}
@end
@implementation GormObjectProxy
/*
* Perhaps this would be better to have a dummy initProxyWithCoder
* in GSNibItem class, so that we are not dependent on actual coding
* order of the ivars ?
*/
- (id) initWithCoder: (NSCoder*)aCoder
{
// do not decode super (it would try to morph into theClass ! )
[aCoder decodeValueOfObjCType: @encode(id) at: &theClass];
theFrame = [aCoder decodeRect];
//NSLog(@"Decoding proxy : %@", theClass);
RETAIN(theClass);
return self;
}
@end
@implementation GormClassProxy
- (id) initWithClassName: (NSString*)n
{
self = [super init];
if (self != nil)
{
ASSIGN(name, n);
}
return self;
}
- (void) dealloc
{
RELEASE(name);
[super dealloc];
}
- (NSString*) className
{
return name;
}
- (NSString*) inspectorClassName
{
return [self classInspectorClassName];
}
- (NSString*) connectInspectorClassName
{
return @"GormNotApplicableInspector";
}
- (NSString*) sizeInspectorClassName
{
return @"GormNotApplicableInspector";
}
@end
@implementation Gorm
- (id<IBDocuments>) activeDocument
@ -99,11 +171,17 @@ NSString *GormLinkPboardType = @"GormLinkPboardType";
- (GormClassManager*) classManager
{
if (classManager == nil)
id document = [self activeDocument];
if (document != nil) return [document classManager];
/* kept in the case one want access to the classManager without document */
else if (classManager == nil)
{
classManager = [GormClassManager new];
}
return classManager;
}
- (id) close: (id)sender
@ -134,6 +212,11 @@ NSString *GormLinkPboardType = @"GormLinkPboardType";
return connectSource;
}
- (id) createSubclass: (id)sender
{
return [(id)[self activeDocument] createSubclass: sender];
}
- (id) cut: (id)sender
{
if ([[selectionOwner selection] count] == 0
@ -257,6 +340,12 @@ NSString *GormLinkPboardType = @"GormLinkPboardType";
}
}
- (id) editClass: (id)sender
{
[self inspector: self];
return [(id)[self activeDocument] editClass: sender];
}
- (id) endTesting: (id)sender
{
if (isTesting == NO)
@ -423,7 +512,7 @@ NSString *GormLinkPboardType = @"GormLinkPboardType";
action: @selector(delete:)
keyEquivalent: @""];
[aMenu addItemWithTitle: @"Select All"
action: @selector(selectAll:)
action: @selector(selectAllItems:)
keyEquivalent: @"a"];
[aMenu addItemWithTitle: @"Set Name..."
action: @selector(setName:)
@ -434,6 +523,30 @@ NSString *GormLinkPboardType = @"GormLinkPboardType";
[mainMenu setSubmenu: aMenu forItem: menuItem];
RELEASE(aMenu);
/*
* Set up classes menu.
*/
aMenu = [NSMenu new];
[aMenu addItemWithTitle: @"Create Subclass..."
action: @selector(createSubclass:)
keyEquivalent: @""];
[aMenu addItemWithTitle: @"Load Class..."
action: @selector(loadClass:)
keyEquivalent: @""];
[aMenu addItemWithTitle: @"Edit Class..."
action: @selector(editClass:)
keyEquivalent: @""];
[aMenu addItemWithTitle: @"Instantiate"
action: @selector(instantiateClass:)
keyEquivalent: @""];
menuItem = [mainMenu addItemWithTitle: @"Classes"
action: NULL
keyEquivalent: @""];
[mainMenu setSubmenu: aMenu forItem: menuItem];
classMenu = aMenu;
RELEASE(aMenu);
/*
* Set up tools menu.
*/
@ -453,6 +566,7 @@ NSString *GormLinkPboardType = @"GormLinkPboardType";
[mainMenu setSubmenu: aMenu forItem: menuItem];
RELEASE(aMenu);
/*
* Set up Windows menu
*/
@ -597,6 +711,11 @@ NSString *GormLinkPboardType = @"GormLinkPboardType";
return inspectorsManager;
}
- (id) instantiateClass: (id)sender
{
return [(id)[self activeDocument] instantiateClass: sender];
}
- (BOOL) isConnecting
{
return isConnecting;
@ -747,7 +866,7 @@ NSString *GormLinkPboardType = @"GormLinkPboardType";
return [(id)[self activeDocument] saveAsDocument: sender];
}
- (id) selectAll: (id)sender
- (id) selectAllItems: (id)sender
{
/* FIXME */
return nil;
@ -982,6 +1101,11 @@ NSString *GormLinkPboardType = @"GormLinkPboardType";
return YES;
}
- (NSMenu*) classMenu
{
return classMenu;
}
@end
int

View file

@ -16,6 +16,18 @@
- (NSArray*) extraOutletsForObject: (NSObject*)anObject;
- (void) removeAction: (NSString*)anAction forObject: (NSObject*)anObject;
- (void) removeOutlet: (NSString*)anOutlet forObject: (NSObject*)anObject;
- (BOOL) renameClassNamed: (NSString*)oldName newName: (NSString*)name;
- (NSString*) addClassWithSuperClassName: (NSString*)name;
- (BOOL) setSuperClassNamed: (NSString*)superclass
forClassNamed: (NSString*)subclass;
- (NSString*) superClassNameForClassNamed: (NSString*)className;
- (BOOL) isSuperclass: (NSString*)superclass
linkedToClass: (NSString*)subclass;
- (BOOL) saveToFile: (NSString*)path;
- (BOOL) loadFromFile: (NSString*)path;
@end
#endif

View file

@ -4,19 +4,19 @@
*
* Author: Richard Frith-Macdonald <richard@brainstrom.co.uk>
* Date: 1999
*
*
* This file is part of GNUstep.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*
* This program 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 General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@ -24,6 +24,8 @@
#include "GormPrivate.h"
NSString *IBClassNameChangedNotification = @"IBClassNameChangedNotification";
@interface GormClassManager (Private)
- (NSMutableDictionary*) classInfoForClassName: (NSString*)className;
- (NSMutableDictionary*) classInfoForObject: (NSObject*)anObject;
@ -54,6 +56,42 @@
}
}
- (NSString*) addClassWithSuperClassName: (NSString*)name
{
if ([name isEqualToString: @"NSObject"]
|| [classInformation objectForKey: name] != nil)
{
NSMutableDictionary *classInfo;
NSMutableArray *outlets;
NSMutableArray *actions;
NSString *newClassName;
int i;
classInfo = [[NSMutableDictionary alloc] initWithCapacity: 3];
outlets = [[NSMutableArray alloc] initWithCapacity: 0];
actions = [[NSMutableArray alloc] initWithCapacity: 0];
newClassName = @"NewClass";
i = 1;
[classInfo setObject: outlets forKey: @"Outlets"];
RELEASE(outlets);
[classInfo setObject: actions forKey: @"Actions"];
RELEASE(actions);
[classInfo setObject: name forKey: @"Super"];
while([classInformation objectForKey: newClassName] != nil)
{
newClassName = [newClassName stringByAppendingString:
[NSString stringWithFormat: @"%d", i++]];
}
[classInformation setObject: classInfo forKey: newClassName];
RELEASE(classInfo);
return newClassName;
}
return @"";
}
- (void) addOutlet: (NSString*)anOutlet forObject: (id)anObject
{
NSMutableDictionary *info = [self classInfoForObject: anObject];
@ -89,6 +127,16 @@
{
className = [(GormFilesOwner*)obj className];
}
else if ([obj isKindOfClass: [GSNibItem class]] == YES)
{
// this adds support for custom objects
className = [(id)obj className];
}
else if ([obj isKindOfClass: [GormClassProxy class]] == YES)
{
// this adds support for class proxies
className = [(id)obj className];
}
else
{
className = NSStringFromClass(theClass);
@ -171,8 +219,9 @@
- (NSArray*) allClassNames
{
return [[classInformation allKeys] sortedArrayUsingSelector:
@selector(compare:)];
NSArray *array = [NSArray arrayWithObject: @"NSObject"];
return [array arrayByAddingObjectsFromArray:
[[classInformation allKeys] sortedArrayUsingSelector: @selector(compare:)]];
}
- (NSArray*) allOutletsForObject: (NSObject*)obj
@ -190,6 +239,16 @@
{
className = [(GormFilesOwner*)obj className];
}
else if ([obj isKindOfClass: [GSNibItem class]] == YES)
{
// this adds support for custom objects
className = [(id)obj className];
}
else if ([obj isKindOfClass: [GormClassProxy class]] == YES)
{
// this adds support for class proxies
className = [(id)obj className];
}
else
{
className = NSStringFromClass(theClass);
@ -305,7 +364,7 @@
}
}
}
}
}
return info;
}
@ -318,6 +377,16 @@
{
className = [(GormFilesOwner*)obj className];
}
else if ([obj isKindOfClass: [GSNibItem class]] == YES)
{
// this adds support for custom objects
className = [(id)obj className];
}
else if ([obj isKindOfClass: [GormClassProxy class]] == YES)
{
// this adds support for class proxies
className = [(id)obj className];
}
else
{
className = NSStringFromClass(theClass);
@ -343,72 +412,30 @@
return [info objectForKey: @"ExtraActions"];
}
- (NSArray*) extraOutletsForObject: (NSObject*)anObject
{
NSMutableDictionary *info = [self classInfoForObject: anObject];
return [info objectForKey: @"ExtraOutlets"];
}
- (id) init
- (id) init
{
self = [super init];
if (self != nil)
{
NSBundle *bundle = [NSBundle mainBundle];
NSString *path;
NSDictionary *dict;
NSEnumerator *enumerator;
NSString *key;
path = [bundle pathForResource: @"ClassInformation" ofType: @"plist"];
if (path == nil)
{
NSLog(@"ClassInformation.plist missing from resources");
dict = nil;
}
else
{
dict = [NSDictionary dictionaryWithContentsOfFile: path];
}
/*
* Convert property-list data into a mutable structure.
*/
classInformation = [NSMutableDictionary new];
enumerator = [dict keyEnumerator];
while ((key = [enumerator nextObject]) != nil)
{
NSDictionary *classInfo = [dict objectForKey: key];
NSMutableDictionary *newInfo;
id obj;
newInfo = [NSMutableDictionary new];
[classInformation setObject: newInfo forKey: key];
RELEASE(newInfo);
obj = [classInfo objectForKey: @"Super"];
if (obj != nil)
{
[newInfo setObject: obj forKey: @"Super"];
}
obj = [classInfo objectForKey: @"Outlets"];
if (obj != nil)
{
obj = [obj mutableCopy];
[obj sortUsingSelector: @selector(compare:)];
[newInfo setObject: obj forKey: @"Outlets"];
RELEASE(obj);
}
obj = [classInfo objectForKey: @"Actions"];
if (obj != nil)
{
obj = [obj mutableCopy];
[obj sortUsingSelector: @selector(compare:)];
[newInfo setObject: obj forKey: @"Actions"];
RELEASE(obj);
}
[self loadFromFile: path];
}
}
return self;
@ -457,7 +484,197 @@
[extraOutlets removeObject: anOutlet];
}
}
- (BOOL) renameClassNamed: (NSString*)oldName newName: (NSString*)name
{
id classInfo = [classInformation objectForKey: oldName];
if (classInfo != nil && [classInformation objectForKey: name] == nil)
{
RETAIN(classInfo);
[classInformation removeObjectForKey: oldName];
[classInformation setObject: classInfo forKey: name];
RELEASE(classInfo);
[[NSNotificationCenter defaultCenter]
postNotificationName: IBClassNameChangedNotification object: self];
return YES;
}
else return NO;
}
- (BOOL) saveToFile: (NSString*)path
{
NSMutableDictionary *ci;
NSEnumerator *enumerator;
id key;
ci = AUTORELEASE([[NSMutableDictionary alloc] initWithCapacity: 0]);
enumerator = [classInformation keyEnumerator];
while ((key = [enumerator nextObject]) != nil)
{
NSDictionary *classInfo;
NSMutableDictionary *newInfo;
id obj;
id extraObj;
classInfo = [classInformation objectForKey: key];
newInfo = [NSMutableDictionary new];
[ci setObject: newInfo forKey: key];
RELEASE(newInfo);
obj = [classInfo objectForKey: @"Super"];
if (obj != nil)
{
[newInfo setObject: obj forKey: @"Super"];
}
obj = [classInfo objectForKey: @"Outlets"];
extraObj = [classInfo objectForKey: @"ExtraOutlets"];
if (obj && extraObj) obj = [obj arrayByAddingObjectsFromArray: extraObj];
else if (extraObj) obj = extraObj;
if (obj != nil)
{
[newInfo setObject: obj forKey: @"Outlets"];
}
obj = [classInfo objectForKey: @"Actions"];
extraObj = [classInfo objectForKey: @"ExtraActions"];
if (obj && extraObj) obj = [obj arrayByAddingObjectsFromArray: extraObj];
else if (extraObj) obj = extraObj;
if (obj != nil)
{
[newInfo setObject: obj forKey: @"Actions"];
}
}
return [ci writeToFile: path atomically: YES];
}
- (BOOL) loadFromFile: (NSString*)path
{
NSDictionary *dict;
NSEnumerator *enumerator;
NSString *key;
dict = [NSDictionary dictionaryWithContentsOfFile: path];
if (dict == nil)
{
NSLog(@"Could not load classes dictionary");
return NO;
}
/*
* Convert property-list data into a mutable structure.
*/
RELEASE(classInformation);
classInformation = [NSMutableDictionary new];
enumerator = [dict keyEnumerator];
while ((key = [enumerator nextObject]) != nil)
{
NSDictionary *classInfo = [dict objectForKey: key];
NSMutableDictionary *newInfo;
id obj;
newInfo = [NSMutableDictionary new];
[classInformation setObject: newInfo forKey: key];
RELEASE(newInfo);
obj = [classInfo objectForKey: @"Super"];
if (obj != nil)
{
[newInfo setObject: obj forKey: @"Super"];
}
obj = [classInfo objectForKey: @"Outlets"];
if (obj != nil)
{
obj = [obj mutableCopy];
[obj sortUsingSelector: @selector(compare:)];
[newInfo setObject: obj forKey: @"Outlets"];
RELEASE(obj);
}
obj = [classInfo objectForKey: @"Actions"];
if (obj != nil)
{
obj = [obj mutableCopy];
[obj sortUsingSelector: @selector(compare:)];
[newInfo setObject: obj forKey: @"Actions"];
RELEASE(obj);
}
}
return YES;
}
- (BOOL) setSuperClassNamed: (NSString*)superclass
forClassNamed: (NSString*)subclass
{
NSArray *cn = [self allClassNames];
if (superclass != nil && subclass != nil && [cn containsObject: subclass]
&& ([cn containsObject: superclass]
|| [superclass isEqualToString: @"NSObject"])
&& [self isSuperclass: subclass linkedToClass: superclass] == NO)
{
NSMutableDictionary *info;
info = [classInformation objectForKey: subclass];
if (info != nil)
{
[info setObject: superclass forKey: @"Super"];
return YES;
}
else return NO;
}
else
{
return NO;
}
}
- (NSString*) superClassNameForClassNamed: (NSString*)className
{
NSMutableDictionary *info = [classInformation objectForKey: className];
NSString *superName = nil;
if (info != nil)
{
superName = [info objectForKey: @"Super"];
}
if (superName == nil)
{
superName = @"NSObject";
}
return superName;
}
- (BOOL) isSuperclass: (NSString*)superclass linkedToClass: (NSString*)subclass
{
NSString *ssclass;
//NSLog(@"isSuperClass : %@, %@", superclass, subclass);
if (superclass == nil || subclass == nil)
{
return NO;
}
if ([superclass isEqualToString: @"NSObject"])
{
return YES;
}
if ([subclass isEqualToString: @"NSObject"])
{
return NO;
}
ssclass = [self superClassNameForClassNamed: subclass];
if ([superclass isEqualToString: ssclass])
{
return YES;
}
else
{
return [self isSuperclass: superclass linkedToClass: ssclass];
}
}
@end
@ -466,17 +683,24 @@
NSArray *actions;
NSArray *outlets;
NSBrowser *browser;
NSPopUpButton *superClassPU;
NSTextField *classNameTF;
NSMatrix *connectionRadios;
NSTextField *editNameTF;
BOOL editClass;
BOOL editActions;
}
- (void) updateButtons;
- (void) renameClass: (id)sender;
- (void) changeSuperClass: (id)sender;
@end
@implementation GormClassInspector
- (int) browser: (NSBrowser*)sender numberOfRowsInColumn: (int)column
{
if (column == 0)
if (!editActions)
{
return [outlets count];
}
@ -493,7 +717,8 @@ selectCellWithString: (NSString*)title
if (col == 0)
{
}
[self updateButtons];
[editNameTF setStringValue: title];
//[self updateButtons];
return YES;
}
@ -504,7 +729,8 @@ selectCellWithString: (NSString*)title
{
NSString *name;
if (col == 0)
//if (col == 0)
if (!editActions)
{
if (row >= 0 && row < [outlets count])
{
@ -558,31 +784,84 @@ selectCellWithString: (NSString*)title
NSMatrix *matrix;
window = [[NSWindow alloc] initWithContentRect: windowRect
styleMask: NSBorderlessWindowMask
styleMask: NSBorderlessWindowMask
backing: NSBackingStoreRetained
defer: NO];
contents = [window contentView];
rect = windowRect;
// Class Name :
rect.origin.y += rect.size.height - 22;
rect.size.height = 22;
rect.origin.x = 20;
rect.size.width = 90-20;
text = [[NSTextField alloc] initWithFrame: rect];
[text setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable];
[text setEditable: NO];
[text setSelectable: NO];
[text setBordered: NO];
[text setBezeled: NO];
[text setDrawsBackground: NO];
[text setStringValue: @"Class name: "];
[contents addSubview: text];
RELEASE(text);
rect.origin.x += 95;
rect.size.width = 150;
classNameTF = text = [[NSTextField alloc] initWithFrame: rect];
[text setTarget: self];
[text setAction: @selector(renameClass:)];
[text setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable];
[contents addSubview: text];
RELEASE(text);
// Super Class :
rect.origin.x = 20;
rect.origin.y -= 24;
rect.size.height = 20;
rect.size.width = 90-20;
text = [[NSTextField alloc] initWithFrame: rect];
[text setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable];
[text setEditable: NO];
[text setSelectable: NO];
[text setBordered: NO];
[text setBezeled: NO];
[text setDrawsBackground: NO];
[text setStringValue: @"Super class: "];
[contents addSubview: text];
RELEASE(text);
rect.origin.x += 95;
rect.size.width = 150;
superClassPU = [[NSPopUpButton alloc] initWithFrame: rect pullsDown: NO];
[superClassPU setTarget: self];
[superClassPU setAction: @selector(changeSuperClass:)];
[superClassPU setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable];
[superClassPU removeAllItems];
[superClassPU addItemWithTitle: @"superclass !"];
[contents addSubview: superClassPU];
RELEASE(superClassPU);
// Outlets/Actions Radios
rect.size = windowRect.size;
rect.origin.x = 0;
rect.origin.y -= 30;
rect.size.height = 20;
cell = [[NSButtonCell alloc] init];
[cell setButtonType: NSRadioButton];
[cell setBordered: NO];
[cell setImagePosition: NSImageLeft];
rect.origin.y -= 22;
rect.size.height = 20;
[cell setImagePosition: NSImageLeft];
matrix = [[NSMatrix alloc] initWithFrame: rect
mode: NSRadioModeMatrix
prototype: cell
numberOfRows: 1
numberOfColumns: 2];
numberOfColumns: 2];
RELEASE(cell);
rect.size.width /= 2;
@ -590,27 +869,29 @@ selectCellWithString: (NSString*)title
[matrix setCellSize: rect.size];
[matrix setTarget: self];
[matrix setAutosizesCells: YES];
cell = [matrix cellAtRow: 0 column: 0];
[cell setTitle: @"Outlets"];
[cell setAction: @selector(setOutlets:)];
[cell setAction: @selector(setOutlets:)];
cell = [matrix cellAtRow: 0 column: 1];
[cell setTitle: @"Actions"];
[cell setAction: @selector(setActions:)];
[cell setAction: @selector(setActions:)];
[matrix selectCellAtRow: 0 column: 0];
[matrix setAutoresizingMask: (NSViewMinYMargin | NSViewWidthSizable)];
[contents addSubview: matrix];
connectionRadios = matrix;
RELEASE(matrix);
rect = windowRect;
rect.size.height -= 70;
rect.origin.y += 25;
// Browser
rect.size = windowRect.size;
rect.size.height -= 110;
rect.origin.y = 28;
browser = [[NSBrowser alloc] initWithFrame: rect];
[browser setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable];
[browser setMaxVisibleColumns: 2];
[browser setMaxVisibleColumns: 1];
[browser setAllowsMultipleSelection: NO];
[browser setHasHorizontalScroller: NO];
[browser setTitled: NO];
@ -622,7 +903,7 @@ selectCellWithString: (NSString*)title
rect = windowRect;
rect.size.height = 22;
rect.origin.y = 0;
text = [[NSTextField alloc] initWithFrame: rect];
editNameTF = text = [[NSTextField alloc] initWithFrame: rect];
[contents addSubview: text];
RELEASE(text);
@ -631,20 +912,88 @@ selectCellWithString: (NSString*)title
[okButton setAction: @selector(ok:)];
[okButton setTarget: self];
[okButton setTitle: @"Add"];
[okButton setEnabled: NO];
[okButton setEnabled: YES];
revertButton = [[NSButton alloc] initWithFrame: NSMakeRect(0,0,90,20)];
[revertButton setAutoresizingMask: NSViewMaxYMargin | NSViewMinXMargin];
[revertButton setAction: @selector(revert:)];
[revertButton setTarget: self];
[revertButton setTitle: @"Revert"];
[revertButton setEnabled: NO];
[revertButton setEnabled: YES];
}
return self;
}
- (void) ok: (id)sender
{
if (editClass == NO)
{
switch (editActions)
{ // Rename
case 0: // outlets
NSLog(@"rename outlet");
break;
default: // actions
NSLog(@"rename action");
break;
}
}
}
- (void) revert: (id)sender
{
GormClassManager *cm = [(id)[(id)NSApp activeDocument] classManager];
NSString *name;
if (editClass == NO)
{
NSString *cn = [object className];
switch (editActions)
{ // Add
case 0: // outlets
name = [editNameTF stringValue];
NSLog(@"add outlet : %@", name);
if (name != nil && ![name isEqualToString: @""])
{
NSArray *classOutlets;
classOutlets = [cm allOutletsForClassNamed: cn];
if ([classOutlets containsObject: name] == NO)
{
GormClassManager *m = [NSApp classManager];
[cm addOutlet: name forObject: object];
ASSIGN(outlets, [m allOutletsForClassNamed: cn]);
[browser reloadColumn: 0];
}
}
break;
default: // actions
name = [editNameTF stringValue];
NSLog(@"add action : %@", name);
if (name != nil && ![name isEqualToString: @""])
{
NSArray *classActions;
classActions = [cm allActionsForClassNamed: cn];
if ([classActions containsObject: name] == NO)
{
GormClassManager *m = [NSApp classManager];
[cm addAction: name forObject: object];
ASSIGN(actions, [m allActionsForClassNamed: cn]);
[browser reloadColumn: 0];
}
}
break;
}
}
}
- (id) setActions: (id)sender
@ -653,20 +1002,25 @@ selectCellWithString: (NSString*)title
{
editActions = YES;
[self updateButtons];
[browser reloadColumn: 0];
}
return self;
}
- (void) setObject: (id)anObject
{
if (anObject != nil && anObject != object)
//NSLog(@"class inspector : %@", anObject);
if (anObject != nil && anObject != object
&& [anObject isKindOfClass: [GormClassProxy class]])
{
ASSIGN(object, anObject);
ASSIGN(actions, [[NSApp classManager] allActionsForObject: object]);
ASSIGN(outlets, [[NSApp classManager] allOutletsForObject: object]);
NSString *cn = [anObject className];
[browser loadColumnZero];
[browser reloadColumn: 1];
ASSIGN(object, anObject);
ASSIGN(actions, [[NSApp classManager] allActionsForClassNamed: cn]);
ASSIGN(outlets, [[NSApp classManager] allOutletsForClassNamed: cn]);
//NSLog(@"%@", actions);
//[browser loadColumnZero];
[browser reloadColumn: 0];
[self updateButtons];
}
}
@ -677,18 +1031,59 @@ selectCellWithString: (NSString*)title
{
editActions = NO;
[self updateButtons];
[browser reloadColumn: 0];
}
return self;
}
- (void) changeSuperClass: (id)sender
{
GormClassManager *cm = [(id)[(id)NSApp activeDocument] classManager];
NSLog(@"change superclass");
if ([cm setSuperClassNamed: [sender titleOfSelectedItem]
forClassNamed: [object className]] == NO)
{
NSRunAlertPanel(@"Error", @"Cyclic definition", @"OK", NULL, NULL);
[self updateButtons];
}
}
- (void) renameClass: (id)sender
{
GormClassManager *cm = [(id)[(id)NSApp activeDocument] classManager];
NSString *newName;
NSLog(@"rename class : Attention, the current implementation won't "
@"rename classes for objects already instantiated !");
newName = [classNameTF stringValue];
if (newName != nil && [newName isEqualToString: @""] == NO)
{
if ([cm renameClassNamed: [object className] newName: newName])
{
GormClassProxy *cp;
cp = [[GormClassProxy alloc] initWithClassName: newName];
[self setObject: cp];
RELEASE(cp);
}
}
else
{
[classNameTF setStringValue: [object className]];
}
}
- (void) updateButtons
{
if (editClass == YES)
GormClassManager *cm = [(id)[(id)NSApp activeDocument] classManager];
/*if (editClass == YES)
{
[okButton setTitle: @"Rename Class"];
[revertButton setTitle: @"Add Class"];
}
else if (editActions == YES)
}*/
if (editActions == YES)
{
[okButton setTitle: @"Rename Action"];
[revertButton setTitle: @"Add Action"];
@ -698,6 +1093,14 @@ selectCellWithString: (NSString*)title
[okButton setTitle: @"Rename Outlet"];
[revertButton setTitle: @"Add Outlet"];
}
[classNameTF setStringValue: [object className]];
[superClassPU removeAllItems];
//[superClassPU addItemWithTitle: @"NSObject"]; // now done in ClassManager
[superClassPU addItemsWithTitles: [cm allClassNames]];
[superClassPU selectItemWithTitle:
[cm superClassNameForClassNamed: [object className]]];
}
- (BOOL) wantsButtons

View file

@ -1,6 +1,8 @@
#ifndef GORMDOCUMENT_H
#define GORMDOCUMENT_H
@class GormClassManager, GormClassEditor;
/*
* Each document has a GormFirstResponder object that is used as a placeholder
* for the first responder at any instant.
@ -21,14 +23,19 @@
@interface GormDocument : GSNibContainer <IBDocuments>
{
GormClassManager *classManager;
GormFilesOwner *filesOwner;
GormFirstResponder *firstResponder;
GormFontManager *fontManager;
GormClassEditor *classEditor; // perhaps should not be here...
NSString *documentPath;
NSMapTable *objToName;
NSWindow *window;
NSMatrix *selectionView;
NSBox *selectionBox;
NSScrollView *scrollView;
NSScrollView *classesScrollView;
id classesView;
id objectsView;
BOOL hasSetDefaults;
BOOL isActive;
@ -42,6 +49,7 @@
- (void) attachObject: (id)anObject toParent: (id)aParent;
- (void) attachObjects: (NSArray*)anArray toParent: (id)aParent;
- (void) beginArchiving;
- (GormClassManager*) classManager;
- (NSArray*) connectorsForDestination: (id)destination;
- (NSArray*) connectorsForDestination: (id)destination
ofClass: (Class)aConnectorClass;
@ -83,6 +91,12 @@
- (void) touch; /* Mark document as having been changed. */
- (NSWindow*) window;
- (BOOL) windowShouldClose: (id)sender;
// classes support
- (id) createSubclass: (id)sender;
- (id) instantiateClass: (id)sender;
- (id) editClass: (id)sender;
- (void) changeCurrentClass: (id)sender;
@end
#endif

View file

@ -23,12 +23,15 @@
*/
#include "GormPrivate.h"
#import "GormClassManager.h"
NSString *IBDidOpenDocumentNotification = @"IBDidOpenDocumentNotification";
NSString *IBWillSaveDocumentNotification = @"IBWillSaveDocumentNotification";
NSString *IBDidSaveDocumentNotification = @"IBDidSaveDocumentNotification";
NSString *IBWillCloseDocumentNotification = @"IBWillCloseDocumentNotification";
@implementation GormFirstResponder
- (NSImage*) imageForViewer
{
@ -181,7 +184,8 @@ static NSImage *classesImage = nil;
* Add top-level objects to objectsView and open their editors.
*/
if ([anObject isKindOfClass: [NSWindow class]] == YES
|| [anObject isKindOfClass: [NSMenu class]] == YES)
|| [anObject isKindOfClass: [NSMenu class]] == YES
|| [anObject isKindOfClass: [GSNibItem class]] == YES)
{
[objectsView addObject: anObject];
[[self openEditorForObject: anObject] activate];
@ -253,6 +257,42 @@ static NSImage *classesImage = nil;
}
}
- (void) changeCurrentClass: (id)sender
{
int row = [classesView selectedRow];
id classes = [classManager allClassNames];
NSLog(@"Double Action");
if (row >= 0 && row < [classes count])
{
[classEditor setSelectedClassName: [classes objectAtIndex: row]];
[self setSelectionFromEditor: (id)classEditor];
}
}
- (void) changeView: (id)sender
{
int tag = [[sender selectedCell] tag];
switch (tag)
{
case 0: // objects
[selectionBox setContentView: scrollView];
break;
case 3: // classes
[selectionBox setContentView: classesScrollView];
break;
}
}
- (GormClassManager*) classManager
{
return classManager;
}
/*
* A Gorm document is encoded in the archive as a GSNibContainer ...
* A class that the gnustep gui library knbows about and can unarchive.
@ -375,6 +415,26 @@ static NSImage *classesImage = nil;
return [aPasteboard setData: data forType: aType];
}
- (id) createSubclass: (id)sender
{
int i = [classesView selectedRow];
NSArray *classNames = [classManager allClassNames];
if (i >= 0 && i < [classNames count])
{
NSString *newClassName;
newClassName = [classManager addClassWithSuperClassName:
[classNames objectAtIndex: i]];
[classesView reloadData];
classNames = [classManager allClassNames];
i = [classNames indexOfObject: newClassName];
[classesView selectRow: i byExtendingSelection: NO];
[self editClass: self];
}
}
- (void) pasteboardChangedOwner: (NSPasteboard*)sender
{
NSDebugLog(@"Owner changed for %@", sender);
@ -385,6 +445,8 @@ static NSImage *classesImage = nil;
[[NSNotificationCenter defaultCenter] removeObserver: self];
[window setDelegate: nil];
[window performClose: self];
RELEASE(classManager);
RELEASE(classEditor);
RELEASE(hidden);
RELEASE(window);
RELEASE(filesOwner);
@ -393,6 +455,10 @@ static NSImage *classesImage = nil;
NSFreeMapTable(objToName);
RELEASE(documentPath);
RELEASE(savedEditors);
RELEASE(selectionBox);
RELEASE(scrollView);
RELEASE(classesScrollView);
[super dealloc];
}
@ -444,6 +510,13 @@ static NSImage *classesImage = nil;
return documentPath;
}
- (id) editClass: (id)sender
{
[self changeCurrentClass: sender];
return self;
}
- (void) editor: (id<IBEditors>)anEditor didCloseForObject: (id)anObject
{
NSArray *links;
@ -704,6 +777,10 @@ static NSImage *classesImage = nil;
[window setExcludedFromWindowsMenu: NO];
}
}
else if ([name isEqual: IBClassNameChangedNotification] == YES)
{
if ([aNotification object] == classManager) [classesView reloadData];
}
}
- (id) init
@ -718,8 +795,12 @@ static NSImage *classesImage = nil;
NSRect mainRect = {{20, 0}, {320, 188}};
NSImage *image;
NSButtonCell *cell;
NSTableColumn *tableColumn;
unsigned style;
classManager = [[GormClassManager alloc] init];
classEditor = [[GormClassEditor alloc] initWithDocument: self];
/*
* NB. We must retain the map values (object names) as the nameTable
* may not hold identical name objects, but merely equal strings.
@ -756,6 +837,10 @@ static NSImage *classesImage = nil;
selector: @selector(handleNotification:)
name: NSWindowDidDeminiaturizeNotification
object: window];
[nc addObserver: self
selector: @selector(handleNotification:)
name: IBClassNameChangedNotification
object: nil];
selectionView = [[NSMatrix alloc] initWithFrame: selectionRect
mode: NSRadioModeMatrix
@ -772,6 +857,7 @@ static NSImage *classesImage = nil;
if ((image = objectsImage) != nil)
{
cell = [selectionView cellAtRow: 0 column: 0];
[cell setTag: 0];
[cell setImage: image];
[cell setTitle: @"Objects"];
[cell setBordered: NO];
@ -782,6 +868,7 @@ static NSImage *classesImage = nil;
if ((image = imagesImage) != nil)
{
cell = [selectionView cellAtRow: 0 column: 1];
[cell setTag: 1];
[cell setImage: image];
[cell setTitle: @"Images"];
[cell setBordered: NO];
@ -792,6 +879,7 @@ static NSImage *classesImage = nil;
if ((image = soundsImage) != nil)
{
cell = [selectionView cellAtRow: 0 column: 2];
[cell setTag: 2];
[cell setImage: image];
[cell setTitle: @"Sounds"];
[cell setBordered: NO];
@ -802,6 +890,7 @@ static NSImage *classesImage = nil;
if ((image = classesImage) != nil)
{
cell = [selectionView cellAtRow: 0 column: 3];
[cell setTag: 3];
[cell setImage: image];
[cell setTitle: @"Classes"];
[cell setBordered: NO];
@ -812,12 +901,20 @@ static NSImage *classesImage = nil;
[[window contentView] addSubview: selectionView];
RELEASE(selectionView);
selectionBox = [[NSBox alloc] initWithFrame: scrollRect];
[selectionBox setTitlePosition: NSNoTitle];
[selectionBox setBorderType: NSNoBorder];
[selectionBox setAutoresizingMask:
NSViewHeightSizable|NSViewWidthSizable];
[[window contentView] addSubview: selectionBox];
RELEASE(selectionBox);
scrollView = [[NSScrollView alloc] initWithFrame: scrollRect];
[scrollView setHasVerticalScroller: YES];
[scrollView setHasHorizontalScroller: NO];
[scrollView setAutoresizingMask: NSViewHeightSizable|NSViewWidthSizable];
[[window contentView] addSubview: scrollView];
RELEASE(scrollView);
//[[window contentView] addSubview: scrollView];
//RELEASE(scrollView);
mainRect.origin = NSMakePoint(0,0);
objectsView = [[GormObjectEditor alloc] initWithObject: nil
@ -827,6 +924,51 @@ static NSImage *classesImage = nil;
[scrollView setDocumentView: objectsView];
RELEASE(objectsView);
classesScrollView = [[NSScrollView alloc] initWithFrame: scrollRect];
[classesScrollView setHasVerticalScroller: YES];
[classesScrollView setHasHorizontalScroller: NO];
[classesScrollView setAutoresizingMask:
NSViewHeightSizable|NSViewWidthSizable];
//[[window contentView] addSubview: scrollView];
//RELEASE(scrollView);
mainRect.origin = NSMakePoint(0,0);
classesView = [[NSTableView alloc] initWithFrame: mainRect];
[classesView setMenu: [(Gorm*)NSApp classMenu]];
[classesView setDataSource: self];
//[classesView setAction: @selector(changeCurrentClass:)];
//[classesView setTarget: self];
[classesView setAutoresizingMask: NSViewHeightSizable|NSViewWidthSizable];
[classesView setAutoresizesAllColumnsToFit: YES];
[classesScrollView setDocumentView: classesView];
RELEASE(classesView);
tableColumn = [[NSTableColumn alloc] initWithIdentifier: @"classes"];
[[tableColumn headerCell] setStringValue: @"Classes"];
[tableColumn setMinWidth: 260];
[tableColumn setResizable: YES];
[tableColumn setEditable: YES];
[classesView addTableColumn: tableColumn];
RELEASE(tableColumn);
tableColumn = [[NSTableColumn alloc] initWithIdentifier: @"outlets"];
[[tableColumn headerCell] setStringValue: @"O"];
[tableColumn setMinWidth: 25];
[tableColumn setResizable: NO];
[classesView addTableColumn: tableColumn];
RELEASE(tableColumn);
tableColumn = [[NSTableColumn alloc] initWithIdentifier: @"actions"];
[[tableColumn headerCell] setStringValue: @"A"];
[tableColumn setMinWidth: 25];
[tableColumn setResizable: NO];
[classesView addTableColumn: tableColumn];
RELEASE(tableColumn);
[classesView setFrame: mainRect];
[selectionBox setContentView: scrollView];
/*
* Set up special-case dummy objects and add them to the objects view.
*/
@ -860,6 +1002,36 @@ static NSImage *classesImage = nil;
return self;
}
- (id) instantiateClass: (id)sender
{
NSLog(@"document -> instantiateClass: ");
if ([[selectionView selectedCell] tag] == 3)
{
int i = [classesView selectedRow];
id classNames = [classManager allClassNames];
if (i >= 0 && i < [classNames count])
{
id className = [classNames objectAtIndex: i];
GSNibItem *item =
[[GormObjectProxy alloc] initWithClassName: className
frame: NSMakeRect(0,0,0,0)];
[self setName: nil forObject: item];
[self attachObject: item toParent: nil];
//[self setObject: item isVisibleAtLaunch: NO];
RELEASE(item);
[selectionView selectCellWithTag: 0];
[selectionBox setContentView: scrollView];
}
}
return nil;
}
- (BOOL) isActive
{
return isActive;
@ -915,8 +1087,9 @@ static NSImage *classesImage = nil;
* by the gui library are converted to their Gorm internal equivalents.
*/
u = AUTORELEASE([[NSUnarchiver alloc] initForReadingWithData: data]);
[u decodeClassName: @"GSNibContainer"
asClassName: @"GormDocument"];
[u decodeClassName: @"GSNibContainer" asClassName: @"GormDocument"];
[u decodeClassName: @"GSNibItem" asClassName: @"GormObjectProxy"];
c = [u decodeObject];
if (c == nil || [c isKindOfClass: [GSNibContainer class]] == NO)
{
@ -924,6 +1097,14 @@ static NSImage *classesImage = nil;
@"OK", NULL, NULL);
return nil;
}
if (![classManager loadFromFile: [[aFile stringByDeletingPathExtension]
stringByAppendingPathExtension: @"classes"]])
{
NSRunAlertPanel(NULL, @"Could not open the associated classes file.\n"
@"You won't be able to edit connections on custom classes",
@"OK", NULL, NULL);
}
[classesView reloadData];
/*
* In the newly loaded nib container, we change all the connectors
@ -934,6 +1115,9 @@ static NSImage *classesImage = nil;
[[c nameTable] setObject: firstResponder forKey: @"NSFirst"];
nt = [c nameTable];
//NSLog(@"nt : %@", nt);
//NSLog(@"--------------");
//NSLog(@"con : %@", [c connections]);
enumerator = [[c connections] objectEnumerator];
while ((con = [enumerator nextObject]) != nil)
{
@ -987,6 +1171,11 @@ static NSImage *classesImage = nil;
[objectsView addObject: obj];
[[self openEditorForObject: obj] activate];
}
else if ([obj isKindOfClass: [GSNibItem class]] == YES)
{
[objectsView addObject: obj];
//[[self openEditorForObject: obj] activate];
}
}
/*
@ -1247,7 +1436,15 @@ static NSImage *classesImage = nil;
/*
* Generate a sensible name for the object based on its class.
*/
base = NSStringFromClass([object class]);
if ([object isKindOfClass: [GSNibItem class]])
{
// use the actual class name for proxies
base = [(id)object className];
}
else
{
base = NSStringFromClass([object class]);
}
if ([base hasPrefix: @"NS"] || [base hasPrefix: @"GS"])
{
base = [base substringFromIndex: 2];
@ -1404,6 +1601,8 @@ static NSImage *classesImage = nil;
{
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
BOOL archiveResult;
NSArchiver *archiver;
NSMutableData *archiverData;
if (documentPath == nil)
{
@ -1415,7 +1614,20 @@ static NSImage *classesImage = nil;
[self beginArchiving];
archiveResult = [NSArchiver archiveRootObject: self toFile: documentPath];
//NSLog(@"nametable : %@", nameTable);
//NSLog(@"connections : %@", connections);
archiverData = [NSMutableData dataWithCapacity: 0];
archiver = [[NSArchiver alloc] initForWritingWithMutableData: archiverData];
[archiver encodeClassName: @"GormObjectProxy" intoClassName: @"GSNibItem"];
[archiver encodeRootObject: self];
archiveResult = [archiverData writeToFile: documentPath atomically: YES];
//archiveResult = [NSArchiver archiveRootObject: self toFile: documentPath];
RELEASE(archiver);
if (archiveResult)
archiveResult = [classManager saveToFile:
[[documentPath stringByDeletingPathExtension]
stringByAppendingPathExtension: @"classes"]];
[self endArchiving];
@ -1569,5 +1781,55 @@ static NSImage *classesImage = nil;
return YES;
}
//--- NSTableView dataSource ---
- (int) numberOfRowsInTableView: (NSTableView *)aTableView
{
if (aTableView == classesView)
{
return [[classManager allClassNames] count];
}
return 0;
}
- (id) tableView: (NSTableView *)aTableView
objectValueForTableColumn: (NSTableColumn *)aTableColumn
row: (int)rowIndex
{
if (aTableView == classesView)
{
id identifier = [aTableColumn identifier];
id className = @"";
id classNames = [classManager allClassNames];
if (rowIndex >= 0 && rowIndex < [classNames count])
{
className = [classNames objectAtIndex: rowIndex];
}
if ([identifier isEqualToString: @"classes"])
{
return className;
}
else if ([identifier isEqualToString: @"outlets"])
{
return [NSString stringWithFormat: @"%d",
[[classManager allOutletsForClassNamed: className] count]];
}
else if ([identifier isEqualToString: @"actions"])
{
return [NSString stringWithFormat: @"%d",
[[classManager allActionsForClassNamed: className] count]];
}
}
return @"";
}
- (void) tableView: (NSTableView *)aTableView
setObjectValue: (id)anObject
forTableColumn: (NSTableColumn *)aTableColumn
row: (int)rowIndex
{
}
@end

View file

@ -4,19 +4,19 @@
*
* Author: Richard Frith-Macdonald <richard@brainstrom.co.uk>
* Date: 1999
*
*
* This file is part of GNUstep.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*
* This program 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 General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@ -46,7 +46,7 @@
NSButton *button;
window = [[NSWindow alloc] initWithContentRect: NSMakeRect(0, 0, IVW, IVH)
styleMask: NSBorderlessWindowMask
styleMask: NSBorderlessWindowMask
backing: NSBackingStoreRetained
defer: NO];
contents = [window contentView];
@ -87,7 +87,7 @@
NSButton *button;
window = [[NSWindow alloc] initWithContentRect: NSMakeRect(0, 0, IVW, IVH)
styleMask: NSBorderlessWindowMask
styleMask: NSBorderlessWindowMask
backing: NSBackingStoreRetained
defer: NO];
contents = [window contentView];
@ -126,7 +126,7 @@
NSButton *button;
window = [[NSWindow alloc] initWithContentRect: NSMakeRect(0, 0, IVW, IVH)
styleMask: NSBorderlessWindowMask
styleMask: NSBorderlessWindowMask
backing: NSBackingStoreRetained
defer: NO];
contents = [window contentView];
@ -222,7 +222,7 @@
selectionView = [[GormISelectionView alloc] initWithFrame: selectionRect];
[selectionView setAutoresizingMask:
NSViewMinYMargin | NSViewWidthSizable];
[[panel contentView] addSubview: selectionView];
[[panel contentView] addSubview: selectionView];
RELEASE(selectionView);
/*
@ -275,7 +275,7 @@
inspectorView = [[NSView alloc] initWithFrame: inspectorRect];
[inspectorView setAutoresizingMask:
NSViewHeightSizable | NSViewWidthSizable];
[[panel contentView] addSubview: inspectorView];
[[panel contentView] addSubview: inspectorView];
RELEASE(inspectorView);
[panel setFrameUsingName: @"Inspector"];
@ -355,6 +355,11 @@
{
[panel setTitle: @"Inspector"];
}
else if ([obj isKindOfClass: [GormClassProxy class]])
{
[panel setTitle: [NSString stringWithFormat: @"Custom Class Inspector:%@",
[obj className]]];
}
else
{
[panel setTitle: [NSString stringWithFormat: @"%@ Inspector",
@ -382,7 +387,7 @@
}
if ([oldInspector isEqual: newInspector] == NO)
{
{
/*
* Return the inspector view to its original window and release the old
* inspector.
@ -391,7 +396,7 @@
[[inspector revertButton] removeFromSuperview];
[[inspector window] setContentView:
[[inspectorView subviews] lastObject]];
ASSIGN(oldInspector, newInspector);
inspector = [cache objectForKey: newInspector];
if (inspector == nil)
@ -683,7 +688,7 @@ selectCellWithString: (NSString*)title
label = [con label];
dest = [con destination];
name = [[(id<IB>)NSApp activeDocument] nameForObject: dest];
name = [label stringByAppendingFormat: @" (%@)", name];
name = [label stringByAppendingFormat: @" (%@)", name];
if ([title isEqual: name] == YES)
{
ASSIGN(currentConnector, con);
@ -761,7 +766,7 @@ selectCellWithString: (NSString*)title
label = [[connectors objectAtIndex: row] label];
dest = [[connectors objectAtIndex: row] destination];
name = [[(id<IB>)NSApp activeDocument] nameForObject: dest];
name = [label stringByAppendingFormat: @" (%@)", name];
name = [label stringByAppendingFormat: @" (%@)", name];
[aCell setStringValue: name];
[aCell setEnabled: YES];
@ -798,7 +803,7 @@ selectCellWithString: (NSString*)title
rect = NSMakeRect(0, 0, IVW, IVH);
window = [[NSWindow alloc] initWithContentRect: rect
styleMask: NSBorderlessWindowMask
styleMask: NSBorderlessWindowMask
backing: NSBackingStoreRetained
defer: NO];
contents = [window contentView];
@ -854,7 +859,12 @@ selectCellWithString: (NSString*)title
if ([currentConnector isKindOfClass: [NSNibOutletConnector class]])
{
[currentConnector setDestination: nil];
[currentConnector establishConnection];
if ([[currentConnector source] isKindOfClass:
[GormObjectProxy class]] == NO)
{
[currentConnector establishConnection];
}
}
if ([currentConnector isKindOfClass: [NSNibControlConnector class]])
{
@ -890,7 +900,18 @@ selectCellWithString: (NSString*)title
}
[connectors addObject: currentConnector];
[[(id<IB>)NSApp activeDocument] addConnector: currentConnector];
[currentConnector establishConnection];
if ([[currentConnector source]
isKindOfClass: [GormObjectProxy class]] == NO
&& [[currentConnector destination]
isKindOfClass: [GormObjectProxy class]] == NO)
{
[currentConnector establishConnection];
}
/*
* We don't want to establish connections on proxy object as their
* class are unknown to IB
*/
}
[[(id<IB>)NSApp activeDocument] touch]; /* mark as edited. */
[oldBrowser loadColumnZero];

View file

@ -15,6 +15,34 @@
extern NSString *GormLinkPboardType;
@interface GSNibItem (GormAdditions)
- initWithClassName: (NSString*)className frame: (NSRect)frame;
- (NSString*) className;
@end
@interface GormObjectProxy : GSNibItem
/*
* Use a GormObjectProxy in Gorm, but encode a GSNibItem in the archive.
* This is done so that we can provide our own decoding method
* (GSNibItem tries to morph into the actual class)
*/
@end
@interface GormClassProxy : NSObject
{
NSString *name;
int t;
}
- initWithClassName: (NSString*)n;
- (NSString*) className;
- (NSString*) inspectorClassName;
- (NSString*) connectInspectorClassName;
- (NSString*) sizeInspectorClassName;
@end
@interface NSApplication (Gorm)
- (GormClassManager*) classManager;
- (NSImage*) linkImage;
@ -33,6 +61,7 @@ extern NSString *GormLinkPboardType;
BOOL isTesting;
id testContainer;
NSMenu *mainMenu;
NSMenu *classMenu; // so we can set it for the class view
NSDictionary *menuLocations;
NSImage *linkImage;
NSImage *sourceImage;
@ -69,9 +98,25 @@ extern NSString *GormLinkPboardType;
- (id) save: (id)sender;
- (id) saveAll: (id)sender;
- (id) saveAs: (id)sender;
- (id) selectAll: (id)sender;
- (id) selectAllItems: (id)sender;
- (id) setName: (id)sender;
- (id) testInterface: (id)sender;
// added for classes support
- (id) createSubclass: (id)sender;
- (id) instantiateClass: (id)sender;
- (id) editClass: (id)sender;
- (NSMenu*) classMenu;
@end
@interface GormClassEditor : NSObject <IBSelectionOwners>
{
GormDocument *document;
NSString *selectedClassName;
}
- (GormClassEditor*) initWithDocument: (GormDocument*)doc;
+ (GormClassEditor*) classEditorForDocument: (GormDocument*)doc;
- (void) setSelectedClassName: (NSString*)cn;
@end
@interface GormObjectEditor : NSMatrix <IBEditors>

View file

@ -1138,7 +1138,7 @@ NSRectFromPoints(NSPoint p0, NSPoint p1)
[[self window] makeKeyAndOrderFront: self];
}
- (id) selectAll: (id)sender
- (id) selectAllItems: (id)sender
{
[self selectObjects: [self subviews]];
return self;