mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-31 21:50:46 +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
639ed3278c
commit
2b9356b4de
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>
|
2004-06-28 Serg Stoyan <stoyan255@ukr.net>
|
||||||
|
|
||||||
* Headers/AppKit/NSScroller.h: Added _pendingKnobProportion ivar.
|
* Headers/AppKit/NSScroller.h: Added _pendingKnobProportion ivar.
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include <AppKit/NSControl.h>
|
#include <AppKit/NSControl.h>
|
||||||
|
|
||||||
// versions of the nib container and the templates.
|
// versions of the nib container and the templates.
|
||||||
#define GNUSTEP_NIB_VERSION 0
|
#define GNUSTEP_NIB_VERSION 1
|
||||||
#define GSSWAPPER_VERSION 0
|
#define GSSWAPPER_VERSION 0
|
||||||
#define GSWINDOWT_VERSION 0
|
#define GSWINDOWT_VERSION 0
|
||||||
#define GSVIEWT_VERSION 0
|
#define GSVIEWT_VERSION 0
|
||||||
|
@ -48,6 +48,7 @@
|
||||||
@class NSString;
|
@class NSString;
|
||||||
@class NSDictionary;
|
@class NSDictionary;
|
||||||
@class NSMutableDictionary;
|
@class NSMutableDictionary;
|
||||||
|
@class NSMutableSet;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the class that holds objects within a nib.
|
* This is the class that holds objects within a nib.
|
||||||
|
@ -56,11 +57,13 @@
|
||||||
{
|
{
|
||||||
NSMutableDictionary *nameTable;
|
NSMutableDictionary *nameTable;
|
||||||
NSMutableArray *connections;
|
NSMutableArray *connections;
|
||||||
BOOL _isAwake;
|
NSMutableSet *topLevelObjects;
|
||||||
|
BOOL isAwake;
|
||||||
}
|
}
|
||||||
- (void) awakeWithContext: (NSDictionary *)context topLevelItems: (NSArray *)items;
|
- (void) awakeWithContext: (NSDictionary *)context;
|
||||||
- (NSMutableDictionary*) nameTable;
|
- (NSMutableDictionary*) nameTable;
|
||||||
- (NSMutableArray*) connections;
|
- (NSMutableArray*) connections;
|
||||||
|
- (NSMutableSet*) topLevelObjects;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include <Foundation/NSKeyValueCoding.h>
|
#include <Foundation/NSKeyValueCoding.h>
|
||||||
#include <Foundation/NSNotification.h>
|
#include <Foundation/NSNotification.h>
|
||||||
#include <Foundation/NSArchiver.h>
|
#include <Foundation/NSArchiver.h>
|
||||||
|
#include <Foundation/NSSet.h>
|
||||||
#include <AppKit/NSMenu.h>
|
#include <AppKit/NSMenu.h>
|
||||||
#include <AppKit/NSView.h>
|
#include <AppKit/NSView.h>
|
||||||
#include <AppKit/NSTextView.h>
|
#include <AppKit/NSTextView.h>
|
||||||
|
@ -70,6 +71,68 @@ static const int currentVersion = 1; // GSNibItem version number...
|
||||||
}
|
}
|
||||||
@end
|
@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.
|
* 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
|
- (void) awakeWithContext: (NSDictionary *)context
|
||||||
topLevelItems: (NSArray *)items
|
|
||||||
{
|
{
|
||||||
if (_isAwake == NO)
|
if (isAwake == NO)
|
||||||
{
|
{
|
||||||
NSEnumerator *enumerator;
|
NSEnumerator *enumerator;
|
||||||
NSNibConnector *connection;
|
NSNibConnector *connection;
|
||||||
NSString *key;
|
NSString *key;
|
||||||
NSArray *visible;
|
NSArray *visible;
|
||||||
NSMenu *menu;
|
NSMenu *menu;
|
||||||
NSMutableArray *topLevelObjects;
|
NSMutableArray *topObjects;
|
||||||
id obj;
|
id obj;
|
||||||
|
|
||||||
_isAwake = YES;
|
isAwake = YES;
|
||||||
/*
|
/*
|
||||||
* Add local entries into name table.
|
* Add local entries into name table.
|
||||||
*/
|
*/
|
||||||
|
@ -153,6 +215,24 @@ static const int currentVersion = 1; // GSNibItem version number...
|
||||||
[NSApp setWindowsMenu: menu];
|
[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
|
* Now tell all the objects that they have been loaded from
|
||||||
* a nib.
|
* 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: @"NSVisible"] == NO && // also exclude any other special parts of the nameTable.
|
||||||
[key isEqualToString: @"NSDeferred"] == NO &&
|
[key isEqualToString: @"NSDeferred"] == NO &&
|
||||||
[key isEqualToString: @"NSTopLevelObjects"] == NO &&
|
[key isEqualToString: @"NSTopLevelObjects"] == NO &&
|
||||||
[key isEqualToString: @"GSCustomClassMap"] == NO)
|
[key isEqualToString: @"GSCustomClassMap"] == NO)
|
||||||
{
|
{
|
||||||
id o = [nameTable objectForKey: key];
|
id o = [nameTable objectForKey: key];
|
||||||
|
|
||||||
|
// send the awake message, if it responds...
|
||||||
if ([o respondsToSelector: @selector(awakeFromNib)])
|
if ([o respondsToSelector: @selector(awakeFromNib)])
|
||||||
{
|
{
|
||||||
[o 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.
|
* 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"];
|
visible = [nameTable objectForKey: @"NSVisible"];
|
||||||
if (visible != nil
|
if (visible != nil
|
||||||
|
@ -274,6 +327,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
||||||
{
|
{
|
||||||
RELEASE(nameTable);
|
RELEASE(nameTable);
|
||||||
RELEASE(connections);
|
RELEASE(connections);
|
||||||
|
RELEASE(topLevelObjects);
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,6 +335,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
||||||
{
|
{
|
||||||
[aCoder encodeObject: nameTable];
|
[aCoder encodeObject: nameTable];
|
||||||
[aCoder encodeObject: connections];
|
[aCoder encodeObject: connections];
|
||||||
|
[aCoder encodeObject: topLevelObjects];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) init
|
- (id) init
|
||||||
|
@ -289,6 +344,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
||||||
{
|
{
|
||||||
nameTable = [[NSMutableDictionary alloc] initWithCapacity: 8];
|
nameTable = [[NSMutableDictionary alloc] initWithCapacity: 8];
|
||||||
connections = [[NSMutableArray alloc] initWithCapacity: 8];
|
connections = [[NSMutableArray alloc] initWithCapacity: 8];
|
||||||
|
topLevelObjects = [[NSMutableSet alloc] initWithCapacity: 8];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -296,11 +352,45 @@ static const int currentVersion = 1; // GSNibItem version number...
|
||||||
- (id) initWithCoder: (NSCoder*)aCoder
|
- (id) initWithCoder: (NSCoder*)aCoder
|
||||||
{
|
{
|
||||||
int version = [aCoder versionForClassName: @"GSNibContainer"];
|
int version = [aCoder versionForClassName: @"GSNibContainer"];
|
||||||
|
|
||||||
|
// save the version to the ivar, we need it later.
|
||||||
if(version == GNUSTEP_NIB_VERSION)
|
if(version == GNUSTEP_NIB_VERSION)
|
||||||
{
|
{
|
||||||
[aCoder decodeValueOfObjCType: @encode(id) at: &nameTable];
|
[aCoder decodeValueOfObjCType: @encode(id) at: &nameTable];
|
||||||
[aCoder decodeValueOfObjCType: @encode(id) at: &connections];
|
[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;
|
return self;
|
||||||
|
@ -310,6 +400,11 @@ static const int currentVersion = 1; // GSNibItem version number...
|
||||||
{
|
{
|
||||||
return nameTable;
|
return nameTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSMutableSet*) topLevelObjects
|
||||||
|
{
|
||||||
|
return topLevelObjects;
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
// The first standin objects here are for views and normal objects like controllers
|
// 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)
|
if (cls == nil)
|
||||||
{
|
{
|
||||||
[NSException raise: NSInternalInconsistencyException
|
[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]];
|
obj = [cls allocWithZone: [self zone]];
|
||||||
|
@ -386,7 +481,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
||||||
if (cls == nil)
|
if (cls == nil)
|
||||||
{
|
{
|
||||||
[NSException raise: NSInternalInconsistencyException
|
[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]];
|
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
|
// 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.
|
// the set of things to be retained. Also, the initial version of the nib container
|
||||||
if(obj != nil)
|
// 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 &&
|
if([self isKindOfClass: [GSNibItem class]] == YES &&
|
||||||
[self isKindOfClass: [GSCustomView class]] == NO)
|
[self isKindOfClass: [GSCustomView class]] == NO)
|
||||||
{
|
{
|
||||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||||
[nc postNotificationName: @"__GSInternalNibItemAddedNotification"
|
[nc postNotificationName: GSInternalNibItemAddedNotification
|
||||||
object: obj];
|
object: obj];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -485,7 +582,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
||||||
if(_superClass == nil)
|
if(_superClass == nil)
|
||||||
{
|
{
|
||||||
[NSException raise: NSInternalInconsistencyException
|
[NSException raise: NSInternalInconsistencyException
|
||||||
format: @"Unable to find class '%@'", superClassName];
|
format: @"Unable to find class '%@', it is not linked into the application.", superClassName];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
@ -538,7 +635,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
||||||
if(aClass == 0)
|
if(aClass == 0)
|
||||||
{
|
{
|
||||||
[NSException raise: NSInternalInconsistencyException
|
[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
|
// 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(![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
|
// if we are not in interface builder, call
|
||||||
// designated initializer per spec...
|
// designated initializer per spec...
|
||||||
|
@ -648,7 +745,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
||||||
{
|
{
|
||||||
if(![self respondsToSelector: @selector(isInInterfaceBuilder)])
|
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];
|
NSRect theFrame = [obj frame];
|
||||||
obj = [obj initWithFrame: theFrame];
|
obj = [obj initWithFrame: theFrame];
|
||||||
|
@ -677,7 +774,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
||||||
{
|
{
|
||||||
if(![self respondsToSelector: @selector(isInInterfaceBuilder)])
|
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];
|
NSRect theFrame = [obj frame];
|
||||||
obj = [obj initWithFrame: theFrame];
|
obj = [obj initWithFrame: theFrame];
|
||||||
|
@ -706,7 +803,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
||||||
{
|
{
|
||||||
if(![self respondsToSelector: @selector(isInInterfaceBuilder)])
|
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];
|
NSRect theFrame = [obj frame];
|
||||||
id textContainer = [obj textContainer];
|
id textContainer = [obj textContainer];
|
||||||
|
@ -737,7 +834,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
||||||
{
|
{
|
||||||
if(![self respondsToSelector: @selector(isInInterfaceBuilder)])
|
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];
|
NSString *theTitle = [obj title];
|
||||||
obj = [obj initWithTitle: theTitle];
|
obj = [obj initWithTitle: theTitle];
|
||||||
|
@ -768,7 +865,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
||||||
/*
|
/*
|
||||||
if(![self respondsToSelector: @selector(isInInterfaceBuilder)])
|
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];
|
NSRect theFrame = [obj frame];
|
||||||
obj = [obj initWithFrame: theFrame];
|
obj = [obj initWithFrame: theFrame];
|
||||||
|
@ -797,7 +894,7 @@ static const int currentVersion = 1; // GSNibItem version number...
|
||||||
{
|
{
|
||||||
if(![self respondsToSelector: @selector(isInInterfaceBuilder)])
|
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];
|
obj = [self init];
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,66 +185,6 @@
|
||||||
}
|
}
|
||||||
@end
|
@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)
|
@implementation NSBundle (NSBundleAdditions)
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -286,7 +226,6 @@ Class gmodel_class(void)
|
||||||
BOOL loaded = NO;
|
BOOL loaded = NO;
|
||||||
NSUnarchiver *unarchiver = nil;
|
NSUnarchiver *unarchiver = nil;
|
||||||
NSString *ext = [fileName pathExtension];
|
NSString *ext = [fileName pathExtension];
|
||||||
id nibitems = nil;
|
|
||||||
|
|
||||||
if ([ext isEqual: @"nib"])
|
if ([ext isEqual: @"nib"])
|
||||||
{
|
{
|
||||||
|
@ -346,19 +285,15 @@ Class gmodel_class(void)
|
||||||
{
|
{
|
||||||
id obj;
|
id obj;
|
||||||
|
|
||||||
nibitems = [[_GSNibItemCollector alloc] init];
|
|
||||||
NSDebugLog(@"Invoking unarchiver");
|
NSDebugLog(@"Invoking unarchiver");
|
||||||
[unarchiver setObjectZone: zone];
|
[unarchiver setObjectZone: zone];
|
||||||
obj = [unarchiver decodeObject];
|
obj = [unarchiver decodeObject];
|
||||||
if (obj != nil)
|
if (obj != nil)
|
||||||
{
|
{
|
||||||
NSArray *items = [nibitems items];
|
|
||||||
if ([obj isKindOfClass: [GSNibContainer class]])
|
if ([obj isKindOfClass: [GSNibContainer class]])
|
||||||
{
|
{
|
||||||
NSDebugLog(@"Calling awakeWithContext");
|
NSDebugLog(@"Calling awakeWithContext");
|
||||||
|
[obj awakeWithContext: context];
|
||||||
[obj awakeWithContext: context
|
|
||||||
topLevelItems: items];
|
|
||||||
loaded = YES;
|
loaded = YES;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -366,7 +301,7 @@ Class gmodel_class(void)
|
||||||
NSLog(@"Nib '%@' without container object!", fileName);
|
NSLog(@"Nib '%@' without container object!", fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RELEASE(nibitems);
|
// RELEASE(nibitems);
|
||||||
RELEASE(unarchiver);
|
RELEASE(unarchiver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -375,7 +310,7 @@ Class gmodel_class(void)
|
||||||
NS_HANDLER
|
NS_HANDLER
|
||||||
{
|
{
|
||||||
NSLog(@"Exception occured while loading model: %@",[localException reason]);
|
NSLog(@"Exception occured while loading model: %@",[localException reason]);
|
||||||
TEST_RELEASE(nibitems);
|
// TEST_RELEASE(nibitems);
|
||||||
TEST_RELEASE(unarchiver);
|
TEST_RELEASE(unarchiver);
|
||||||
}
|
}
|
||||||
NS_ENDHANDLER
|
NS_ENDHANDLER
|
||||||
|
|
|
@ -111,25 +111,6 @@
|
||||||
NS_ENDHANDLER
|
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
|
- (NSDictionary *) _copyTable: (NSDictionary *)dict
|
||||||
{
|
{
|
||||||
NSMutableDictionary *ctx = nil;
|
NSMutableDictionary *ctx = nil;
|
||||||
|
@ -174,7 +155,6 @@
|
||||||
{
|
{
|
||||||
// load the nib data into memory...
|
// load the nib data into memory...
|
||||||
_nibData = [NSData dataWithContentsOfURL: nibFileURL];
|
_nibData = [NSData dataWithContentsOfURL: nibFileURL];
|
||||||
[self _addObserver];
|
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -202,7 +182,6 @@
|
||||||
|
|
||||||
// load the nib data into memory...
|
// load the nib data into memory...
|
||||||
[self _readNibData: fileName];
|
[self _readNibData: fileName];
|
||||||
[self _addObserver];
|
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -226,7 +205,6 @@
|
||||||
{
|
{
|
||||||
id obj;
|
id obj;
|
||||||
|
|
||||||
_topLevelItems = [[NSMutableArray alloc] init];
|
|
||||||
[unarchiver setObjectZone: zone];
|
[unarchiver setObjectZone: zone];
|
||||||
obj = [unarchiver decodeObject];
|
obj = [unarchiver decodeObject];
|
||||||
if (obj != nil)
|
if (obj != nil)
|
||||||
|
@ -234,8 +212,7 @@
|
||||||
if ([obj isKindOfClass: [GSNibContainer class]])
|
if ([obj isKindOfClass: [GSNibContainer class]])
|
||||||
{
|
{
|
||||||
NSDictionary *nameTable = [self _copyTable: externalNameTable];
|
NSDictionary *nameTable = [self _copyTable: externalNameTable];
|
||||||
[obj awakeWithContext: nameTable
|
[obj awakeWithContext: nameTable];
|
||||||
topLevelItems: _topLevelItems];
|
|
||||||
loaded = YES;
|
loaded = YES;
|
||||||
RELEASE(nameTable);
|
RELEASE(nameTable);
|
||||||
}
|
}
|
||||||
|
@ -245,7 +222,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RELEASE(unarchiver);
|
RELEASE(unarchiver);
|
||||||
RELEASE(_topLevelItems);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,7 +229,6 @@
|
||||||
{
|
{
|
||||||
NSLog(@"Exception occured while loading model: %@",[localException reason]);
|
NSLog(@"Exception occured while loading model: %@",[localException reason]);
|
||||||
TEST_RELEASE(unarchiver);
|
TEST_RELEASE(unarchiver);
|
||||||
TEST_RELEASE(_topLevelItems);
|
|
||||||
}
|
}
|
||||||
NS_ENDHANDLER
|
NS_ENDHANDLER
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue