mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-23 20:01:11 +00:00
New .gorm version updates.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@19649 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
e87ca75d37
commit
95a20b1b16
5 changed files with 206 additions and 174 deletions
22
ChangeLog
22
ChangeLog
|
@ -1,3 +1,25 @@
|
|||
2004-06-28 Gregory John Casamento <greg_casamento@yahoo.com>
|
||||
|
||||
* Headers/Additions/GNUstepGUI/GSNibTemplates.h: Updated the
|
||||
GNUSTEP_NIB_VERSION. This constant defines the number used for
|
||||
the GSNibContainer objects' version. Also added a new topLevelObjects
|
||||
ivar to the GSNibContainer class and the method to retrieve it.
|
||||
* Source/GSNibTemplates.m: Move the private class GSNibItemCollector
|
||||
from NSBundleAdditions.m to GSNibTemplates.m. This helped clean up
|
||||
code and also facilitated the changes necessary for the new .gorm version.
|
||||
Also changed the signature of awakeWithContext: so it only takes the context
|
||||
dictionary as an argument and no longer requires the items to be passed in.
|
||||
Changed the awakeWithContext method to efficiently retain the objects.
|
||||
In initWithCoder: and encodeWithCoder: added new section for updated
|
||||
version. Added some logic to collect the top level items at that time
|
||||
so that version 0 and version 1 .gorm files load in a precisely equivalent
|
||||
manner. Also, updated a change made by Alex Malmberg which was causing
|
||||
the designated initializers to not be called.
|
||||
* Source/NSBundleAdditions.m: Moved class to GSNibTemplates as described
|
||||
above. Cleaned up implementation of +loadNibNamed:context:.
|
||||
* Source/NSNib.m: Removed some of the code which was there to collect top level
|
||||
items. Also cleaned up some of the code with the new implementation.
|
||||
|
||||
2004-06-28 Serg Stoyan <stoyan255@ukr.net>
|
||||
|
||||
* Headers/AppKit/NSScroller.h: Added _pendingKnobProportion ivar.
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include <AppKit/NSControl.h>
|
||||
|
||||
// versions of the nib container and the templates.
|
||||
#define GNUSTEP_NIB_VERSION 0
|
||||
#define GNUSTEP_NIB_VERSION 1
|
||||
#define GSSWAPPER_VERSION 0
|
||||
#define GSWINDOWT_VERSION 0
|
||||
#define GSVIEWT_VERSION 0
|
||||
|
@ -48,6 +48,7 @@
|
|||
@class NSString;
|
||||
@class NSDictionary;
|
||||
@class NSMutableDictionary;
|
||||
@class NSMutableSet;
|
||||
|
||||
/*
|
||||
* This is the class that holds objects within a nib.
|
||||
|
@ -56,11 +57,13 @@
|
|||
{
|
||||
NSMutableDictionary *nameTable;
|
||||
NSMutableArray *connections;
|
||||
BOOL _isAwake;
|
||||
NSMutableSet *topLevelObjects;
|
||||
BOOL isAwake;
|
||||
}
|
||||
- (void) awakeWithContext: (NSDictionary *)context topLevelItems: (NSArray *)items;
|
||||
- (void) awakeWithContext: (NSDictionary *)context;
|
||||
- (NSMutableDictionary*) nameTable;
|
||||
- (NSMutableArray*) connections;
|
||||
- (NSMutableSet*) topLevelObjects;
|
||||
@end
|
||||
|
||||
/*
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <Foundation/NSKeyValueCoding.h>
|
||||
#include <Foundation/NSNotification.h>
|
||||
#include <Foundation/NSArchiver.h>
|
||||
#include <Foundation/NSSet.h>
|
||||
#include <AppKit/NSMenu.h>
|
||||
#include <AppKit/NSView.h>
|
||||
#include <AppKit/NSTextView.h>
|
||||
|
@ -70,6 +71,68 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
}
|
||||
@end
|
||||
|
||||
/*
|
||||
* This private class is used to collect the nib items while the
|
||||
* .gorm file is being unarchived. This is done to allow only
|
||||
* the top level items to be retained in a clean way. The reason it's
|
||||
* being done this way is because old .gorm files don't have any
|
||||
* array within the nameTable which indicates the objects which are
|
||||
* considered top level, so there is no clean and generic way to determine
|
||||
* this. Basically the top level items are any instances of or instances
|
||||
* of subclasses of NSMenu, NSWindow, or any controller class.
|
||||
* It's the last one that's hairy. Controller classes are
|
||||
* represented in .gorm files by the GSNibItem class, but once they transform
|
||||
* into the actual class instance it's not easy to tell if it should be
|
||||
* retained or not since there are a lot of other things stored in the nameTable
|
||||
* as well. GJC
|
||||
*/
|
||||
|
||||
static NSString *GSInternalNibItemAddedNotification = @"_GSInternalNibItemAddedNotification";
|
||||
|
||||
@interface GSNibItemCollector : NSObject
|
||||
{
|
||||
NSMutableArray *items;
|
||||
}
|
||||
- (void) handleNotification: (NSNotification *)notification;
|
||||
- (NSMutableArray *)items;
|
||||
@end
|
||||
|
||||
@implementation GSNibItemCollector
|
||||
- (void) handleNotification: (NSNotification *)notification;
|
||||
{
|
||||
id obj = [notification object];
|
||||
[items addObject: obj];
|
||||
}
|
||||
|
||||
- init
|
||||
{
|
||||
if((self = [super init]) != nil)
|
||||
{
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
|
||||
// add myself as an observer and initialize the items array.
|
||||
[nc addObserver: self
|
||||
selector: @selector(handleNotification:)
|
||||
name: GSInternalNibItemAddedNotification
|
||||
object: nil];
|
||||
items = [[NSMutableArray alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver: self];
|
||||
RELEASE(items);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSMutableArray *)items
|
||||
{
|
||||
return items;
|
||||
}
|
||||
@end
|
||||
|
||||
/*
|
||||
* The GSNibContainer class manages the internals of a nib file.
|
||||
*/
|
||||
|
@ -84,19 +147,18 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
}
|
||||
|
||||
- (void) awakeWithContext: (NSDictionary *)context
|
||||
topLevelItems: (NSArray *)items
|
||||
{
|
||||
if (_isAwake == NO)
|
||||
if (isAwake == NO)
|
||||
{
|
||||
NSEnumerator *enumerator;
|
||||
NSNibConnector *connection;
|
||||
NSString *key;
|
||||
NSArray *visible;
|
||||
NSMenu *menu;
|
||||
NSMutableArray *topLevelObjects;
|
||||
NSMutableArray *topObjects;
|
||||
id obj;
|
||||
|
||||
_isAwake = YES;
|
||||
isAwake = YES;
|
||||
/*
|
||||
* Add local entries into name table.
|
||||
*/
|
||||
|
@ -153,6 +215,24 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
[NSApp setWindowsMenu: menu];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* See if the user has passed in the NSTopLevelObjects key.
|
||||
* This is an implementation of an undocumented, but commonly used feature
|
||||
* of nib files to allow the release of the top level objects in the nib
|
||||
* file.
|
||||
*/
|
||||
obj = [context objectForKey: @"NSTopLevelObjects"];
|
||||
if([obj isKindOfClass: [NSMutableArray class]])
|
||||
{
|
||||
topObjects = obj;
|
||||
}
|
||||
else
|
||||
{
|
||||
topObjects = nil;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Now tell all the objects that they have been loaded from
|
||||
* a nib.
|
||||
|
@ -168,76 +248,49 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
[key isEqualToString: @"NSVisible"] == NO && // also exclude any other special parts of the nameTable.
|
||||
[key isEqualToString: @"NSDeferred"] == NO &&
|
||||
[key isEqualToString: @"NSTopLevelObjects"] == NO &&
|
||||
[key isEqualToString: @"GSCustomClassMap"] == NO)
|
||||
[key isEqualToString: @"GSCustomClassMap"] == NO)
|
||||
{
|
||||
id o = [nameTable objectForKey: key];
|
||||
|
||||
// send the awake message, if it responds...
|
||||
if ([o respondsToSelector: @selector(awakeFromNib)])
|
||||
{
|
||||
[o awakeFromNib];
|
||||
}
|
||||
|
||||
/*
|
||||
* Retain all "top level" items so that, when the container is released, they will remain.
|
||||
* The GSNibItems instantiated in the gorm need to be retained,
|
||||
* since we are deallocating the container. We don't want to retain the owner.
|
||||
*/
|
||||
if([key isEqualToString: @"NSOwner"] == NO)
|
||||
{
|
||||
if([topLevelObjects containsObject: o]) // anything already designated a top level item..
|
||||
{
|
||||
if(topObjects == nil)
|
||||
{
|
||||
// It is expected, if the NSTopLevelObjects key is not passed in,
|
||||
// that the user has opted to either allow these objects to leak or
|
||||
// to release them explicitly.
|
||||
RETAIN(o);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We don't want to do the extra retain if the items are added to the
|
||||
// array, since the array will do the retain for us. When the array
|
||||
// is released, the top level objects should be released as well.
|
||||
[topObjects addObject: o];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* See if the user has passed in the NSTopLevelObjects key.
|
||||
* This is an implementation of an undocumented, but commonly used feature
|
||||
* of nib files to allow the release of the top level objects in the nib
|
||||
* file.
|
||||
*/
|
||||
obj = [context objectForKey: @"NSTopLevelObjects"];
|
||||
if([obj isKindOfClass: [NSMutableArray class]])
|
||||
{
|
||||
topLevelObjects = obj;
|
||||
}
|
||||
else
|
||||
{
|
||||
topLevelObjects = nil;
|
||||
}
|
||||
|
||||
/*
|
||||
* Retain all "top level" items so that, when the container is released, they will remain.
|
||||
* The GSNibItems instantiated in the gorm need to be retained,
|
||||
* since we are deallocating the container.
|
||||
*/
|
||||
enumerator = [nameTable keyEnumerator];
|
||||
while ((key = [enumerator nextObject]) != nil)
|
||||
{
|
||||
if ([context objectForKey: key] == nil &&
|
||||
[key isEqualToString: @"NSWindowsMenu"] == NO && // exclude special sections.
|
||||
[key isEqualToString: @"NSServicesMenu"] == NO &&
|
||||
[key isEqualToString: @"NSVisible"] == NO &&
|
||||
[key isEqualToString: @"NSDeferred"] == NO &&
|
||||
[key isEqualToString: @"NSTopLevelObjects"] == NO &&
|
||||
[key isEqualToString: @"GSCustomClassMap"] == NO)
|
||||
{
|
||||
id o = [nameTable objectForKey: key];
|
||||
// RETAIN all top-level items...
|
||||
if (([o isKindOfClass: [NSMenu class]] == YES &&
|
||||
[key isEqualToString: @"NSMenu"] == YES) || // the main menu...
|
||||
([o isKindOfClass: [NSWindow class]] == YES) || // any windows...
|
||||
([items containsObject: o] == YES))
|
||||
{
|
||||
if(topLevelObjects == nil)
|
||||
{
|
||||
// It is expected, if the NSTopLevelObjects key is not passed in,
|
||||
// that the user has opted to either allow these objects to leak or
|
||||
// to release them explicitly.
|
||||
RETAIN(o);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We don't want to do the extra retain if the items are added to the
|
||||
// array, since the array will do the retain for us. When the array
|
||||
// is released, the top level objects should be released as well.
|
||||
[topLevelObjects addObject: o];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* See if there are objects that should be made visible.
|
||||
* This is the last thing we should do since changes might be made
|
||||
* in the awakeFromNib methods which are called on all of the objects.
|
||||
*/
|
||||
visible = [nameTable objectForKey: @"NSVisible"];
|
||||
if (visible != nil
|
||||
|
@ -274,6 +327,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
{
|
||||
RELEASE(nameTable);
|
||||
RELEASE(connections);
|
||||
RELEASE(topLevelObjects);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -281,6 +335,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
{
|
||||
[aCoder encodeObject: nameTable];
|
||||
[aCoder encodeObject: connections];
|
||||
[aCoder encodeObject: topLevelObjects];
|
||||
}
|
||||
|
||||
- (id) init
|
||||
|
@ -289,6 +344,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
{
|
||||
nameTable = [[NSMutableDictionary alloc] initWithCapacity: 8];
|
||||
connections = [[NSMutableArray alloc] initWithCapacity: 8];
|
||||
topLevelObjects = [[NSMutableSet alloc] initWithCapacity: 8];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
@ -296,11 +352,45 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
- (id) initWithCoder: (NSCoder*)aCoder
|
||||
{
|
||||
int version = [aCoder versionForClassName: @"GSNibContainer"];
|
||||
|
||||
|
||||
// save the version to the ivar, we need it later.
|
||||
if(version == GNUSTEP_NIB_VERSION)
|
||||
{
|
||||
[aCoder decodeValueOfObjCType: @encode(id) at: &nameTable];
|
||||
[aCoder decodeValueOfObjCType: @encode(id) at: &connections];
|
||||
[aCoder decodeValueOfObjCType: @encode(id) at: &topLevelObjects];
|
||||
}
|
||||
else if(version == 0)
|
||||
{
|
||||
GSNibItemCollector *nibitems = [[GSNibItemCollector alloc] init];
|
||||
NSEnumerator *en;
|
||||
NSString *key;
|
||||
|
||||
// initialize the set of top level objects...
|
||||
topLevelObjects = [[NSMutableSet alloc] initWithCapacity: 8];
|
||||
|
||||
// unarchive...
|
||||
[aCoder decodeValueOfObjCType: @encode(id) at: &nameTable];
|
||||
[aCoder decodeValueOfObjCType: @encode(id) at: &connections];
|
||||
[topLevelObjects addObjectsFromArray: [nibitems items]]; // get the top level items here...
|
||||
RELEASE(nibitems);
|
||||
|
||||
// iterate through the objects returned
|
||||
en = [nameTable keyEnumerator];
|
||||
while((key = [en nextObject]) != nil)
|
||||
{
|
||||
id o = [nameTable objectForKey: key];
|
||||
if(([o isKindOfClass: [NSMenu class]] && [key isEqual: @"NSMenu"]) ||
|
||||
[o isKindOfClass: [NSWindow class]])
|
||||
{
|
||||
[topLevelObjects addObject: o]; // if it's a top level object, add it.
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[NSException raise: NSInternalInconsistencyException
|
||||
format: @"Unable to read GSNibContainer version #%d. GSNibContainer version for the installed gui lib is %d.", version, GNUSTEP_NIB_VERSION];
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -310,6 +400,11 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
{
|
||||
return nameTable;
|
||||
}
|
||||
|
||||
- (NSMutableSet*) topLevelObjects
|
||||
{
|
||||
return topLevelObjects;
|
||||
}
|
||||
@end
|
||||
|
||||
// The first standin objects here are for views and normal objects like controllers
|
||||
|
@ -357,7 +452,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
if (cls == nil)
|
||||
{
|
||||
[NSException raise: NSInternalInconsistencyException
|
||||
format: @"Unable to find class '%@'", theClass];
|
||||
format: @"Unable to find class '%@', it is not linked into the application.", theClass];
|
||||
}
|
||||
|
||||
obj = [cls allocWithZone: [self zone]];
|
||||
|
@ -386,7 +481,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
if (cls == nil)
|
||||
{
|
||||
[NSException raise: NSInternalInconsistencyException
|
||||
format: @"Unable to find class '%@'", theClass];
|
||||
format: @"Unable to find class '%@', it is not linked into the application.", theClass];
|
||||
}
|
||||
|
||||
obj = [cls allocWithZone: [self zone]];
|
||||
|
@ -405,14 +500,16 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
}
|
||||
|
||||
// If this is a nib item and not a custom view, then we need to add it to
|
||||
// the set of things to be retained.
|
||||
if(obj != nil)
|
||||
// the set of things to be retained. Also, the initial version of the nib container
|
||||
// needed this code, but subsequent versions don't, so don't send the notification,
|
||||
// if the version isn't zero.
|
||||
if(obj != nil && [aCoder versionForClassName: NSStringFromClass([GSNibContainer class])] == 0)
|
||||
{
|
||||
if([self isKindOfClass: [GSNibItem class]] == YES &&
|
||||
[self isKindOfClass: [GSCustomView class]] == NO)
|
||||
{
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
[nc postNotificationName: @"__GSInternalNibItemAddedNotification"
|
||||
[nc postNotificationName: GSInternalNibItemAddedNotification
|
||||
object: obj];
|
||||
}
|
||||
}
|
||||
|
@ -485,7 +582,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
if(_superClass == nil)
|
||||
{
|
||||
[NSException raise: NSInternalInconsistencyException
|
||||
format: @"Unable to find class '%@'", superClassName];
|
||||
format: @"Unable to find class '%@', it is not linked into the application.", superClassName];
|
||||
}
|
||||
}
|
||||
return self;
|
||||
|
@ -538,7 +635,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
if(aClass == 0)
|
||||
{
|
||||
[NSException raise: NSInternalInconsistencyException
|
||||
format: @"Unable to find class '%@'", _className];
|
||||
format: @"Unable to find class '%@', it is not linked into the application.", _className];
|
||||
}
|
||||
|
||||
// Initialize the object... dont call decode, since this wont
|
||||
|
@ -606,7 +703,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
|
||||
if(![self respondsToSelector: @selector(isInInterfaceBuilder)])
|
||||
{
|
||||
if(GSGetMethod([obj class], @selector(initWithContentRect:styleMask:backing:defer:), NO, NO) != NULL)
|
||||
if(GSGetMethod([obj class], @selector(initWithContentRect:styleMask:backing:defer:), YES, NO) != NULL)
|
||||
{
|
||||
// if we are not in interface builder, call
|
||||
// designated initializer per spec...
|
||||
|
@ -648,7 +745,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
{
|
||||
if(![self respondsToSelector: @selector(isInInterfaceBuilder)])
|
||||
{
|
||||
if(GSGetMethod([obj class],@selector(initWithFrame:), NO, NO) != NULL)
|
||||
if(GSGetMethod([obj class],@selector(initWithFrame:), YES, NO) != NULL)
|
||||
{
|
||||
NSRect theFrame = [obj frame];
|
||||
obj = [obj initWithFrame: theFrame];
|
||||
|
@ -677,7 +774,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
{
|
||||
if(![self respondsToSelector: @selector(isInInterfaceBuilder)])
|
||||
{
|
||||
if(GSGetMethod([obj class],@selector(initWithFrame:), NO, NO) != NULL)
|
||||
if(GSGetMethod([obj class],@selector(initWithFrame:), YES, NO) != NULL)
|
||||
{
|
||||
NSRect theFrame = [obj frame];
|
||||
obj = [obj initWithFrame: theFrame];
|
||||
|
@ -706,7 +803,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
{
|
||||
if(![self respondsToSelector: @selector(isInInterfaceBuilder)])
|
||||
{
|
||||
if(GSGetMethod([obj class],@selector(initWithFrame:textContainer:), NO, NO) != NULL)
|
||||
if(GSGetMethod([obj class],@selector(initWithFrame:textContainer:), YES, NO) != NULL)
|
||||
{
|
||||
NSRect theFrame = [obj frame];
|
||||
id textContainer = [obj textContainer];
|
||||
|
@ -737,7 +834,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
{
|
||||
if(![self respondsToSelector: @selector(isInInterfaceBuilder)])
|
||||
{
|
||||
if(GSGetMethod([obj class],@selector(initWithTitle:), NO, NO) != NULL)
|
||||
if(GSGetMethod([obj class],@selector(initWithTitle:), YES, NO) != NULL)
|
||||
{
|
||||
NSString *theTitle = [obj title];
|
||||
obj = [obj initWithTitle: theTitle];
|
||||
|
@ -768,7 +865,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
/*
|
||||
if(![self respondsToSelector: @selector(isInInterfaceBuilder)])
|
||||
{
|
||||
if(GSGetMethod([obj class],@selector(initWithFrame:), NO, NO) != NULL)
|
||||
if(GSGetMethod([obj class],@selector(initWithFrame:), YES, NO) != NULL)
|
||||
{
|
||||
NSRect theFrame = [obj frame];
|
||||
obj = [obj initWithFrame: theFrame];
|
||||
|
@ -797,7 +894,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
|||
{
|
||||
if(![self respondsToSelector: @selector(isInInterfaceBuilder)])
|
||||
{
|
||||
if(GSGetMethod([obj class],@selector(init), NO, NO) != NULL)
|
||||
if(GSGetMethod([obj class],@selector(init), YES, NO) != NULL)
|
||||
{
|
||||
obj = [self init];
|
||||
}
|
||||
|
|
|
@ -185,66 +185,6 @@
|
|||
}
|
||||
@end
|
||||
|
||||
/*
|
||||
* This private class is used to collect the nib items while the
|
||||
* .gorm file is being unarchived. This is done to allow only
|
||||
* the top level items to be retained in a clean way. The reason it's
|
||||
* being done this way is because old .gorm files don't have any
|
||||
* array within the nameTable which indicates the objects which are
|
||||
* considered top level, so there is no clean and generic way to determine
|
||||
* this. Basically the top level items are any instances of or instances
|
||||
* of subclasses of NSMenu, NSWindow, or any controller class.
|
||||
* It's the last one that's hairy. Controller classes are
|
||||
* represented in .gorm files by the GSNibItem class, but once they transform
|
||||
* into the actual class instance it's not easy to tell if it should be
|
||||
* retained or not since there are a lot of other things stored in the nameTable
|
||||
* as well. GJC
|
||||
*/
|
||||
@interface _GSNibItemCollector : NSObject
|
||||
{
|
||||
NSMutableArray *items;
|
||||
}
|
||||
- (void) handleNotification: (NSNotification *)notification;
|
||||
- (NSMutableArray *)items;
|
||||
@end
|
||||
|
||||
@implementation _GSNibItemCollector
|
||||
- (void) handleNotification: (NSNotification *)notification;
|
||||
{
|
||||
id obj = [notification object];
|
||||
[items addObject: obj];
|
||||
}
|
||||
|
||||
- init
|
||||
{
|
||||
if((self = [super init]) != nil)
|
||||
{
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
|
||||
// add myself as an observer and initialize the items array.
|
||||
[nc addObserver: self
|
||||
selector: @selector(handleNotification:)
|
||||
name: @"__GSInternalNibItemAddedNotification"
|
||||
object: nil];
|
||||
items = [[NSMutableArray alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver: self];
|
||||
RELEASE(items);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSMutableArray *)items
|
||||
{
|
||||
return items;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@implementation NSBundle (NSBundleAdditions)
|
||||
|
||||
static
|
||||
|
@ -286,7 +226,6 @@ Class gmodel_class(void)
|
|||
BOOL loaded = NO;
|
||||
NSUnarchiver *unarchiver = nil;
|
||||
NSString *ext = [fileName pathExtension];
|
||||
id nibitems = nil;
|
||||
|
||||
if ([ext isEqual: @"nib"])
|
||||
{
|
||||
|
@ -346,19 +285,15 @@ Class gmodel_class(void)
|
|||
{
|
||||
id obj;
|
||||
|
||||
nibitems = [[_GSNibItemCollector alloc] init];
|
||||
NSDebugLog(@"Invoking unarchiver");
|
||||
[unarchiver setObjectZone: zone];
|
||||
obj = [unarchiver decodeObject];
|
||||
if (obj != nil)
|
||||
{
|
||||
NSArray *items = [nibitems items];
|
||||
if ([obj isKindOfClass: [GSNibContainer class]])
|
||||
{
|
||||
NSDebugLog(@"Calling awakeWithContext");
|
||||
|
||||
[obj awakeWithContext: context
|
||||
topLevelItems: items];
|
||||
[obj awakeWithContext: context];
|
||||
loaded = YES;
|
||||
}
|
||||
else
|
||||
|
@ -366,7 +301,7 @@ Class gmodel_class(void)
|
|||
NSLog(@"Nib '%@' without container object!", fileName);
|
||||
}
|
||||
}
|
||||
RELEASE(nibitems);
|
||||
// RELEASE(nibitems);
|
||||
RELEASE(unarchiver);
|
||||
}
|
||||
}
|
||||
|
@ -375,7 +310,7 @@ Class gmodel_class(void)
|
|||
NS_HANDLER
|
||||
{
|
||||
NSLog(@"Exception occured while loading model: %@",[localException reason]);
|
||||
TEST_RELEASE(nibitems);
|
||||
// TEST_RELEASE(nibitems);
|
||||
TEST_RELEASE(unarchiver);
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
|
|
|
@ -111,25 +111,6 @@
|
|||
NS_ENDHANDLER
|
||||
}
|
||||
|
||||
// handle the notification...
|
||||
- (void) _handleNotification: (NSNotification *)notification
|
||||
{
|
||||
id obj = [notification object];
|
||||
[_topLevelItems addObject: obj];
|
||||
}
|
||||
|
||||
// subscribe to the notification...
|
||||
- (void) _addObserver
|
||||
{
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
|
||||
// add myself as an observer and initialize the items array.
|
||||
[nc addObserver: self
|
||||
selector: @selector(_handleNotification:)
|
||||
name: @"__GSInternalNibItemAddedNotification"
|
||||
object: nil];
|
||||
}
|
||||
|
||||
- (NSDictionary *) _copyTable: (NSDictionary *)dict
|
||||
{
|
||||
NSMutableDictionary *ctx = nil;
|
||||
|
@ -174,7 +155,6 @@
|
|||
{
|
||||
// load the nib data into memory...
|
||||
_nibData = [NSData dataWithContentsOfURL: nibFileURL];
|
||||
[self _addObserver];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
@ -202,7 +182,6 @@
|
|||
|
||||
// load the nib data into memory...
|
||||
[self _readNibData: fileName];
|
||||
[self _addObserver];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
@ -226,7 +205,6 @@
|
|||
{
|
||||
id obj;
|
||||
|
||||
_topLevelItems = [[NSMutableArray alloc] init];
|
||||
[unarchiver setObjectZone: zone];
|
||||
obj = [unarchiver decodeObject];
|
||||
if (obj != nil)
|
||||
|
@ -234,8 +212,7 @@
|
|||
if ([obj isKindOfClass: [GSNibContainer class]])
|
||||
{
|
||||
NSDictionary *nameTable = [self _copyTable: externalNameTable];
|
||||
[obj awakeWithContext: nameTable
|
||||
topLevelItems: _topLevelItems];
|
||||
[obj awakeWithContext: nameTable];
|
||||
loaded = YES;
|
||||
RELEASE(nameTable);
|
||||
}
|
||||
|
@ -245,7 +222,6 @@
|
|||
}
|
||||
}
|
||||
RELEASE(unarchiver);
|
||||
RELEASE(_topLevelItems);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -253,7 +229,6 @@
|
|||
{
|
||||
NSLog(@"Exception occured while loading model: %@",[localException reason]);
|
||||
TEST_RELEASE(unarchiver);
|
||||
TEST_RELEASE(_topLevelItems);
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
|
||||
|
|
Loading…
Reference in a new issue