1999-12-20 14:20:06 +00:00
|
|
|
/* GormClassManager.m
|
|
|
|
*
|
|
|
|
* Copyright (C) 1999 Free Software Foundation, Inc.
|
|
|
|
*
|
|
|
|
* Author: Richard Frith-Macdonald <richard@brainstrom.co.uk>
|
2002-07-14 23:54:05 +00:00
|
|
|
* Author: Gregory John Casamento <greg_casamento@yahoo.com>
|
|
|
|
* Date: 1999, 2002
|
2001-05-08 09:43:11 +00:00
|
|
|
*
|
1999-12-20 14:20:06 +00:00
|
|
|
* This file is part of GNUstep.
|
2001-05-08 09:43:11 +00:00
|
|
|
*
|
1999-12-20 14:20:06 +00:00
|
|
|
* 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.
|
2001-05-08 09:43:11 +00:00
|
|
|
*
|
1999-12-20 14:20:06 +00:00
|
|
|
* 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.
|
2001-05-08 09:43:11 +00:00
|
|
|
*
|
1999-12-20 14:20:06 +00:00
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "GormPrivate.h"
|
2001-10-03 17:38:46 +00:00
|
|
|
#include "GormCustomView.h"
|
2003-06-06 06:24:46 +00:00
|
|
|
#include "GormDocument.h"
|
2003-05-23 02:25:34 +00:00
|
|
|
#include <InterfaceBuilder/IBEditors.h>
|
2001-05-08 09:43:11 +00:00
|
|
|
|
1999-12-21 11:38:49 +00:00
|
|
|
@interface GormClassManager (Private)
|
|
|
|
- (NSMutableDictionary*) classInfoForClassName: (NSString*)className;
|
2002-10-13 06:04:05 +00:00
|
|
|
- (NSMutableDictionary*) classInfoForObject: (id)anObject;
|
1999-12-21 11:38:49 +00:00
|
|
|
@end
|
|
|
|
|
1999-12-20 14:20:06 +00:00
|
|
|
@implementation GormClassManager
|
|
|
|
|
2003-06-06 06:24:46 +00:00
|
|
|
- (void) _touch
|
|
|
|
{
|
|
|
|
id<IBDocuments> doc = [(id<IB>)NSApp activeDocument];
|
2003-06-08 04:38:59 +00:00
|
|
|
[[NSNotificationCenter defaultCenter]
|
|
|
|
postNotificationName: GormDidModifyClassNotification
|
|
|
|
object: self];
|
2003-06-06 06:24:46 +00:00
|
|
|
[doc touch];
|
|
|
|
}
|
|
|
|
|
1999-12-21 11:38:49 +00:00
|
|
|
- (void) addAction: (NSString*)anAction forObject: (id)anObject
|
|
|
|
{
|
|
|
|
NSMutableDictionary *info = [self classInfoForObject: anObject];
|
|
|
|
NSMutableArray *extraActions = [info objectForKey: @"ExtraActions"];
|
|
|
|
NSMutableArray *allActions = [self allActionsForObject: anObject];
|
|
|
|
|
2003-06-06 06:24:46 +00:00
|
|
|
[self _touch];
|
1999-12-21 11:38:49 +00:00
|
|
|
if ([extraActions containsObject: anAction] == YES)
|
|
|
|
{
|
|
|
|
return; /* Can't add action twice. */
|
|
|
|
}
|
|
|
|
if (extraActions == nil)
|
|
|
|
{
|
|
|
|
extraActions = [[NSMutableArray alloc] initWithCapacity: 1];
|
|
|
|
[info setObject: extraActions forKey: @"ExtraActions"];
|
2003-06-07 16:33:59 +00:00
|
|
|
// RELEASE(extraActions);
|
1999-12-21 11:38:49 +00:00
|
|
|
}
|
|
|
|
[extraActions addObject: anAction];
|
|
|
|
if ([allActions containsObject: anAction] == NO)
|
|
|
|
{
|
|
|
|
[[info objectForKey: @"AllActions"] addObject: anAction];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-05-08 09:43:11 +00:00
|
|
|
- (NSString*) addClassWithSuperClassName: (NSString*)name
|
|
|
|
{
|
|
|
|
if ([name isEqualToString: @"NSObject"]
|
|
|
|
|| [classInformation objectForKey: name] != nil)
|
|
|
|
{
|
|
|
|
NSMutableDictionary *classInfo;
|
|
|
|
NSMutableArray *outlets;
|
|
|
|
NSMutableArray *actions;
|
|
|
|
NSString *newClassName;
|
|
|
|
int i;
|
|
|
|
|
2003-06-06 06:24:46 +00:00
|
|
|
[self _touch];
|
2001-05-08 09:43:11 +00:00
|
|
|
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"];
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
while ([classInformation objectForKey: newClassName] != nil)
|
2001-05-08 09:43:11 +00:00
|
|
|
{
|
|
|
|
newClassName = [newClassName stringByAppendingString:
|
|
|
|
[NSString stringWithFormat: @"%d", i++]];
|
|
|
|
|
|
|
|
}
|
|
|
|
[classInformation setObject: classInfo forKey: newClassName];
|
2002-07-14 23:54:05 +00:00
|
|
|
[customClasses addObject: newClassName];
|
2001-05-08 09:43:11 +00:00
|
|
|
RELEASE(classInfo);
|
2002-07-13 19:12:15 +00:00
|
|
|
|
2001-05-08 09:43:11 +00:00
|
|
|
return newClassName;
|
|
|
|
}
|
|
|
|
return @"";
|
|
|
|
}
|
|
|
|
|
2002-07-14 23:54:05 +00:00
|
|
|
- (NSString *) addNewActionToClassNamed: (NSString *)name
|
|
|
|
{
|
|
|
|
NSDictionary *classInfo = [classInformation objectForKey: name];
|
|
|
|
NSArray *array = [classInfo objectForKey: @"Actions"];
|
|
|
|
NSArray *extra = [classInfo objectForKey: @"ExtraActions"];
|
|
|
|
NSMutableArray *combined = [NSMutableArray arrayWithArray: array];
|
|
|
|
NSString *new = @"newAction", *search = [new stringByAppendingString: @":"];
|
|
|
|
int i = 1;
|
2003-06-06 06:24:46 +00:00
|
|
|
|
2002-07-14 23:54:05 +00:00
|
|
|
[combined addObjectsFromArray: extra];
|
2003-02-13 13:32:59 +00:00
|
|
|
while ([combined containsObject: search])
|
2002-07-14 23:54:05 +00:00
|
|
|
{
|
2003-02-13 13:32:59 +00:00
|
|
|
new = [new stringByAppendingFormat: @"%d", i++];
|
2002-07-14 23:54:05 +00:00
|
|
|
search = [new stringByAppendingString: @":"];
|
|
|
|
}
|
|
|
|
|
|
|
|
[self addAction: search forClassNamed: name];
|
|
|
|
return search;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) addNewOutletToClassNamed: (NSString *)name
|
|
|
|
{
|
|
|
|
NSDictionary *classInfo = [classInformation objectForKey: name];
|
2002-07-15 00:52:39 +00:00
|
|
|
NSArray *array = [classInfo objectForKey: @"Outlets"];
|
|
|
|
NSArray *extra = [classInfo objectForKey: @"ExtraOutlets"];
|
2002-07-14 23:54:05 +00:00
|
|
|
NSMutableArray *combined = [NSMutableArray arrayWithArray: array];
|
|
|
|
NSString *new = @"newOutlet";
|
|
|
|
int i = 1;
|
|
|
|
|
|
|
|
[combined addObjectsFromArray: extra];
|
2003-02-13 13:32:59 +00:00
|
|
|
while ([combined containsObject: new])
|
2002-07-14 23:54:05 +00:00
|
|
|
{
|
2003-02-13 13:32:59 +00:00
|
|
|
new = [new stringByAppendingFormat: @"%d", i++];
|
2002-07-14 23:54:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
[self addOutlet: new forClassNamed: name];
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2001-12-19 07:13:54 +00:00
|
|
|
- (BOOL) addClassNamed: (NSString*)className
|
|
|
|
withSuperClassNamed: (NSString*)superClassName
|
|
|
|
withActions: (NSArray*)actions
|
|
|
|
withOutlets: (NSArray*)outlets
|
|
|
|
{
|
|
|
|
BOOL result = NO;
|
|
|
|
|
|
|
|
if ([superClassName isEqualToString: @"NSObject"]
|
|
|
|
|| [classInformation objectForKey: superClassName] != nil)
|
|
|
|
{
|
|
|
|
NSMutableDictionary *classInfo;
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
if (![classInformation objectForKey: className])
|
2001-12-19 07:13:54 +00:00
|
|
|
{
|
2003-06-07 05:21:16 +00:00
|
|
|
NSEnumerator *e = [actions objectEnumerator];
|
|
|
|
id action = nil;
|
|
|
|
|
2003-06-06 06:24:46 +00:00
|
|
|
[self _touch];
|
2001-12-19 07:13:54 +00:00
|
|
|
classInfo = [[NSMutableDictionary alloc] initWithCapacity: 3];
|
|
|
|
|
|
|
|
[classInfo setObject: outlets forKey: @"Outlets"];
|
|
|
|
[classInfo setObject: actions forKey: @"Actions"];
|
|
|
|
[classInfo setObject: superClassName forKey: @"Super"];
|
|
|
|
[classInformation setObject: classInfo forKey: className];
|
2002-11-12 21:44:48 +00:00
|
|
|
[customClasses addObject: className];
|
2001-12-19 07:13:54 +00:00
|
|
|
RELEASE(classInfo);
|
2003-06-07 05:21:16 +00:00
|
|
|
|
|
|
|
// copy all actions from the class imported to the first responder
|
2003-06-08 04:38:59 +00:00
|
|
|
while((action = [e nextObject]))
|
2003-06-07 05:21:16 +00:00
|
|
|
{
|
|
|
|
[self addAction: action forClassNamed: @"FirstResponder"];
|
|
|
|
}
|
|
|
|
|
2001-12-19 07:13:54 +00:00
|
|
|
result = YES;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-12-27 22:16:12 +00:00
|
|
|
NSDebugLog(@"Class already exists");
|
2001-12-19 07:13:54 +00:00
|
|
|
result = NO;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-12-21 11:38:49 +00:00
|
|
|
- (void) addOutlet: (NSString*)anOutlet forObject: (id)anObject
|
|
|
|
{
|
|
|
|
NSMutableDictionary *info = [self classInfoForObject: anObject];
|
|
|
|
NSMutableArray *extraOutlets = [info objectForKey: @"ExtraOutlets"];
|
|
|
|
NSArray *allOutlets = [self allOutletsForObject: anObject];
|
|
|
|
|
|
|
|
if ([allOutlets containsObject: anOutlet] == YES)
|
|
|
|
{
|
|
|
|
return; /* Can't add outlet with same name. */
|
|
|
|
}
|
2003-06-06 06:24:46 +00:00
|
|
|
[self _touch];
|
1999-12-21 11:38:49 +00:00
|
|
|
if (extraOutlets == nil)
|
|
|
|
{
|
|
|
|
extraOutlets = [[NSMutableArray alloc] initWithCapacity: 1];
|
|
|
|
[info setObject: extraOutlets forKey: @"ExtraOutlets"];
|
2003-06-07 16:33:59 +00:00
|
|
|
// RELEASE(extraOutlets);
|
1999-12-21 11:38:49 +00:00
|
|
|
}
|
|
|
|
[extraOutlets addObject: anOutlet];
|
|
|
|
[[info objectForKey: @"AllOutlets"] addObject: anOutlet];
|
|
|
|
}
|
|
|
|
|
2002-07-12 05:46:29 +00:00
|
|
|
- (void) addAction: (NSString *)anAction forClassNamed: (NSString *)className
|
2002-07-11 05:50:04 +00:00
|
|
|
{
|
2002-07-12 05:46:29 +00:00
|
|
|
NSMutableDictionary *info = [classInformation objectForKey: className];
|
|
|
|
NSMutableArray *extraActions = [info objectForKey: @"ExtraActions"];
|
|
|
|
NSArray *allActions = [self allActionsForClassNamed: className];
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
if ([allActions containsObject: anAction])
|
2002-07-12 05:46:29 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2003-06-06 06:24:46 +00:00
|
|
|
[self _touch];
|
2003-02-13 13:32:59 +00:00
|
|
|
if (extraActions == nil)
|
2002-07-12 05:46:29 +00:00
|
|
|
{
|
|
|
|
extraActions = [[NSMutableArray alloc] initWithCapacity: 1];
|
|
|
|
[info setObject: extraActions forKey: @"ExtraActions"];
|
2003-06-07 16:33:59 +00:00
|
|
|
// RELEASE(extraActions);
|
2002-07-12 05:46:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
[extraActions addObject: anAction];
|
|
|
|
[[info objectForKey: @"AllActions"] insertObject: anAction atIndex: 0];
|
2003-05-25 19:08:36 +00:00
|
|
|
if(![className isEqualToString: @"FirstResponder"])
|
|
|
|
{
|
|
|
|
[self addAction: anAction forClassNamed: @"FirstResponder"];
|
|
|
|
}
|
2002-07-11 05:50:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) addOutlet: (NSString *)anOutlet forClassNamed: (NSString *)className
|
|
|
|
{
|
2002-07-12 05:46:29 +00:00
|
|
|
NSMutableDictionary *info = [classInformation objectForKey: className];
|
|
|
|
NSMutableArray *extraOutlets = [info objectForKey: @"ExtraOutlets"];
|
|
|
|
NSArray *allOutlets = [self allOutletsForClassNamed: className];
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
if ([allOutlets containsObject: anOutlet])
|
2002-07-12 05:46:29 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2003-06-06 06:24:46 +00:00
|
|
|
|
|
|
|
[self _touch];
|
2003-02-13 13:32:59 +00:00
|
|
|
if (extraOutlets == nil)
|
2002-07-12 05:46:29 +00:00
|
|
|
{
|
|
|
|
extraOutlets = [[NSMutableArray alloc] initWithCapacity: 1];
|
|
|
|
[info setObject: extraOutlets forKey: @"ExtraOutlets"];
|
2003-06-07 16:33:59 +00:00
|
|
|
// RELEASE(extraOutlets);
|
2002-07-12 05:46:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
[extraOutlets addObject: anOutlet];
|
|
|
|
[[info objectForKey: @"AllOutlets"] insertObject: anOutlet atIndex: 0];
|
|
|
|
}
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
- (void) replaceAction: (NSString *)oldAction
|
|
|
|
withAction: (NSString *)newAction
|
|
|
|
forClassNamed: className
|
2002-07-12 05:46:29 +00:00
|
|
|
{
|
|
|
|
NSMutableDictionary *info = [classInformation objectForKey: className];
|
|
|
|
NSMutableArray *extraActions = [info objectForKey: @"ExtraActions"];
|
2002-07-14 23:54:05 +00:00
|
|
|
NSMutableArray *actions = [info objectForKey: @"Actions"];
|
2002-07-21 04:04:18 +00:00
|
|
|
NSMutableArray *allActions = [info objectForKey: @"AllActions"];
|
2002-07-12 05:46:29 +00:00
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
if ([allActions containsObject: newAction]
|
|
|
|
|| [extraActions containsObject: newAction])
|
2002-07-22 15:24:37 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
if ([extraActions containsObject: oldAction])
|
2002-07-12 05:46:29 +00:00
|
|
|
{
|
|
|
|
int all_index = [allActions indexOfObject: oldAction];
|
2002-07-14 23:54:05 +00:00
|
|
|
int extra_index = [extraActions indexOfObject: oldAction];
|
2002-07-12 05:46:29 +00:00
|
|
|
|
2003-06-06 06:24:46 +00:00
|
|
|
[self _touch];
|
2002-07-12 05:46:29 +00:00
|
|
|
[extraActions replaceObjectAtIndex: extra_index withObject: newAction];
|
2002-07-21 04:04:18 +00:00
|
|
|
[allActions replaceObjectAtIndex: all_index withObject: newAction];
|
2002-07-12 05:46:29 +00:00
|
|
|
}
|
2003-02-13 13:32:59 +00:00
|
|
|
else if ([actions containsObject: oldAction])
|
2002-07-14 23:54:05 +00:00
|
|
|
{
|
|
|
|
int all_index = [allActions indexOfObject: oldAction];
|
|
|
|
int actions_index = [actions indexOfObject: oldAction];
|
|
|
|
|
2003-06-06 06:24:46 +00:00
|
|
|
[self _touch];
|
2002-07-14 23:54:05 +00:00
|
|
|
[actions replaceObjectAtIndex: actions_index withObject: newAction];
|
2002-07-21 04:04:18 +00:00
|
|
|
[allActions replaceObjectAtIndex: all_index withObject: newAction];
|
2002-07-14 23:54:05 +00:00
|
|
|
}
|
2003-05-25 19:08:36 +00:00
|
|
|
if(![className isEqualToString: @"FirstResponder"])
|
|
|
|
{
|
|
|
|
[self replaceAction: oldAction withAction: newAction forClassNamed: @"FirstResponder"];
|
|
|
|
}
|
2002-07-12 05:46:29 +00:00
|
|
|
}
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
- (void) replaceOutlet: (NSString *)oldOutlet
|
|
|
|
withOutlet: (NSString *)newOutlet
|
|
|
|
forClassNamed: className
|
2002-07-12 05:46:29 +00:00
|
|
|
{
|
|
|
|
NSMutableDictionary *info = [classInformation objectForKey: className];
|
|
|
|
NSMutableArray *extraOutlets = [info objectForKey: @"ExtraOutlets"];
|
2002-07-14 23:54:05 +00:00
|
|
|
NSMutableArray *outlets = [info objectForKey: @"Outlets"];
|
2002-07-21 04:04:18 +00:00
|
|
|
NSMutableArray *allOutlets = [info objectForKey: @"AllOutlets"];
|
2002-07-12 05:46:29 +00:00
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
if ([allOutlets containsObject: newOutlet]
|
|
|
|
|| [extraOutlets containsObject: newOutlet])
|
2002-07-22 15:24:37 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
if ([extraOutlets containsObject: oldOutlet])
|
2002-07-12 05:46:29 +00:00
|
|
|
{
|
|
|
|
int all_index = [allOutlets indexOfObject: oldOutlet];
|
2002-07-21 04:04:18 +00:00
|
|
|
int extra_index = [extraOutlets indexOfObject: oldOutlet];
|
2002-07-12 05:46:29 +00:00
|
|
|
|
2003-06-06 06:24:46 +00:00
|
|
|
[self _touch];
|
2002-07-12 05:46:29 +00:00
|
|
|
[extraOutlets replaceObjectAtIndex: extra_index withObject: newOutlet];
|
2002-07-21 04:04:18 +00:00
|
|
|
[allOutlets replaceObjectAtIndex: all_index withObject: newOutlet];
|
2002-07-12 05:46:29 +00:00
|
|
|
}
|
2003-02-13 13:32:59 +00:00
|
|
|
else if ([outlets containsObject: oldOutlet])
|
2002-07-14 23:54:05 +00:00
|
|
|
{
|
|
|
|
int all_index = [allOutlets indexOfObject: oldOutlet];
|
|
|
|
int outlets_index = [outlets indexOfObject: oldOutlet];
|
|
|
|
|
2003-06-06 06:24:46 +00:00
|
|
|
[self _touch];
|
2002-07-14 23:54:05 +00:00
|
|
|
[outlets replaceObjectAtIndex: outlets_index withObject: newOutlet];
|
2002-07-21 04:04:18 +00:00
|
|
|
[allOutlets replaceObjectAtIndex: all_index withObject: newOutlet];
|
2002-07-14 23:54:05 +00:00
|
|
|
}
|
2002-07-11 05:50:04 +00:00
|
|
|
}
|
|
|
|
|
2002-10-13 06:04:05 +00:00
|
|
|
- (NSArray*) allActionsForObject: (id)obj
|
1999-12-20 14:20:06 +00:00
|
|
|
{
|
|
|
|
NSString *className;
|
|
|
|
NSArray *actions;
|
2002-10-13 06:04:05 +00:00
|
|
|
Class theClass = [obj class];
|
|
|
|
NSString *customClassName = [self customClassForObject: obj];
|
2003-01-09 03:39:27 +00:00
|
|
|
|
|
|
|
NSDebugLog(@"** ACTIONS");
|
2003-01-08 05:54:20 +00:00
|
|
|
NSDebugLog(@"Object: %@",obj);
|
|
|
|
NSDebugLog(@"Custom class: %@",customClassName);
|
2003-02-13 13:32:59 +00:00
|
|
|
if (customClassName != nil)
|
2002-10-13 06:04:05 +00:00
|
|
|
{
|
|
|
|
// if the object has been mapped to a custom class, then
|
|
|
|
// get the information for it.
|
|
|
|
className = customClassName;
|
|
|
|
}
|
|
|
|
else if (theClass == [GormFirstResponder class])
|
1999-12-20 15:21:26 +00:00
|
|
|
{
|
2002-01-29 22:41:02 +00:00
|
|
|
className = @"FirstResponder";
|
1999-12-20 15:21:26 +00:00
|
|
|
}
|
2002-01-29 22:41:02 +00:00
|
|
|
else if (theClass == [GormFilesOwner class])
|
1999-12-20 15:21:26 +00:00
|
|
|
{
|
|
|
|
className = [(GormFilesOwner*)obj className];
|
|
|
|
}
|
2001-05-08 09:43:11 +00:00
|
|
|
else if ([obj isKindOfClass: [GSNibItem class]] == YES)
|
|
|
|
{
|
|
|
|
// this adds support for custom objects
|
2002-10-13 06:04:05 +00:00
|
|
|
className = [obj className];
|
2001-05-08 09:43:11 +00:00
|
|
|
}
|
|
|
|
else if ([obj isKindOfClass: [GormClassProxy class]] == YES)
|
|
|
|
{
|
|
|
|
// this adds support for class proxies
|
2002-10-13 06:04:05 +00:00
|
|
|
className = [obj className];
|
2001-05-08 09:43:11 +00:00
|
|
|
}
|
2001-10-03 17:38:46 +00:00
|
|
|
else if ([obj isKindOfClass: [GormCustomView class]] == YES)
|
|
|
|
{
|
|
|
|
// this adds support for custom views
|
2002-10-13 06:04:05 +00:00
|
|
|
className = [obj className];
|
2001-10-03 17:38:46 +00:00
|
|
|
}
|
1999-12-20 15:21:26 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
className = NSStringFromClass(theClass);
|
|
|
|
}
|
1999-12-20 14:20:06 +00:00
|
|
|
if (className == nil)
|
|
|
|
{
|
2002-09-10 03:00:12 +00:00
|
|
|
NSLog(@"attempt to get actions for non-existent class (%@)",
|
|
|
|
[obj class]);
|
1999-12-20 14:20:06 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
actions = [self allActionsForClassNamed: className];
|
|
|
|
while (actions == nil && (theClass = class_get_super_class(theClass)) != nil
|
|
|
|
&& theClass != [NSObject class])
|
|
|
|
{
|
|
|
|
className = NSStringFromClass(theClass);
|
|
|
|
actions = [self allActionsForClassNamed: className];
|
|
|
|
}
|
2003-01-08 05:54:20 +00:00
|
|
|
|
|
|
|
NSDebugLog(@"class=%@ actions=%@",className,actions);
|
1999-12-20 14:20:06 +00:00
|
|
|
return actions;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray*) allActionsForClassNamed: (NSString*)className
|
|
|
|
{
|
|
|
|
NSMutableDictionary *info = [classInformation objectForKey: className];
|
|
|
|
|
|
|
|
if (info != nil)
|
|
|
|
{
|
|
|
|
NSMutableArray *allActions = [info objectForKey: @"AllActions"];
|
|
|
|
|
|
|
|
if (allActions == nil)
|
|
|
|
{
|
|
|
|
NSString *superName = [info objectForKey: @"Super"];
|
|
|
|
NSArray *actions = [info objectForKey: @"Actions"];
|
|
|
|
NSArray *superActions;
|
|
|
|
|
|
|
|
if (superName == nil)
|
|
|
|
{
|
|
|
|
superActions = nil;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
superActions = [self allActionsForClassNamed: superName];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (superActions == nil)
|
|
|
|
{
|
|
|
|
if (actions == nil)
|
|
|
|
{
|
|
|
|
allActions = [NSMutableArray new];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
allActions = [actions mutableCopy];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
allActions = [superActions mutableCopy];
|
|
|
|
if (actions != nil)
|
|
|
|
{
|
|
|
|
NSEnumerator *enumerator = [actions objectEnumerator];
|
|
|
|
NSString *actionName;
|
|
|
|
|
|
|
|
while ((actionName = [enumerator nextObject]) != nil)
|
|
|
|
{
|
|
|
|
if ([allActions containsObject: actionName] == NO)
|
|
|
|
{
|
|
|
|
[allActions addObject: actionName];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[allActions sortUsingSelector: @selector(compare:)];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[info setObject: allActions forKey: @"AllActions"];
|
|
|
|
RELEASE(allActions);
|
|
|
|
}
|
|
|
|
return AUTORELEASE([allActions copy]);
|
|
|
|
}
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
1999-12-21 08:13:35 +00:00
|
|
|
- (NSArray*) allClassNames
|
|
|
|
{
|
2001-05-08 09:43:11 +00:00
|
|
|
NSArray *array = [NSArray arrayWithObject: @"NSObject"];
|
|
|
|
return [array arrayByAddingObjectsFromArray:
|
|
|
|
[[classInformation allKeys] sortedArrayUsingSelector: @selector(compare:)]];
|
1999-12-21 08:13:35 +00:00
|
|
|
}
|
|
|
|
|
2002-10-13 06:04:05 +00:00
|
|
|
- (NSArray*) allOutletsForObject: (id)obj
|
1999-12-20 14:20:06 +00:00
|
|
|
{
|
|
|
|
NSString *className;
|
|
|
|
NSArray *outlets;
|
1999-12-20 15:21:26 +00:00
|
|
|
Class theClass = [obj class];
|
2002-10-13 06:04:05 +00:00
|
|
|
NSString *customClassName = [self customClassForObject: obj];
|
1999-12-20 15:21:26 +00:00
|
|
|
|
2003-01-09 03:39:27 +00:00
|
|
|
NSDebugLog(@"** OUTLETS");
|
|
|
|
NSDebugLog(@"Object: %@",obj);
|
|
|
|
NSDebugLog(@"Custom class: %@",customClassName);
|
2003-02-13 13:32:59 +00:00
|
|
|
if (customClassName != nil)
|
2002-10-13 06:04:05 +00:00
|
|
|
{
|
|
|
|
// if the object has been mapped to a custom class, then
|
|
|
|
// get the information for it.
|
|
|
|
className = customClassName;
|
|
|
|
}
|
|
|
|
else if (theClass == [GormFirstResponder class])
|
1999-12-20 15:21:26 +00:00
|
|
|
{
|
|
|
|
return nil;
|
|
|
|
}
|
2002-10-13 06:04:05 +00:00
|
|
|
else if (theClass == [GormFilesOwner class])
|
1999-12-20 15:21:26 +00:00
|
|
|
{
|
|
|
|
className = [(GormFilesOwner*)obj className];
|
|
|
|
}
|
2001-05-08 09:43:11 +00:00
|
|
|
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];
|
|
|
|
}
|
2001-10-03 17:38:46 +00:00
|
|
|
else if ([obj isKindOfClass: [GormCustomView class]] == YES)
|
|
|
|
{
|
|
|
|
// this adds support for custom views
|
|
|
|
className = [(id)obj className];
|
|
|
|
}
|
1999-12-20 15:21:26 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
className = NSStringFromClass(theClass);
|
|
|
|
}
|
1999-12-20 14:20:06 +00:00
|
|
|
|
|
|
|
if (className == nil)
|
|
|
|
{
|
2002-09-10 03:00:12 +00:00
|
|
|
NSLog(@"attempt to get outlets for non-existent class (%@)",
|
|
|
|
[obj class]);
|
1999-12-20 14:20:06 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
outlets = [self allOutletsForClassNamed: className];
|
|
|
|
while (outlets == nil && (theClass = class_get_super_class(theClass)) != nil
|
|
|
|
&& theClass != [NSObject class])
|
|
|
|
{
|
|
|
|
className = NSStringFromClass(theClass);
|
|
|
|
outlets = [self allOutletsForClassNamed: className];
|
|
|
|
}
|
|
|
|
return outlets;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray*) allOutletsForClassNamed: (NSString*)className;
|
|
|
|
{
|
|
|
|
NSMutableDictionary *info = [classInformation objectForKey: className];
|
|
|
|
|
|
|
|
if (info != nil)
|
|
|
|
{
|
|
|
|
NSMutableArray *allOutlets = [info objectForKey: @"AllOutlets"];
|
|
|
|
|
|
|
|
if (allOutlets == nil)
|
|
|
|
{
|
|
|
|
NSString *superName = [info objectForKey: @"Super"];
|
|
|
|
NSArray *outlets = [info objectForKey: @"Outlets"];
|
|
|
|
NSArray *superOutlets;
|
|
|
|
|
|
|
|
if (superName == nil)
|
|
|
|
{
|
|
|
|
superOutlets = nil;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
superOutlets = [self allOutletsForClassNamed: superName];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (superOutlets == nil)
|
|
|
|
{
|
|
|
|
if (outlets == nil)
|
|
|
|
{
|
|
|
|
allOutlets = [NSMutableArray new];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
allOutlets = [outlets mutableCopy];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
allOutlets = [superOutlets mutableCopy];
|
|
|
|
if (outlets != nil)
|
|
|
|
{
|
|
|
|
NSEnumerator *enumerator = [outlets objectEnumerator];
|
|
|
|
NSString *outletName;
|
|
|
|
|
|
|
|
while ((outletName = [enumerator nextObject]) != nil)
|
|
|
|
{
|
|
|
|
if ([allOutlets containsObject: outletName] == NO)
|
|
|
|
{
|
|
|
|
[allOutlets addObject: outletName];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[allOutlets sortUsingSelector: @selector(compare:)];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[info setObject: allOutlets forKey: @"AllOutlets"];
|
|
|
|
RELEASE(allOutlets);
|
|
|
|
}
|
|
|
|
return AUTORELEASE([allOutlets copy]);
|
|
|
|
}
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
1999-12-21 11:38:49 +00:00
|
|
|
- (NSMutableDictionary*) classInfoForClassName: (NSString*)className
|
|
|
|
{
|
|
|
|
NSMutableDictionary *info;
|
|
|
|
|
|
|
|
info = [classInformation objectForKey: className];
|
|
|
|
if (info == nil)
|
|
|
|
{
|
|
|
|
Class theClass = NSClassFromString(className);
|
|
|
|
|
|
|
|
if (theClass != nil)
|
|
|
|
{
|
|
|
|
theClass = class_get_super_class(theClass);
|
|
|
|
if (theClass != nil && theClass != [NSObject class])
|
|
|
|
{
|
|
|
|
NSString *name;
|
|
|
|
NSMutableDictionary *dict;
|
|
|
|
|
|
|
|
name = NSStringFromClass(theClass);
|
|
|
|
dict = [self classInfoForClassName: name];
|
|
|
|
if (dict != nil)
|
|
|
|
{
|
|
|
|
id o;
|
|
|
|
|
|
|
|
info = [[NSMutableDictionary alloc] initWithCapacity: 3];
|
|
|
|
[info setObject: name forKey: @"Super"];
|
|
|
|
o = [[self allActionsForClassNamed: name] mutableCopy];
|
|
|
|
[info setObject: o forKey: @"AllActions"];
|
|
|
|
o = [[self allOutletsForClassNamed: name] mutableCopy];
|
|
|
|
[info setObject: o forKey: @"AllOutlets"];
|
|
|
|
[classInformation setObject: info forKey: className];
|
|
|
|
RELEASE(info);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2001-05-08 09:43:11 +00:00
|
|
|
}
|
1999-12-21 11:38:49 +00:00
|
|
|
return info;
|
|
|
|
}
|
|
|
|
|
2002-10-13 06:04:05 +00:00
|
|
|
- (NSMutableDictionary*) classInfoForObject: (id)obj
|
1999-12-21 11:38:49 +00:00
|
|
|
{
|
|
|
|
NSString *className;
|
|
|
|
Class theClass = [obj class];
|
|
|
|
|
|
|
|
if (theClass == [GormFilesOwner class])
|
|
|
|
{
|
|
|
|
className = [(GormFilesOwner*)obj className];
|
|
|
|
}
|
2001-05-08 09:43:11 +00:00
|
|
|
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];
|
2001-10-03 17:38:46 +00:00
|
|
|
}
|
|
|
|
else if ([obj isKindOfClass: [GormCustomView class]] == YES)
|
|
|
|
{
|
|
|
|
// this adds support for custom views
|
|
|
|
className = [(id)obj className];
|
2001-05-08 09:43:11 +00:00
|
|
|
}
|
1999-12-21 11:38:49 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
className = NSStringFromClass(theClass);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (className == nil)
|
|
|
|
{
|
2002-09-10 03:00:12 +00:00
|
|
|
NSLog(@"attempt to get outlets for non-existent class (%@)",
|
|
|
|
[obj class]);
|
1999-12-21 11:38:49 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
return [self classInfoForClassName: className];
|
|
|
|
}
|
|
|
|
|
1999-12-20 14:20:06 +00:00
|
|
|
- (void) dealloc
|
|
|
|
{
|
|
|
|
RELEASE(classInformation);
|
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
2002-10-13 06:04:05 +00:00
|
|
|
- (NSArray*) extraActionsForObject: (id)anObject
|
1999-12-21 11:38:49 +00:00
|
|
|
{
|
|
|
|
NSMutableDictionary *info = [self classInfoForObject: anObject];
|
|
|
|
|
|
|
|
return [info objectForKey: @"ExtraActions"];
|
|
|
|
}
|
2001-05-08 09:43:11 +00:00
|
|
|
|
2002-10-13 06:04:05 +00:00
|
|
|
- (NSArray*) extraOutletsForObject: (id)anObject
|
1999-12-21 11:38:49 +00:00
|
|
|
{
|
|
|
|
NSMutableDictionary *info = [self classInfoForObject: anObject];
|
|
|
|
|
|
|
|
return [info objectForKey: @"ExtraOutlets"];
|
|
|
|
}
|
2001-05-08 09:43:11 +00:00
|
|
|
|
|
|
|
- (id) init
|
1999-12-20 14:20:06 +00:00
|
|
|
{
|
|
|
|
self = [super init];
|
|
|
|
if (self != nil)
|
|
|
|
{
|
|
|
|
NSBundle *bundle = [NSBundle mainBundle];
|
|
|
|
NSString *path;
|
|
|
|
|
|
|
|
path = [bundle pathForResource: @"ClassInformation" ofType: @"plist"];
|
|
|
|
if (path == nil)
|
|
|
|
{
|
|
|
|
NSLog(@"ClassInformation.plist missing from resources");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-10-13 06:04:05 +00:00
|
|
|
// load the classes, initialize the custom class array and map..
|
2001-05-08 09:43:11 +00:00
|
|
|
[self loadFromFile: path];
|
2003-02-13 13:32:59 +00:00
|
|
|
customClasses = [[NSMutableArray alloc] initWithCapacity: 1];
|
|
|
|
customClassMap = [[NSMutableDictionary alloc] initWithCapacity: 10];
|
2002-10-31 15:00:17 +00:00
|
|
|
|
|
|
|
// add first responder so that it may be edited.
|
|
|
|
[customClasses addObject: @"FirstResponder"];
|
1999-12-20 14:20:06 +00:00
|
|
|
}
|
|
|
|
}
|
2002-10-13 06:04:05 +00:00
|
|
|
|
1999-12-20 14:20:06 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2002-07-21 04:04:18 +00:00
|
|
|
- (void) allSubclassesOf: (NSString *)superclass
|
|
|
|
referenceClassList: (NSArray *)classList
|
|
|
|
intoArray: (NSMutableArray *)array
|
|
|
|
{
|
|
|
|
NSEnumerator *cen = [classList objectEnumerator];
|
|
|
|
id object = nil;
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
while ((object = [cen nextObject]))
|
2002-07-21 04:04:18 +00:00
|
|
|
{
|
|
|
|
NSDictionary *dictForClass = [classInformation objectForKey: object];
|
2003-02-13 13:32:59 +00:00
|
|
|
if ([[dictForClass objectForKey: @"Super"] isEqual: superclass])
|
2002-07-21 04:04:18 +00:00
|
|
|
{
|
|
|
|
[array addObject: object];
|
|
|
|
[self allSubclassesOf: object
|
2003-02-13 13:32:59 +00:00
|
|
|
referenceClassList: classList
|
|
|
|
intoArray: array];
|
2002-07-21 04:04:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray *) allCustomSubclassesOf: (NSString *)superClass
|
|
|
|
{
|
|
|
|
NSMutableArray *array = [NSMutableArray array];
|
2003-02-13 13:32:59 +00:00
|
|
|
|
2002-07-21 04:04:18 +00:00
|
|
|
[self allSubclassesOf: superClass
|
2003-02-13 13:32:59 +00:00
|
|
|
referenceClassList: customClasses
|
|
|
|
intoArray: array];
|
2002-10-31 15:00:17 +00:00
|
|
|
|
|
|
|
// add known allowable subclasses to the list.
|
2003-02-13 13:32:59 +00:00
|
|
|
if ([superClass isEqualToString: @"NSWindow"])
|
2002-10-31 15:00:17 +00:00
|
|
|
{
|
|
|
|
[array addObject: @"NSPanel"];
|
|
|
|
}
|
2003-02-13 13:32:59 +00:00
|
|
|
else if ([superClass isEqualToString: @"NSTextField"])
|
2002-10-31 15:00:17 +00:00
|
|
|
{
|
|
|
|
[array addObject: @"NSSecureTextField"];
|
|
|
|
}
|
|
|
|
|
2002-07-21 04:04:18 +00:00
|
|
|
return array;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray *) customSubClassesOf: (NSString *)superclass
|
|
|
|
{
|
|
|
|
NSEnumerator *cen = [customClasses objectEnumerator];
|
|
|
|
id object = nil;
|
|
|
|
NSMutableArray *subclasses = [NSMutableArray array];
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
while ((object = [cen nextObject]))
|
2002-07-21 04:04:18 +00:00
|
|
|
{
|
|
|
|
NSDictionary *dictForClass = [classInformation objectForKey: object];
|
2003-02-13 13:32:59 +00:00
|
|
|
|
|
|
|
if ([[dictForClass objectForKey: @"Super"] isEqual: superclass])
|
2002-07-21 04:04:18 +00:00
|
|
|
{
|
|
|
|
[subclasses addObject: object];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return subclasses;
|
|
|
|
}
|
|
|
|
|
2002-03-25 01:44:01 +00:00
|
|
|
- (NSArray *) subClassesOf: (NSString *)superclass
|
|
|
|
{
|
|
|
|
NSArray *allClasses = [classInformation allKeys];
|
|
|
|
NSEnumerator *cen = [allClasses objectEnumerator];
|
|
|
|
id object = nil;
|
|
|
|
NSMutableArray *subclasses = [NSMutableArray array];
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
while ((object = [cen nextObject]))
|
2002-03-25 01:44:01 +00:00
|
|
|
{
|
|
|
|
NSDictionary *dictForClass = [classInformation objectForKey: object];
|
2003-02-13 13:32:59 +00:00
|
|
|
|
|
|
|
if ([[dictForClass objectForKey: @"Super"] isEqual: superclass])
|
2002-03-25 01:44:01 +00:00
|
|
|
{
|
|
|
|
[subclasses addObject: object];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return subclasses;
|
|
|
|
}
|
|
|
|
|
1999-12-21 11:38:49 +00:00
|
|
|
- (void) removeAction: (NSString*)anAction forObject: (id)anObject
|
|
|
|
{
|
|
|
|
NSMutableDictionary *info = [self classInfoForObject: anObject];
|
|
|
|
NSMutableArray *extraActions = [info objectForKey: @"ExtraActions"];
|
2003-01-01 07:07:27 +00:00
|
|
|
NSMutableArray *allActions = [info objectForKey: @"AllActions"];
|
1999-12-21 11:38:49 +00:00
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
if ([extraActions containsObject: anAction] == YES
|
|
|
|
|| [allActions containsObject: anAction] == YES)
|
1999-12-21 11:38:49 +00:00
|
|
|
{
|
|
|
|
NSString *superName = [info objectForKey: @"Super"];
|
|
|
|
|
2003-06-06 06:24:46 +00:00
|
|
|
[self _touch];
|
1999-12-21 11:38:49 +00:00
|
|
|
if (superName != nil)
|
|
|
|
{
|
|
|
|
NSArray *superActions;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If this action is new in this class (ie not overriding an
|
|
|
|
* action in a parent) then we remove it from the list of all
|
|
|
|
* actions that the object responds to.
|
|
|
|
*/
|
|
|
|
superActions = [self allActionsForClassNamed: superName];
|
|
|
|
if ([superActions containsObject: anAction] == NO)
|
|
|
|
{
|
|
|
|
NSMutableArray *array = [info objectForKey: @"AllActions"];
|
|
|
|
|
|
|
|
[array removeObject: anAction];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[extraActions removeObject: anAction];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
- (void) removeAction: (NSString*)anAction
|
|
|
|
fromClassNamed: (NSString *)className
|
2002-07-15 05:58:01 +00:00
|
|
|
{
|
|
|
|
NSMutableDictionary *info = [classInformation objectForKey: className];
|
|
|
|
NSMutableArray *extraActions = [info objectForKey: @"ExtraActions"];
|
2003-01-01 07:07:27 +00:00
|
|
|
NSMutableArray *allActions = [info objectForKey: @"AllActions"];
|
2002-07-15 05:58:01 +00:00
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
if ([extraActions containsObject: anAction] == YES
|
|
|
|
|| [allActions containsObject: anAction] == YES)
|
2002-07-15 05:58:01 +00:00
|
|
|
{
|
|
|
|
NSString *superName = [info objectForKey: @"Super"];
|
|
|
|
|
2003-06-06 06:24:46 +00:00
|
|
|
[self _touch];
|
2002-07-15 05:58:01 +00:00
|
|
|
if (superName != nil)
|
|
|
|
{
|
|
|
|
NSArray *superActions;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If this action is new in this class (ie not overriding an
|
|
|
|
* action in a parent) then we remove it from the list of all
|
|
|
|
* actions that the object responds to.
|
|
|
|
*/
|
|
|
|
superActions = [self allActionsForClassNamed: superName];
|
|
|
|
if ([superActions containsObject: anAction] == NO)
|
|
|
|
{
|
|
|
|
NSMutableArray *array = [info objectForKey: @"AllActions"];
|
|
|
|
|
|
|
|
[array removeObject: anAction];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[extraActions removeObject: anAction];
|
|
|
|
}
|
2003-05-25 19:08:36 +00:00
|
|
|
if(![className isEqualToString: @"FirstResponder"])
|
|
|
|
{
|
|
|
|
[self removeAction: anAction fromClassNamed: @"FirstResponder"];
|
|
|
|
}
|
2002-07-15 05:58:01 +00:00
|
|
|
}
|
|
|
|
|
1999-12-21 11:38:49 +00:00
|
|
|
- (void) removeOutlet: (NSString*)anOutlet forObject: (id)anObject
|
|
|
|
{
|
|
|
|
NSMutableDictionary *info = [self classInfoForObject: anObject];
|
|
|
|
NSMutableArray *extraOutlets = [info objectForKey: @"ExtraOutlets"];
|
2001-06-20 16:00:19 +00:00
|
|
|
NSMutableArray *allOutlets = [info objectForKey: @"AllOutlets"];
|
1999-12-21 11:38:49 +00:00
|
|
|
|
|
|
|
if ([extraOutlets containsObject: anOutlet] == YES)
|
|
|
|
{
|
2003-06-06 06:24:46 +00:00
|
|
|
[self _touch];
|
1999-12-21 11:38:49 +00:00
|
|
|
[extraOutlets removeObject: anOutlet];
|
|
|
|
}
|
2001-06-20 16:00:19 +00:00
|
|
|
if ([allOutlets containsObject: anOutlet] == YES)
|
|
|
|
{
|
2003-06-06 06:24:46 +00:00
|
|
|
[self _touch];
|
2001-06-20 16:00:19 +00:00
|
|
|
[allOutlets removeObject: anOutlet];
|
|
|
|
}
|
1999-12-21 11:38:49 +00:00
|
|
|
}
|
2001-07-09 15:39:20 +00:00
|
|
|
|
2002-07-15 05:58:01 +00:00
|
|
|
- (void) removeOutlet: (NSString*)anOutlet fromClassNamed: (NSString *)className
|
|
|
|
{
|
|
|
|
NSMutableDictionary *info = [classInformation objectForKey: className];
|
|
|
|
NSMutableArray *extraOutlets = [info objectForKey: @"ExtraOutlets"];
|
|
|
|
NSMutableArray *allOutlets = [info objectForKey: @"AllOutlets"];
|
|
|
|
|
|
|
|
if ([extraOutlets containsObject: anOutlet] == YES)
|
|
|
|
{
|
2003-06-06 06:24:46 +00:00
|
|
|
[self _touch];
|
2002-07-15 05:58:01 +00:00
|
|
|
[extraOutlets removeObject: anOutlet];
|
|
|
|
}
|
|
|
|
if ([allOutlets containsObject: anOutlet] == YES)
|
|
|
|
{
|
2003-06-06 06:24:46 +00:00
|
|
|
[self _touch];
|
2002-07-15 05:58:01 +00:00
|
|
|
[allOutlets removeObject: anOutlet];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) removeClassNamed: (NSString *)className
|
|
|
|
{
|
2003-02-13 13:32:59 +00:00
|
|
|
if ([customClasses containsObject: className])
|
2002-07-15 05:58:01 +00:00
|
|
|
{
|
2003-06-06 06:24:46 +00:00
|
|
|
[self _touch];
|
2002-07-15 05:58:01 +00:00
|
|
|
[customClasses removeObject: className];
|
|
|
|
}
|
|
|
|
|
|
|
|
[classInformation removeObjectForKey: className];
|
|
|
|
}
|
|
|
|
|
2001-05-08 09:43:11 +00:00
|
|
|
- (BOOL) renameClassNamed: (NSString*)oldName newName: (NSString*)name
|
|
|
|
{
|
|
|
|
id classInfo = [classInformation objectForKey: oldName];
|
|
|
|
|
|
|
|
if (classInfo != nil && [classInformation objectForKey: name] == nil)
|
|
|
|
{
|
2002-07-14 23:54:05 +00:00
|
|
|
int index = 0;
|
|
|
|
|
2003-06-06 06:24:46 +00:00
|
|
|
[self _touch];
|
2001-05-08 09:43:11 +00:00
|
|
|
RETAIN(classInfo);
|
|
|
|
|
|
|
|
[classInformation removeObjectForKey: oldName];
|
|
|
|
[classInformation setObject: classInfo forKey: name];
|
|
|
|
|
|
|
|
RELEASE(classInfo);
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
if ((index = [customClasses indexOfObject: oldName]) != NSNotFound)
|
2002-07-14 23:54:05 +00:00
|
|
|
{
|
|
|
|
[customClasses replaceObjectAtIndex: index withObject: name];
|
|
|
|
}
|
|
|
|
|
2001-05-08 09:43:11 +00:00
|
|
|
[[NSNotificationCenter defaultCenter]
|
|
|
|
postNotificationName: IBClassNameChangedNotification object: self];
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
else return NO;
|
|
|
|
|
|
|
|
}
|
2003-02-13 13:32:59 +00:00
|
|
|
|
2001-05-08 09:43:11 +00:00
|
|
|
- (BOOL) saveToFile: (NSString*)path
|
|
|
|
{
|
|
|
|
NSMutableDictionary *ci;
|
|
|
|
NSEnumerator *enumerator;
|
|
|
|
id key;
|
|
|
|
|
|
|
|
ci = AUTORELEASE([[NSMutableDictionary alloc] initWithCapacity: 0]);
|
2002-07-14 23:54:05 +00:00
|
|
|
enumerator = [customClasses objectEnumerator];
|
2001-05-08 09:43:11 +00:00
|
|
|
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"];
|
2001-07-09 15:39:20 +00:00
|
|
|
if (obj && extraObj)
|
|
|
|
{
|
|
|
|
obj = [obj arrayByAddingObjectsFromArray: extraObj];
|
|
|
|
}
|
|
|
|
else if (extraObj)
|
|
|
|
{
|
|
|
|
obj = extraObj;
|
|
|
|
}
|
2001-05-08 09:43:11 +00:00
|
|
|
if (obj != nil)
|
|
|
|
{
|
|
|
|
[newInfo setObject: obj forKey: @"Outlets"];
|
|
|
|
}
|
|
|
|
obj = [classInfo objectForKey: @"Actions"];
|
|
|
|
extraObj = [classInfo objectForKey: @"ExtraActions"];
|
2001-07-09 15:39:20 +00:00
|
|
|
if (obj && extraObj)
|
|
|
|
{
|
|
|
|
obj = [obj arrayByAddingObjectsFromArray: extraObj];
|
|
|
|
}
|
|
|
|
else if (extraObj)
|
|
|
|
{
|
|
|
|
obj = extraObj;
|
|
|
|
}
|
2001-05-08 09:43:11 +00:00
|
|
|
if (obj != nil)
|
|
|
|
{
|
|
|
|
[newInfo setObject: obj forKey: @"Actions"];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return [ci writeToFile: path atomically: YES];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) loadFromFile: (NSString*)path
|
|
|
|
{
|
|
|
|
NSDictionary *dict;
|
|
|
|
NSEnumerator *enumerator;
|
|
|
|
NSString *key;
|
|
|
|
|
2002-12-15 18:17:53 +00:00
|
|
|
NSDebugLog(@"Load from file %@",path);
|
2001-05-08 09:43:11 +00:00
|
|
|
|
|
|
|
dict = [NSDictionary dictionaryWithContentsOfFile: path];
|
2002-07-14 23:54:05 +00:00
|
|
|
// customClasses = [NSMutableArray arrayWithCapacity: 1];
|
2001-05-08 09:43:11 +00:00
|
|
|
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;
|
2002-10-31 15:00:17 +00:00
|
|
|
NSMutableDictionary *oldInfo;
|
2001-05-08 09:43:11 +00:00
|
|
|
id obj;
|
|
|
|
|
|
|
|
newInfo = [NSMutableDictionary new];
|
2002-10-31 15:00:17 +00:00
|
|
|
oldInfo = [classInformation objectForKey: key];
|
|
|
|
|
2001-05-08 09:43:11 +00:00
|
|
|
[classInformation setObject: newInfo forKey: key];
|
|
|
|
RELEASE(newInfo);
|
2002-10-31 15:00:17 +00:00
|
|
|
|
2001-05-08 09:43:11 +00:00
|
|
|
obj = [classInfo objectForKey: @"Super"];
|
|
|
|
if (obj != nil)
|
|
|
|
{
|
|
|
|
[newInfo setObject: obj forKey: @"Super"];
|
|
|
|
}
|
2002-10-31 15:00:17 +00:00
|
|
|
|
|
|
|
// outlets
|
2001-05-08 09:43:11 +00:00
|
|
|
obj = [classInfo objectForKey: @"Outlets"];
|
|
|
|
if (obj != nil)
|
|
|
|
{
|
|
|
|
obj = [obj mutableCopy];
|
|
|
|
[obj sortUsingSelector: @selector(compare:)];
|
|
|
|
[newInfo setObject: obj forKey: @"Outlets"];
|
|
|
|
RELEASE(obj);
|
|
|
|
}
|
2002-10-31 15:00:17 +00:00
|
|
|
|
|
|
|
// actions
|
2001-05-08 09:43:11 +00:00
|
|
|
obj = [classInfo objectForKey: @"Actions"];
|
|
|
|
if (obj != nil)
|
|
|
|
{
|
|
|
|
obj = [obj mutableCopy];
|
|
|
|
[obj sortUsingSelector: @selector(compare:)];
|
|
|
|
[newInfo setObject: obj forKey: @"Actions"];
|
|
|
|
RELEASE(obj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
2002-10-31 15:00:17 +00:00
|
|
|
- (void) _convertDictionary: (NSMutableDictionary *)dict
|
|
|
|
{
|
|
|
|
NSMutableArray *array = [classInformation allKeys];
|
|
|
|
[dict removeObjectsForKeys: array];
|
|
|
|
}
|
|
|
|
|
2002-07-14 23:54:05 +00:00
|
|
|
// this method will load the custom classes and merge them with the
|
|
|
|
// Class information loaded at initialization time.
|
2003-02-13 13:32:59 +00:00
|
|
|
- (BOOL) loadCustomClasses: (NSString *)path
|
2002-07-14 23:54:05 +00:00
|
|
|
{
|
2002-10-31 15:00:17 +00:00
|
|
|
NSMutableDictionary *dict;
|
2002-07-14 23:54:05 +00:00
|
|
|
|
2002-12-15 18:17:53 +00:00
|
|
|
NSDebugLog(@"Load custom classes from file %@",path);
|
2002-07-14 23:54:05 +00:00
|
|
|
|
|
|
|
dict = [NSMutableDictionary dictionaryWithContentsOfFile: path];
|
|
|
|
if (dict == nil)
|
|
|
|
{
|
|
|
|
NSLog(@"Could not load custom classes dictionary");
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
if (classInformation == nil)
|
2002-07-14 23:54:05 +00:00
|
|
|
{
|
|
|
|
NSLog(@"Default classes file not loaded");
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
if ([[dict allKeys] containsObject: @"NSObject"])
|
2002-07-14 23:54:05 +00:00
|
|
|
{
|
|
|
|
NSLog(@"The file being loaded is in the old .classes format. Updating..");
|
2002-10-31 15:00:17 +00:00
|
|
|
[self _convertDictionary: dict];
|
2002-07-14 23:54:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
[customClasses addObjectsFromArray: [dict allKeys]];
|
|
|
|
[classInformation addEntriesFromDictionary: dict];
|
2002-10-31 15:00:17 +00:00
|
|
|
|
2002-07-14 23:54:05 +00:00
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) isCustomClass: (NSString *)className
|
|
|
|
{
|
2003-06-07 05:21:16 +00:00
|
|
|
return ([customClasses indexOfObject: className] != NSNotFound); // &&
|
|
|
|
// ![className isEqualToString: @"FirstResponder"]);
|
2002-07-14 23:54:05 +00:00
|
|
|
}
|
|
|
|
|
2002-11-21 01:00:08 +00:00
|
|
|
- (BOOL) isKnownClass: (NSString *)className
|
|
|
|
{
|
|
|
|
return ([classInformation objectForKey: className] != nil);
|
|
|
|
}
|
|
|
|
|
2001-05-08 09:43:11 +00:00
|
|
|
- (BOOL) setSuperClassNamed: (NSString*)superclass
|
|
|
|
forClassNamed: (NSString*)subclass
|
|
|
|
{
|
|
|
|
NSArray *cn = [self allClassNames];
|
|
|
|
|
|
|
|
if (superclass != nil && subclass != nil && [cn containsObject: subclass]
|
2001-07-09 15:39:20 +00:00
|
|
|
&& ([cn containsObject: superclass]
|
|
|
|
|| [superclass isEqualToString: @"NSObject"])
|
|
|
|
&& [self isSuperclass: subclass linkedToClass: superclass] == NO)
|
2001-05-08 09:43:11 +00:00
|
|
|
{
|
|
|
|
NSMutableDictionary *info;
|
|
|
|
|
|
|
|
info = [classInformation objectForKey: subclass];
|
|
|
|
if (info != nil)
|
|
|
|
{
|
|
|
|
[info setObject: superclass forKey: @"Super"];
|
|
|
|
return YES;
|
|
|
|
}
|
2001-07-09 15:39:20 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
2001-05-08 09:43:11 +00:00
|
|
|
}
|
|
|
|
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;
|
|
|
|
|
|
|
|
}
|
2001-07-09 15:39:20 +00:00
|
|
|
|
2001-05-08 09:43:11 +00:00
|
|
|
- (BOOL) isSuperclass: (NSString*)superclass linkedToClass: (NSString*)subclass
|
|
|
|
{
|
|
|
|
NSString *ssclass;
|
|
|
|
|
2003-01-09 03:39:27 +00:00
|
|
|
//NSDebugLog(@"isSuperClass : %@, %@", superclass, subclass);
|
1999-12-21 11:38:49 +00:00
|
|
|
|
2001-05-08 09:43:11 +00:00
|
|
|
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];
|
|
|
|
}
|
|
|
|
}
|
2001-07-06 17:10:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* create .m & .h files for a class
|
|
|
|
*/
|
|
|
|
- (BOOL) makeSourceAndHeaderFilesForClass: (NSString*)className
|
2001-07-09 15:39:20 +00:00
|
|
|
withName: (NSString*)sourcePath
|
|
|
|
and: (NSString*)headerPath
|
2001-07-06 17:10:51 +00:00
|
|
|
{
|
2001-07-09 15:39:20 +00:00
|
|
|
NSMutableString *headerFile;
|
|
|
|
NSMutableString *sourceFile;
|
|
|
|
NSData *headerData;
|
|
|
|
NSData *sourceData;
|
|
|
|
NSArray *outlets;
|
|
|
|
NSArray *actions;
|
|
|
|
NSString *actionName;
|
|
|
|
int i;
|
|
|
|
int n;
|
2001-07-06 17:10:51 +00:00
|
|
|
|
|
|
|
headerFile = [NSMutableString stringWithCapacity: 200];
|
|
|
|
sourceFile = [NSMutableString stringWithCapacity: 200];
|
|
|
|
outlets = [self allOutletsForClassNamed: className];
|
|
|
|
actions = [self allActionsForClassNamed: className];
|
|
|
|
|
|
|
|
[headerFile appendString: @"/* All Rights reserved */\n\n"];
|
|
|
|
[sourceFile appendString: @"/* All Rights reserved */\n\n"];
|
2003-03-03 09:15:48 +00:00
|
|
|
[headerFile appendString: @"#include <AppKit/AppKit.h>\n\n"];
|
|
|
|
[sourceFile appendString: @"#include <AppKit/AppKit.h>\n"];
|
2001-07-06 17:10:51 +00:00
|
|
|
if ([[headerPath stringByDeletingLastPathComponent]
|
2001-07-09 15:39:20 +00:00
|
|
|
isEqualToString: [sourcePath stringByDeletingLastPathComponent]])
|
2001-07-06 17:10:51 +00:00
|
|
|
{
|
2003-03-03 09:15:48 +00:00
|
|
|
[sourceFile appendFormat: @"#include \"%@\"\n\n",
|
2001-07-09 15:39:20 +00:00
|
|
|
[headerPath lastPathComponent]];
|
2001-07-06 17:10:51 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-03-03 09:15:48 +00:00
|
|
|
[sourceFile appendFormat: @"#include \"%@\"\n\n",
|
2001-07-09 15:39:20 +00:00
|
|
|
headerPath];
|
|
|
|
}
|
|
|
|
[headerFile appendFormat: @"@interface %@ : %@\n{\n", className,
|
|
|
|
[self superClassNameForClassNamed: className]];
|
|
|
|
[sourceFile appendFormat: @"@implementation %@\n\n", className];
|
2001-07-06 17:10:51 +00:00
|
|
|
|
|
|
|
n = [outlets count];
|
2001-07-09 15:39:20 +00:00
|
|
|
for (i = 0; i < n; i++)
|
2001-07-06 17:10:51 +00:00
|
|
|
{
|
2001-07-09 15:39:20 +00:00
|
|
|
[headerFile appendFormat: @" id %@;\n", [outlets objectAtIndex: i]];
|
2001-07-06 17:10:51 +00:00
|
|
|
}
|
|
|
|
[headerFile appendFormat: @"}\n"];
|
|
|
|
|
|
|
|
n = [actions count];
|
2001-07-09 15:39:20 +00:00
|
|
|
for (i = 0; i < n; i++)
|
|
|
|
{
|
|
|
|
actionName = [actions objectAtIndex: i];
|
2001-10-29 06:10:30 +00:00
|
|
|
[headerFile appendFormat: @"- (void) %@ (id)sender;\n", actionName];
|
2001-07-09 15:39:20 +00:00
|
|
|
[sourceFile appendFormat:
|
|
|
|
@"\n"
|
2001-10-29 06:10:30 +00:00
|
|
|
@"- (void) %@ (id)sender\n"
|
2001-07-09 15:39:20 +00:00
|
|
|
@"{\n"
|
|
|
|
@" /* insert your code here */\n"
|
|
|
|
@"}\n"
|
|
|
|
@"\n"
|
|
|
|
, [actions objectAtIndex: i]];
|
2001-07-06 17:10:51 +00:00
|
|
|
}
|
|
|
|
[headerFile appendFormat: @"@end\n"];
|
|
|
|
[sourceFile appendFormat: @"@end\n"];
|
|
|
|
|
|
|
|
headerData = [headerFile dataUsingEncoding:
|
2001-07-09 15:39:20 +00:00
|
|
|
[NSString defaultCStringEncoding]];
|
2001-07-06 17:10:51 +00:00
|
|
|
sourceData = [sourceFile dataUsingEncoding:
|
2001-07-09 15:39:20 +00:00
|
|
|
[NSString defaultCStringEncoding]];
|
2001-07-06 17:10:51 +00:00
|
|
|
|
|
|
|
[headerData writeToFile: headerPath atomically: NO];
|
|
|
|
[sourceData writeToFile: sourcePath atomically: NO];
|
|
|
|
|
|
|
|
return YES;
|
|
|
|
}
|
2002-07-14 23:54:05 +00:00
|
|
|
|
|
|
|
- (BOOL) isAction: (NSString *)name ofClass: (NSString *)className
|
|
|
|
{
|
|
|
|
BOOL result = NO;
|
|
|
|
NSDictionary *classInfo = [classInformation objectForKey: className];
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
if (classInfo != nil)
|
2002-07-14 23:54:05 +00:00
|
|
|
{
|
|
|
|
NSArray *array = [classInfo objectForKey: @"Actions"];
|
|
|
|
NSArray *extra_array = [classInfo objectForKey: @"ExtraActions"];
|
|
|
|
NSMutableArray *combined = [NSMutableArray array];
|
|
|
|
|
|
|
|
[combined addObjectsFromArray: array];
|
|
|
|
[combined addObjectsFromArray: extra_array];
|
|
|
|
result = ([combined indexOfObject: name] != NSNotFound);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) isOutlet: (NSString *)name ofClass: (NSString *)className
|
|
|
|
{
|
|
|
|
BOOL result = NO;
|
|
|
|
NSDictionary *classInfo = [classInformation objectForKey: className];
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
if (classInfo != nil)
|
2002-07-14 23:54:05 +00:00
|
|
|
{
|
|
|
|
NSArray *array = [classInfo objectForKey: @"Outlets"];
|
|
|
|
NSArray *extra_array = [classInfo objectForKey: @"ExtraOutlets"];
|
|
|
|
NSMutableArray *combined = [NSMutableArray array];
|
|
|
|
|
|
|
|
[combined addObjectsFromArray: array];
|
|
|
|
[combined addObjectsFromArray: extra_array];
|
|
|
|
result = ([combined indexOfObject: name] != NSNotFound);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
1999-12-21 11:38:49 +00:00
|
|
|
|
2002-10-13 06:04:05 +00:00
|
|
|
// custom class support...
|
2003-01-14 06:29:34 +00:00
|
|
|
- (NSString *) customClassForName: (NSString *)name
|
|
|
|
{
|
|
|
|
NSString *result = [customClassMap objectForKey: name];
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2002-10-13 06:04:05 +00:00
|
|
|
- (NSString *) customClassForObject: (id)object
|
1999-12-21 11:38:49 +00:00
|
|
|
{
|
2003-01-09 03:39:27 +00:00
|
|
|
NSString *name = [[(id<IB>)NSApp activeDocument] nameForObject: object];
|
2003-01-14 06:29:34 +00:00
|
|
|
NSString *result = [self customClassForName: name];
|
|
|
|
// NSString *result = [customClassMap objectForKey: name];
|
2003-01-09 03:39:27 +00:00
|
|
|
NSDebugLog(@"in customClassForObject: object = %@, name = %@, result = %@, customClassMap = %@",object, name, result, customClassMap);
|
2003-01-08 05:54:20 +00:00
|
|
|
return result;
|
1999-12-21 11:38:49 +00:00
|
|
|
}
|
2001-05-08 09:43:11 +00:00
|
|
|
|
2002-10-13 06:04:05 +00:00
|
|
|
- (void) setCustomClass: (NSString *)className
|
|
|
|
forObject: (id)object
|
1999-12-21 11:38:49 +00:00
|
|
|
{
|
2002-11-18 06:15:06 +00:00
|
|
|
// NSString *name = [NSString stringWithString: className];
|
2002-10-13 06:04:05 +00:00
|
|
|
[customClassMap setObject: className forKey: object];
|
1999-12-21 11:38:49 +00:00
|
|
|
}
|
|
|
|
|
2002-10-13 06:04:05 +00:00
|
|
|
- (void) removeCustomClassForObject: (id) object
|
1999-12-21 11:38:49 +00:00
|
|
|
{
|
2002-10-13 06:04:05 +00:00
|
|
|
[customClassMap removeObjectForKey: object];
|
1999-12-21 11:38:49 +00:00
|
|
|
}
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
- (NSMutableDictionary *) customClassMap
|
1999-12-21 11:38:49 +00:00
|
|
|
{
|
2002-10-13 06:04:05 +00:00
|
|
|
return customClassMap;
|
1999-12-21 11:38:49 +00:00
|
|
|
}
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
- (void) setCustomClassMap: (NSMutableDictionary *)dict
|
1999-12-21 11:38:49 +00:00
|
|
|
{
|
2002-10-13 06:04:05 +00:00
|
|
|
// copy the dictionary..
|
2002-12-15 18:17:53 +00:00
|
|
|
NSDebugLog(@"dictionary = %@",dict);
|
2002-11-18 06:15:06 +00:00
|
|
|
ASSIGN(customClassMap, dict);
|
|
|
|
RETAIN(customClassMap);
|
1999-12-21 11:38:49 +00:00
|
|
|
}
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
- (BOOL) isCustomClassMapEmpty
|
1999-12-21 11:38:49 +00:00
|
|
|
{
|
2002-10-13 06:04:05 +00:00
|
|
|
return ([customClassMap count] == 0);
|
2001-05-08 09:43:11 +00:00
|
|
|
}
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
- (NSString *) nonCustomSuperClassOf: (NSString *)className
|
2001-05-08 09:43:11 +00:00
|
|
|
{
|
2002-10-13 06:04:05 +00:00
|
|
|
NSString *result = className;
|
1999-12-21 11:38:49 +00:00
|
|
|
|
2002-10-13 06:04:05 +00:00
|
|
|
// iterate up the chain until a non-custom superclass is found...
|
2003-02-13 13:32:59 +00:00
|
|
|
while ([self isCustomClass: result])
|
1999-12-21 11:38:49 +00:00
|
|
|
{
|
2002-12-15 18:17:53 +00:00
|
|
|
NSDebugLog(@"result = %@",result);
|
2002-10-13 06:04:05 +00:00
|
|
|
result = [self superClassNameForClassNamed: result];
|
1999-12-21 11:38:49 +00:00
|
|
|
}
|
|
|
|
|
2002-10-13 06:04:05 +00:00
|
|
|
return result;
|
1999-12-21 11:38:49 +00:00
|
|
|
}
|
|
|
|
|
2003-02-13 13:32:59 +00:00
|
|
|
- (NSArray *) allSuperClassesOf: (NSString *)className
|
2002-12-15 07:30:35 +00:00
|
|
|
{
|
|
|
|
NSMutableArray *classes = [NSMutableArray array];
|
2003-02-13 13:32:59 +00:00
|
|
|
while (![className isEqualToString: @"NSObject"])
|
2002-12-15 07:30:35 +00:00
|
|
|
{
|
|
|
|
NSDictionary *dict = [self classInfoForClassName: className];
|
|
|
|
className = [dict objectForKey: @"Super"];
|
|
|
|
[classes insertObject: className atIndex: 0];
|
|
|
|
}
|
|
|
|
return classes;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (NSString *) correctClassName: (NSString *)className
|
|
|
|
{
|
|
|
|
if ([className isEqualToString: @"GormNSMenu"])
|
|
|
|
{
|
|
|
|
return @"NSMenu";
|
|
|
|
}
|
|
|
|
if ([className isEqualToString: @"GormNSWindow"])
|
|
|
|
{
|
|
|
|
return @"NSWindow";
|
|
|
|
}
|
2003-01-05 06:03:14 +00:00
|
|
|
if ([className isEqualToString: @"GormNSPanel"])
|
|
|
|
{
|
|
|
|
return @"NSPanel";
|
|
|
|
}
|
2002-12-15 07:30:35 +00:00
|
|
|
if ([className isEqualToString: @"GormNSBrowser"])
|
|
|
|
{
|
|
|
|
return @"NSBrowser";
|
|
|
|
}
|
|
|
|
if ([className isEqualToString: @"GormNSTableView"])
|
|
|
|
{
|
|
|
|
return @"NSTableView";
|
|
|
|
}
|
|
|
|
if ([className isEqualToString: @"GormNSOutlineView"])
|
|
|
|
{
|
|
|
|
return @"NSOutlineView";
|
|
|
|
}
|
|
|
|
if ([className isEqualToString: @"GormNSPopUpButton"])
|
|
|
|
{
|
|
|
|
return @"NSPopUpButton";
|
|
|
|
}
|
|
|
|
if ([className isEqualToString: @"GormNSPopUpButtonCell"])
|
|
|
|
{
|
|
|
|
return @"NSPopUpButtonCell";
|
|
|
|
}
|
|
|
|
if ([className isEqualToString: @"GormFirstResponder"])
|
|
|
|
{
|
|
|
|
return @"FirstResponder";
|
|
|
|
}
|
2003-01-08 05:54:20 +00:00
|
|
|
if ([className isEqualToString: @"GormFilesOwner"])
|
|
|
|
{
|
|
|
|
return @"FilesOwner";
|
|
|
|
}
|
2002-12-15 07:30:35 +00:00
|
|
|
|
|
|
|
return className;
|
|
|
|
}
|
1999-12-21 11:38:49 +00:00
|
|
|
@end
|