mirror of
https://github.com/gnustep/apps-gorm.git
synced 2025-02-23 19:51:00 +00:00
Cleanup, memory leak fix.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/apps/gorm/trunk@20290 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
2085f591e6
commit
5255ce829e
3 changed files with 160 additions and 101 deletions
|
@ -1,4 +1,11 @@
|
|||
2004-11-03 10:07 Gregory John Casamento <greg_casamento@yahoo.com>
|
||||
2004-11-04 01:43 Gregory John Casamento <greg_casamento@yahoo.com>
|
||||
|
||||
* GormClassManager.m: Corrected a memory leak in
|
||||
loadFromFile:.
|
||||
* GormClassManager.h: Added FSF/GPL header and organized
|
||||
the methods in the header according to function.
|
||||
|
||||
2004-11-03 22:07 Gregory John Casamento <greg_casamento@yahoo.com>
|
||||
|
||||
* GormClassManager.m: modified addNewActionToClassNamed: and
|
||||
addNewOutletToClassNamed: so that the initial names for outlets
|
||||
|
|
|
@ -1,21 +1,50 @@
|
|||
/* GormClassManager.h
|
||||
*
|
||||
* Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
*
|
||||
* Author: Richard Frith-Macdonald <richard@brainstrom.co.uk>
|
||||
* Author: Gregory John Casamento <greg_casamento@yahoo.com>
|
||||
* Date: 1999, 2002
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <InterfaceBuilder/IBPalette.h>
|
||||
|
||||
#ifndef INCLUDED_GormClassManager_h
|
||||
#define INCLUDED_GormClassManager_h
|
||||
|
||||
// the custom classes array will hold only those things which will be persisted
|
||||
// to the .classes file. Since the overall list of classes will not change
|
||||
// it seems that the only thing that we should save is the "delta" that being
|
||||
// the custom classes. Once loaded they can be "merged" in with the list of
|
||||
// base classes, in gui, to form the full list of classes.
|
||||
// the custom classes and category arrays will hold only those things which
|
||||
// will be persisted to the .classes file. Since the overall list of classes will
|
||||
// not change it seems that the only thing that we should save is the "delta"
|
||||
// that being the custom classes. Once loaded they can be "merged" in with the
|
||||
// list of base classes, in gui, to form the full list of classes.
|
||||
@interface GormClassManager : NSObject
|
||||
{
|
||||
NSMutableDictionary *classInformation;
|
||||
NSMutableArray *customClasses;
|
||||
NSMutableDictionary *customClassMap;
|
||||
NSMutableArray *categoryClasses;
|
||||
id document;
|
||||
}
|
||||
|
||||
- (id) initWithDocument: (id)aDocument;
|
||||
|
||||
/** Managing actions and outlets */
|
||||
- (void) addAction: (NSString*)anAction forObject: (id)anObject;
|
||||
- (void) addOutlet: (NSString*)anOutlet forObject: (id)anObject;
|
||||
- (NSArray*) allActionsForClassNamed: (NSString*)className;
|
||||
|
@ -25,10 +54,6 @@
|
|||
- (NSArray*) allOutletsForObject: (id)anObject;
|
||||
- (NSArray*) extraActionsForObject: (id)anObject;
|
||||
- (NSArray*) extraOutletsForObject: (id)anObject;
|
||||
- (NSArray*) subClassesOf: (NSString *)superclass;
|
||||
- (NSArray*) allSubclassesOf: (NSString *)superClass;
|
||||
- (NSArray*) customSubClassesOf: (NSString *)superclass;
|
||||
- (NSArray*) allCustomSubclassesOf: (NSString *)superclass;
|
||||
- (void) removeAction: (NSString*)anAction forObject: (id)anObject;
|
||||
- (void) removeOutlet: (NSString*)anOutlet forObject: (id)anObject;
|
||||
- (void) removeAction: (NSString*)anAction fromClassNamed: (NSString*)anObject;
|
||||
|
@ -41,9 +66,15 @@
|
|||
- (NSString *) addNewOutletToClassNamed: (NSString *)name;
|
||||
- (void) replaceAction: (NSString *)oldAction withAction: (NSString *)newAction forClassNamed: className;
|
||||
- (void) replaceOutlet: (NSString *)oldOutlet withOutlet: (NSString *)newOutlet forClassNamed: className;
|
||||
|
||||
/** Managing classes and subclasses */
|
||||
- (BOOL) renameClassNamed: (NSString *)oldName newName: (NSString*)name;
|
||||
- (void) removeClassNamed: (NSString *)className;
|
||||
- (NSString*) addClassWithSuperClassName: (NSString*)name;
|
||||
- (NSArray*) subClassesOf: (NSString *)superclass;
|
||||
- (NSArray*) allSubclassesOf: (NSString *)superClass;
|
||||
- (NSArray*) customSubClassesOf: (NSString *)superclass;
|
||||
- (NSArray*) allCustomSubclassesOf: (NSString *)superclass;
|
||||
|
||||
- (BOOL) addClassNamed: (NSString*)className
|
||||
withSuperClassNamed: (NSString*)superClassName
|
||||
|
@ -59,26 +90,21 @@
|
|||
- (BOOL) setSuperClassNamed: (NSString*)superclass
|
||||
forClassNamed: (NSString*)subclass;
|
||||
|
||||
- (NSString *)parentOfClass: (NSString *)aClass;
|
||||
- (NSString*) superClassNameForClassNamed: (NSString*)className;
|
||||
- (BOOL) isSuperclass: (NSString*)superclass
|
||||
linkedToClass: (NSString*)subclass;
|
||||
|
||||
- (BOOL) makeSourceAndHeaderFilesForClass: (NSString*)className
|
||||
withName:(NSString*)sourcePath
|
||||
and:(NSString*)headerPath;
|
||||
|
||||
- (BOOL) parseHeader: (NSString *)headerPath;
|
||||
- (BOOL) saveToFile: (NSString*)path;
|
||||
- (BOOL) loadFromFile: (NSString*)path;
|
||||
- (BOOL) loadCustomClasses: (NSString*)path;
|
||||
/** Managing custom classes */
|
||||
- (BOOL) isCustomClass: (NSString *)className;
|
||||
- (BOOL) isNonCustomClass: (NSString *)className;
|
||||
- (BOOL) isCategoryForClass: (NSString *)className;
|
||||
- (BOOL) isKnownClass: (NSString *)className;
|
||||
- (BOOL) isAction: (NSString *)actionName ofClass: (NSString *)className;
|
||||
- (BOOL) isOutlet: (NSString *)outletName ofClass: (NSString *)className;
|
||||
- (NSArray *) allSuperClassesOf: (NSString *)className;
|
||||
- (BOOL) canInstantiateClassNamed: (NSString *)className;
|
||||
|
||||
// custom class support...
|
||||
- (NSString *) customClassForObject: (id)object;
|
||||
- (NSString *) customClassForName: (NSString *)name;
|
||||
|
||||
|
@ -90,7 +116,19 @@
|
|||
- (void) setCustomClassMap: (NSMutableDictionary *)dict;
|
||||
- (BOOL) isCustomClassMapEmpty;
|
||||
- (NSString *) nonCustomSuperClassOf: (NSString *)className;
|
||||
- (NSString *)parentOfClass: (NSString *)aClass;
|
||||
|
||||
/** Parsing and creating classes */
|
||||
- (BOOL) makeSourceAndHeaderFilesForClass: (NSString*)className
|
||||
withName:(NSString*)sourcePath
|
||||
and:(NSString*)headerPath;
|
||||
|
||||
- (BOOL) parseHeader: (NSString *)headerPath;
|
||||
|
||||
/** loading and saving */
|
||||
- (BOOL) saveToFile: (NSString*)path;
|
||||
- (BOOL) loadFromFile: (NSString*)path;
|
||||
- (BOOL) loadCustomClasses: (NSString*)path;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
|
|
@ -31,14 +31,53 @@
|
|||
#include <InterfaceBuilder/IBEditors.h>
|
||||
#include <InterfaceBuilder/IBPalette.h>
|
||||
|
||||
@interface GormClassManager (Private)
|
||||
/** Private methods not accesible from outside */
|
||||
@interface GormClassManager (Private)
|
||||
- (NSMutableDictionary*) classInfoForClassName: (NSString*)className;
|
||||
- (NSMutableDictionary*) classInfoForObject: (id)anObject;
|
||||
- (void) touch;
|
||||
- (void) convertDictionary: (NSMutableDictionary *)dict;
|
||||
@end
|
||||
|
||||
@implementation GormClassManager
|
||||
|
||||
- (void) _touch
|
||||
- (id) initWithDocument: (id)aDocument
|
||||
{
|
||||
self = [super init];
|
||||
if (self != nil)
|
||||
{
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
NSString *path;
|
||||
|
||||
document = aDocument; // the document retains us, this is for convenience
|
||||
|
||||
path = [bundle pathForResource: @"ClassInformation" ofType: @"plist"];
|
||||
if (path == nil)
|
||||
{
|
||||
NSLog(@"ClassInformation.plist missing from resources");
|
||||
}
|
||||
else
|
||||
{
|
||||
GormPalettesManager *palettesManager = [(Gorm *)NSApp palettesManager];
|
||||
|
||||
// load the classes, initialize the custom class array and map..
|
||||
[self loadFromFile: path];
|
||||
customClasses = [[NSMutableArray alloc] initWithCapacity: 1];
|
||||
customClassMap = [[NSMutableDictionary alloc] initWithCapacity: 10];
|
||||
categoryClasses = [[NSMutableArray alloc] initWithCapacity: 1];
|
||||
|
||||
// add first responder so that it may be edited.
|
||||
[customClasses addObject: @"FirstResponder"];
|
||||
|
||||
// add the imported classes to the class information list...
|
||||
[classInformation addEntriesFromDictionary: [palettesManager importedClasses]];
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) touch
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
postNotificationName: GormDidModifyClassNotification
|
||||
|
@ -46,6 +85,12 @@
|
|||
[document touch];
|
||||
}
|
||||
|
||||
- (void) convertDictionary: (NSMutableDictionary *)dict
|
||||
{
|
||||
NSMutableArray *array = [classInformation allKeys];
|
||||
[dict removeObjectsForKeys: array];
|
||||
}
|
||||
|
||||
- (NSString*) addClassWithSuperClassName: (NSString*)name
|
||||
{
|
||||
if ([name isEqualToString: @"NSObject"]
|
||||
|
@ -76,7 +121,7 @@
|
|||
[classInformation setObject: classInfo forKey: newClassName];
|
||||
[customClasses addObject: newClassName];
|
||||
|
||||
[self _touch];
|
||||
[self touch];
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
postNotificationName: GormDidAddClassNotification
|
||||
|
@ -163,7 +208,7 @@
|
|||
NSEnumerator *e = [actions objectEnumerator];
|
||||
id action = nil;
|
||||
|
||||
[self _touch];
|
||||
[self touch];
|
||||
classInfo = [[NSMutableDictionary alloc] initWithCapacity: 3];
|
||||
|
||||
[classInfo setObject: outlets forKey: @"Outlets"];
|
||||
|
@ -232,10 +277,7 @@
|
|||
[[info objectForKey: @"AllActions"] insertObject: anAction atIndex: 0];
|
||||
if(![className isEqualToString: @"FirstResponder"])
|
||||
{
|
||||
// if([self isSuperclass: @"NSResponder" linkedToClass: className])
|
||||
{
|
||||
[self addAction: anAction forClassNamed: @"FirstResponder"];
|
||||
}
|
||||
[self addAction: anAction forClassNamed: @"FirstResponder"];
|
||||
}
|
||||
|
||||
while((subclassName = [en nextObject]) != nil)
|
||||
|
@ -243,7 +285,7 @@
|
|||
[self addAction: anAction forClassNamed: subclassName];
|
||||
}
|
||||
|
||||
[self _touch];
|
||||
[self touch];
|
||||
}
|
||||
|
||||
- (void) addOutlet: (NSString*)outlet forObject: (id)anObject
|
||||
|
@ -279,7 +321,7 @@
|
|||
[self addOutlet: outlet forClassNamed: subclassName];
|
||||
}
|
||||
|
||||
[self _touch];
|
||||
[self touch];
|
||||
}
|
||||
|
||||
- (void) replaceAction: (NSString *)oldAction
|
||||
|
@ -317,7 +359,7 @@
|
|||
[allActions replaceObjectAtIndex: all_index withObject: newAction];
|
||||
}
|
||||
|
||||
[self _touch];
|
||||
[self touch];
|
||||
|
||||
// add the action to all of the subclasses, in the "AllActions" section...
|
||||
while((subclassName = [en nextObject]) != nil)
|
||||
|
@ -327,10 +369,7 @@
|
|||
|
||||
if(![className isEqualToString: @"FirstResponder"])
|
||||
{
|
||||
// if([self isSuperclass: @"NSResponder" linkedToClass: className])
|
||||
{
|
||||
[self replaceAction: oldAction withAction: newAction forClassNamed: @"FirstResponder"];
|
||||
}
|
||||
[self replaceAction: oldAction withAction: newAction forClassNamed: @"FirstResponder"];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -369,7 +408,7 @@
|
|||
[allOutlets replaceObjectAtIndex: all_index withObject: newOutlet];
|
||||
}
|
||||
|
||||
[self _touch];
|
||||
[self touch];
|
||||
|
||||
// add the action to all of the subclasses, in the "AllActions" section...
|
||||
while((subclassName = [en nextObject]) != nil)
|
||||
|
@ -416,15 +455,12 @@
|
|||
}
|
||||
}
|
||||
[extraActions removeObject: anAction];
|
||||
[self _touch];
|
||||
[self touch];
|
||||
}
|
||||
|
||||
if(![className isEqualToString: @"FirstResponder"])
|
||||
{
|
||||
// if([self isSuperclass: @"NSResponder" linkedToClass: className])
|
||||
{
|
||||
[self removeAction: anAction fromClassNamed: @"FirstResponder"];
|
||||
}
|
||||
[self removeAction: anAction fromClassNamed: @"FirstResponder"];
|
||||
}
|
||||
|
||||
while((subclassName = [en nextObject]) != nil)
|
||||
|
@ -466,7 +502,7 @@
|
|||
}
|
||||
}
|
||||
[extraOutlets removeObject: anOutlet];
|
||||
[self _touch];
|
||||
[self touch];
|
||||
}
|
||||
|
||||
while((subclassName = [en nextObject]) != nil)
|
||||
|
@ -825,41 +861,6 @@
|
|||
return [info objectForKey: @"ExtraOutlets"];
|
||||
}
|
||||
|
||||
- (id) initWithDocument: (id)aDocument
|
||||
{
|
||||
self = [super init];
|
||||
if (self != nil)
|
||||
{
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
NSString *path;
|
||||
|
||||
document = aDocument; // the document retains us, this is for convenience
|
||||
|
||||
path = [bundle pathForResource: @"ClassInformation" ofType: @"plist"];
|
||||
if (path == nil)
|
||||
{
|
||||
NSLog(@"ClassInformation.plist missing from resources");
|
||||
}
|
||||
else
|
||||
{
|
||||
GormPalettesManager *palettesManager = [(Gorm *)NSApp palettesManager];
|
||||
|
||||
// load the classes, initialize the custom class array and map..
|
||||
[self loadFromFile: path];
|
||||
customClasses = [[NSMutableArray alloc] initWithCapacity: 1];
|
||||
customClassMap = [[NSMutableDictionary alloc] initWithCapacity: 10];
|
||||
|
||||
// add first responder so that it may be edited.
|
||||
[customClasses addObject: @"FirstResponder"];
|
||||
|
||||
// add the imported classes to the class information list...
|
||||
[classInformation addEntriesFromDictionary: [palettesManager importedClasses]];
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) allSubclassesOf: (NSString *)superclass
|
||||
referenceClassList: (NSArray *)classList
|
||||
intoArray: (NSMutableArray *)array
|
||||
|
@ -982,7 +983,7 @@
|
|||
}
|
||||
|
||||
[classInformation removeObjectForKey: className];
|
||||
[self _touch];
|
||||
[self touch];
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
postNotificationName: GormDidDeleteClassNotification
|
||||
|
@ -1042,7 +1043,7 @@
|
|||
forClassNamed: sc];
|
||||
}
|
||||
|
||||
[self _touch];
|
||||
[self touch];
|
||||
}
|
||||
else
|
||||
NSLog(@"customClass not found %@",oldName);
|
||||
|
@ -1063,8 +1064,10 @@
|
|||
{
|
||||
NSMutableDictionary *ci;
|
||||
NSEnumerator *enumerator;
|
||||
id key;
|
||||
|
||||
id key;
|
||||
NSMutableArray *classesToSave;
|
||||
|
||||
classesToSave = [customClasses arrayByAddingObjectsFromArray: categoryClasses];
|
||||
ci = AUTORELEASE([[NSMutableDictionary alloc] initWithCapacity: 0]);
|
||||
enumerator = [customClasses objectEnumerator];
|
||||
while ((key = [enumerator nextObject]) != nil)
|
||||
|
@ -1074,6 +1077,7 @@
|
|||
id obj;
|
||||
id extraObj;
|
||||
|
||||
// superclass...
|
||||
classInfo = [classInformation objectForKey: key];
|
||||
newInfo = [NSMutableDictionary new];
|
||||
[ci setObject: newInfo forKey: key];
|
||||
|
@ -1083,6 +1087,8 @@
|
|||
{
|
||||
[newInfo setObject: obj forKey: @"Super"];
|
||||
}
|
||||
|
||||
// outlets...
|
||||
obj = [classInfo objectForKey: @"Outlets"];
|
||||
extraObj = [classInfo objectForKey: @"ExtraOutlets"];
|
||||
if (obj && extraObj)
|
||||
|
@ -1097,6 +1103,8 @@
|
|||
{
|
||||
[newInfo setObject: obj forKey: @"Outlets"];
|
||||
}
|
||||
|
||||
// actions...
|
||||
obj = [classInfo objectForKey: @"Actions"];
|
||||
extraObj = [classInfo objectForKey: @"ExtraActions"];
|
||||
if (obj && extraObj)
|
||||
|
@ -1125,31 +1133,31 @@
|
|||
NSDebugLog(@"Load from file %@",path);
|
||||
|
||||
dict = [NSDictionary dictionaryWithContentsOfFile: path];
|
||||
// customClasses = [NSMutableArray arrayWithCapacity: 1];
|
||||
if (dict == nil)
|
||||
{
|
||||
NSLog(@"Could not load classes dictionary");
|
||||
return NO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert property-list data into a mutable structure.
|
||||
*/
|
||||
RELEASE(classInformation);
|
||||
classInformation = [NSMutableDictionary new];
|
||||
RETAIN(classInformation); // released in dealloc...
|
||||
classInformation = [[NSMutableDictionary alloc] init];
|
||||
enumerator = [dict keyEnumerator];
|
||||
while ((key = [enumerator nextObject]) != nil)
|
||||
{
|
||||
NSDictionary *classInfo = [dict objectForKey: key];
|
||||
NSMutableDictionary *newInfo;
|
||||
NSMutableDictionary *oldInfo;
|
||||
id obj;
|
||||
|
||||
NSDictionary *classInfo = [dict objectForKey: key];
|
||||
NSMutableDictionary *newInfo;
|
||||
NSMutableDictionary *oldInfo;
|
||||
id obj;
|
||||
|
||||
newInfo = [NSMutableDictionary new];
|
||||
oldInfo = [classInformation objectForKey: key];
|
||||
|
||||
|
||||
[classInformation setObject: newInfo forKey: key];
|
||||
|
||||
// superclass
|
||||
obj = [classInfo objectForKey: @"Super"];
|
||||
if (obj != nil)
|
||||
{
|
||||
|
@ -1163,8 +1171,9 @@
|
|||
obj = [obj mutableCopy];
|
||||
[obj sortUsingSelector: @selector(compare:)];
|
||||
[newInfo setObject: obj forKey: @"Outlets"];
|
||||
RELEASE(obj);
|
||||
}
|
||||
|
||||
|
||||
// actions
|
||||
obj = [classInfo objectForKey: @"Actions"];
|
||||
if (obj != nil)
|
||||
|
@ -1172,22 +1181,19 @@
|
|||
obj = [obj mutableCopy];
|
||||
[obj sortUsingSelector: @selector(compare:)];
|
||||
[newInfo setObject: obj forKey: @"Actions"];
|
||||
RELEASE(obj);
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) _convertDictionary: (NSMutableDictionary *)dict
|
||||
{
|
||||
NSMutableArray *array = [classInformation allKeys];
|
||||
[dict removeObjectsForKeys: array];
|
||||
}
|
||||
|
||||
// this method will load the custom classes and merge them with the
|
||||
// Class information loaded at initialization time.
|
||||
- (BOOL) loadCustomClasses: (NSString *)path
|
||||
{
|
||||
NSMutableDictionary *dict;
|
||||
NSEnumerator *en;
|
||||
id obj;
|
||||
|
||||
NSDebugLog(@"Load custom classes from file %@",path);
|
||||
|
||||
|
@ -1207,7 +1213,7 @@
|
|||
if ([[dict allKeys] containsObject: @"NSObject"])
|
||||
{
|
||||
NSLog(@"The file being loaded is in the old .classes format. Updating..");
|
||||
[self _convertDictionary: dict];
|
||||
[self convertDictionary: dict];
|
||||
}
|
||||
|
||||
[customClasses addObjectsFromArray: [dict allKeys]];
|
||||
|
@ -1218,8 +1224,17 @@
|
|||
|
||||
- (BOOL) isCustomClass: (NSString *)className
|
||||
{
|
||||
return ([customClasses indexOfObject: className] != NSNotFound); // &&
|
||||
// ![className isEqualToString: @"FirstResponder"]);
|
||||
return ([customClasses indexOfObject: className] != NSNotFound);
|
||||
}
|
||||
|
||||
- (BOOL) isNonCustomClass: (NSString *)className
|
||||
{
|
||||
return !([self isCustomClass: className]);
|
||||
}
|
||||
|
||||
- (BOOL) isCategoryForClass: (NSString *)className
|
||||
{
|
||||
return ([categoryClasses indexOfObject: className] != NSNotFound);
|
||||
}
|
||||
|
||||
- (BOOL) isKnownClass: (NSString *)className
|
||||
|
@ -1445,7 +1460,6 @@
|
|||
{
|
||||
NSString *name = [document nameForObject: object];
|
||||
NSString *result = [self customClassForName: name];
|
||||
// NSString *result = [customClassMap objectForKey: name];
|
||||
NSDebugLog(@"in customClassForObject: object = %@, name = %@, result = %@, customClassMap = %@",
|
||||
object, name, result, customClassMap);
|
||||
return result;
|
||||
|
|
Loading…
Reference in a new issue