Get the class NSNib to work and use it in NSBundleAdditions.

Restructure top level object handling for NIB loading.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@30018 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
fredkiefer 2010-03-22 09:08:50 +00:00
parent ec2ea1114d
commit 444b0fc6db
9 changed files with 122 additions and 126 deletions

View file

@ -1,3 +1,16 @@
2010-03-22 Fred Kiefer <FredKiefer@gmx.de>
* Headers/Additions/GNUstepGUI/GSModelLoaderFactory.h,
* Source/GSModelLoaderFactory.m,
* Source/GSGormLoader.m,
* Source/GSXibLoader.m,
* Source/GSNibLoader.m: New method dataForFile: on GSModelLoader
and its subclasses.
* Source/NSNib.m: Use this new method to load NIB files.
* Source/NSBundleAdditions.m: Use NSNib for NIB loading.
* Source/GSNibLoading.m: Correctly handle top level objects and
clean up dealloc for most classes here.
2010-03-22 Fred Kiefer <FredKiefer@gmx.de> 2010-03-22 Fred Kiefer <FredKiefer@gmx.de>
* Source/NSDocument.m (-close): Retain and autorelease self before * Source/NSDocument.m (-close): Retain and autorelease self before

View file

@ -46,6 +46,7 @@
- (BOOL) loadModelFile: (NSString *)fileName - (BOOL) loadModelFile: (NSString *)fileName
externalNameTable: (NSDictionary *)context externalNameTable: (NSDictionary *)context
withZone: (NSZone *)zone; withZone: (NSZone *)zone;
- (NSData *)dataForFile: (NSString *)fileName;
@end @end
@interface GSModelLoaderFactory : NSObject @interface GSModelLoaderFactory : NSObject

View file

@ -26,11 +26,18 @@
Boston, MA 02110-1301, USA. Boston, MA 02110-1301, USA.
*/ */
#include <Foundation/Foundation.h> #import "config.h"
#include <AppKit/AppKit.h> #import <Foundation/NSArchiver.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSData.h>
#import <Foundation/NSDebug.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSException.h>
#import <Foundation/NSFileManager.h>
#import <Foundation/NSString.h>
#include "GNUstepGUI/GSModelLoaderFactory.h" #import "GNUstepGUI/GSModelLoaderFactory.h"
#include "GNUstepGUI/GSGormLoading.h" #import "GNUstepGUI/GSGormLoading.h"
@interface GSGormLoader : GSModelLoader @interface GSGormLoader : GSModelLoader
@end @end
@ -104,19 +111,15 @@
return loaded; return loaded;
} }
- (BOOL) loadModelFile: (NSString *)fileName - (NSData *) dataForFile: (NSString *)fileName
externalNameTable: (NSDictionary *)context
withZone: (NSZone *)zone;
{ {
NSFileManager *mgr = [NSFileManager defaultManager]; NSFileManager *mgr = [NSFileManager defaultManager];
BOOL isDir = NO; BOOL isDir = NO;
BOOL loaded = NO;
NSDebugLog(@"Loading Gorm `%@'...\n", fileName); NSDebugLog(@"Loading Gorm `%@'...\n", fileName);
if ([mgr fileExistsAtPath: fileName isDirectory: &isDir]) if ([mgr fileExistsAtPath: fileName isDirectory: &isDir])
{ {
NSData *data = nil; NSData *data = nil;
// if the data is in a directory, then load from objects.gorm in the directory // if the data is in a directory, then load from objects.gorm in the directory
if (isDir == NO) if (isDir == NO)
@ -130,18 +133,13 @@
data = [NSData dataWithContentsOfFile: newFileName]; data = [NSData dataWithContentsOfFile: newFileName];
NSDebugLog(@"Loaded data from %@...",newFileName); NSDebugLog(@"Loaded data from %@...",newFileName);
} }
return data;
loaded = [self loadModelData: data
externalNameTable: context
withZone: zone];
// report a problem if there is one.
if (loaded == NO)
{
NSLog(@"Could not load Gorm file: %@",fileName);
}
} }
else
return loaded; {
NSLog(@"Gorm file specified %@, could not be found.", fileName);
}
return nil;
} }
@end @end

View file

@ -28,6 +28,7 @@
#import "config.h" #import "config.h"
#import <Foundation/NSArray.h> #import <Foundation/NSArray.h>
#import <Foundation/NSData.h>
#import <Foundation/NSDictionary.h> #import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h> #import <Foundation/NSEnumerator.h>
#import <Foundation/NSException.h> #import <Foundation/NSException.h>
@ -60,9 +61,26 @@
externalNameTable: (NSDictionary *)context externalNameTable: (NSDictionary *)context
withZone: (NSZone *)zone withZone: (NSZone *)zone
{ {
[NSException raise: NSInternalInconsistencyException NSData *data = [self dataForFile: fileName];
format: @"Abstract model loader."];
return NO; if (data != nil)
{
BOOL loaded = [self loadModelData: data
externalNameTable: context
withZone: zone];
if (!loaded)
NSLog(@"Could not load Nib file: %@", fileName);
return loaded;
}
else
{
return NO;
}
}
- (NSData *) dataForFile: (NSString *)fileName
{
return [NSData dataWithContentsOfFile: fileName];
} }
+ (NSComparisonResult) _comparePriority: (Class)loader + (NSComparisonResult) _comparePriority: (Class)loader

View file

@ -124,19 +124,15 @@
return loaded; return loaded;
} }
- (BOOL) loadModelFile: (NSString *)fileName - (NSData *) dataForFile: (NSString *)fileName
externalNameTable: (NSDictionary *)context
withZone: (NSZone *)zone;
{ {
NSFileManager *mgr = [NSFileManager defaultManager]; NSFileManager *mgr = [NSFileManager defaultManager];
BOOL isDir = NO; BOOL isDir = NO;
BOOL loaded = NO;
NSDebugLog(@"Loading Nib `%@'...\n", fileName); NSDebugLog(@"Loading Nib `%@'...\n", fileName);
if ([mgr fileExistsAtPath: fileName isDirectory: &isDir]) if ([mgr fileExistsAtPath: fileName isDirectory: &isDir])
{ {
NSData *data = nil; NSData *data = nil;
// if the data is in a directory, then load from keyedobjects.nib in the directory // if the data is in a directory, then load from keyedobjects.nib in the directory
if (isDir == NO) if (isDir == NO)
@ -148,24 +144,14 @@
{ {
NSString *newFileName = [fileName stringByAppendingPathComponent: @"keyedobjects.nib"]; NSString *newFileName = [fileName stringByAppendingPathComponent: @"keyedobjects.nib"];
data = [NSData dataWithContentsOfFile: newFileName]; data = [NSData dataWithContentsOfFile: newFileName];
NSDebugLog(@"Loaded data from %@...",newFileName); NSDebugLog(@"Loaded data from %@...", newFileName);
}
loaded = [self loadModelData: data
externalNameTable: context
withZone: zone];
// report a problem if there is one.
if (loaded == NO)
{
NSLog(@"Could not load Nib file: %@",fileName);
} }
return data;
} }
else else
{ {
NSLog(@"Nib file specified %@, could not be found.",fileName); NSLog(@"NIB file specified %@, could not be found.", fileName);
} }
return nil;
return loaded;
} }
@end @end

View file

@ -9,6 +9,8 @@
Author: Gregory John Casamento Author: Gregory John Casamento
Date: 2003, 2005 Date: 2003, 2005
Author: Fred Kiefer
Date: 2003, 2010
This file is part of the GNUstep GUI Library. This file is part of the GNUstep GUI Library.
@ -286,6 +288,7 @@ static BOOL _isInInterfaceBuilder = NO;
RELEASE(_windowClass); RELEASE(_windowClass);
RELEASE(_view); RELEASE(_view);
RELEASE(_autosaveName); RELEASE(_autosaveName);
RELEASE(_realObject);
[super dealloc]; [super dealloc];
} }
@ -701,6 +704,13 @@ static BOOL _isInInterfaceBuilder = NO;
} }
} }
- (void) dealloc
{
RELEASE(_className);
RELEASE(_realObject);
[super dealloc];
}
/** /**
* Designated initializer for NSViewTemplate. * Designated initializer for NSViewTemplate.
*/ */
@ -837,6 +847,13 @@ static BOOL _isInInterfaceBuilder = NO;
} }
} }
- (void) dealloc
{
RELEASE(_menuClass);
RELEASE(_realObject);
[super dealloc];
}
- (id) initWithCoder: (NSCoder *)aCoder - (id) initWithCoder: (NSCoder *)aCoder
{ {
RELEASE(self); RELEASE(self);
@ -988,6 +1005,7 @@ static BOOL _isInInterfaceBuilder = NO;
{ {
RELEASE(_className); RELEASE(_className);
RELEASE(_extension); RELEASE(_extension);
RELEASE(_object);
[super dealloc]; [super dealloc];
} }
@end @end
@ -1858,15 +1876,16 @@ static BOOL _isInInterfaceBuilder = NO;
*/ */
- (void) nibInstantiateWithOwner: (id)owner topLevelObjects: (NSMutableArray *)topLevelObjects - (void) nibInstantiateWithOwner: (id)owner topLevelObjects: (NSMutableArray *)topLevelObjects
{ {
NSEnumerator *en = [_connections objectEnumerator]; NSEnumerator *en;
NSArray *objs = NSAllMapTableKeys([self names]); NSArray *objs;
id obj = nil; id obj = nil;
id menu = nil; id menu = nil;
// set the new root object. // set the new root object.
[_root setRealObject: owner]; [_root setRealObject: owner];
// iterate over connections, instantiate, and then establish them. // iterate over connections, instantiate and then establish them.
en = [_connections objectEnumerator];
while ((obj = [en nextObject]) != nil) while ((obj = [en nextObject]) != nil)
{ {
if ([obj respondsToSelector: @selector(instantiateWithInstantiator:)]) if ([obj respondsToSelector: @selector(instantiateWithInstantiator:)])
@ -1876,24 +1895,23 @@ static BOOL _isInInterfaceBuilder = NO;
} }
} }
// iterate over all objects instantiate windows, awaken objects and fill // iterate over all objects, instantiate, awaken objects and fill
// in top level array. // in top level array.
objs = NSAllMapTableKeys(_objects);
en = [objs objectEnumerator]; en = [objs objectEnumerator];
while ((obj = [en nextObject]) != nil) while ((obj = [en nextObject]) != nil)
{ {
// instantiate all windows and fill in the top level array. id v = NSMapGet(_objects, obj);
if ([obj isKindOfClass: [NSWindowTemplate class]]) obj = [self instantiateObject: obj];
// Object is top level if it isn't the owner but points to it.
if ((v == owner || v == _root) && (obj != owner) && (obj != _root))
{ {
if ([obj realObject] == nil) if (topLevelObjects == nil)
{ {
obj = [self instantiateObject: obj]; // When there is no top level object array, just retain these objects
[topLevelObjects addObject: obj]; RETAIN(obj);
} }
} else
else
{
id v = NSMapGet(_objects, obj);
if (v == nil || v == owner)
{ {
[topLevelObjects addObject: obj]; [topLevelObjects addObject: obj];
} }

View file

@ -693,41 +693,28 @@
return loaded; return loaded;
} }
- (BOOL) loadModelFile: (NSString *)fileName - (NSData *) dataForFile: (NSString *)fileName
externalNameTable: (NSDictionary *)context
withZone: (NSZone *)zone;
{ {
NSFileManager *mgr = [NSFileManager defaultManager]; NSFileManager *mgr = [NSFileManager defaultManager];
BOOL isDir = NO; BOOL isDir = NO;
BOOL loaded = NO;
NSDebugLog(@"Loading Xib `%@'...\n", fileName); NSDebugLog(@"Loading Xib `%@'...\n", fileName);
if ([mgr fileExistsAtPath: fileName isDirectory: &isDir]) if ([mgr fileExistsAtPath: fileName isDirectory: &isDir])
{ {
NSData *data = nil;
if (isDir == NO) if (isDir == NO)
{ {
data = [NSData dataWithContentsOfFile: fileName]; return [NSData dataWithContentsOfFile: fileName];
NSDebugLog(@"Loaded data from file..."); }
loaded = [self loadModelData: data else
externalNameTable: context {
withZone: zone]; NSLog(@"Xib file specified %@, is directory.", fileName);
} }
// report a problem if there is one.
if (loaded == NO)
{
NSLog(@"Could not load Xib file: %@",fileName);
}
} }
else else
{ {
NSLog(@"Xib file specified %@, could not be found.",fileName); NSLog(@"Xib file specified %@, could not be found.", fileName);
} }
return nil;
return loaded;
} }
@end @end

View file

@ -38,9 +38,11 @@
#import <Foundation/NSEnumerator.h> #import <Foundation/NSEnumerator.h>
#import <Foundation/NSException.h> #import <Foundation/NSException.h>
#import <Foundation/NSString.h> #import <Foundation/NSString.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSUserDefaults.h> #import <Foundation/NSUserDefaults.h>
#import <Foundation/NSKeyValueCoding.h> #import <Foundation/NSKeyValueCoding.h>
#import <AppKit/NSControl.h> #import "AppKit/NSControl.h"
#import "AppKit/NSNib.h"
#import "AppKit/NSNibConnector.h" #import "AppKit/NSNibConnector.h"
#import "AppKit/NSNibLoading.h" #import "AppKit/NSNibLoading.h"
#import "GNUstepGUI/GSModelLoaderFactory.h" #import "GNUstepGUI/GSModelLoaderFactory.h"
@ -229,10 +231,11 @@
externalNameTable: (NSDictionary*)context externalNameTable: (NSDictionary*)context
withZone: (NSZone*)zone withZone: (NSZone*)zone
{ {
GSModelLoader *loader = [GSModelLoaderFactory modelLoaderForFileName: fileName]; NSNib *nib = [[NSNib alloc] initWithContentsOfURL: [NSURL fileURLWithPath: fileName]];
BOOL loaded = [loader loadModelFile: fileName BOOL loaded = [nib instantiateNibWithExternalNameTable: context
externalNameTable: context withZone: zone];
withZone: zone];
RELEASE(nib);
return loaded; return loaded;
} }
@ -246,7 +249,7 @@
{ {
return NO; return NO;
} }
table = [NSDictionary dictionaryWithObject: owner forKey: @"NSOwner"]; table = [NSDictionary dictionaryWithObject: owner forKey: @"NSNibOwner"];
/* /*
* First look for the NIB in the bundle corresponding to the owning class, * First look for the NIB in the bundle corresponding to the owning class,

View file

@ -52,8 +52,6 @@
#import "AppKit/NSNib.h" #import "AppKit/NSNib.h"
#import "AppKit/NSNibLoading.h" #import "AppKit/NSNibLoading.h"
#import "GNUstepGUI/GSModelLoaderFactory.h" #import "GNUstepGUI/GSModelLoaderFactory.h"
#import "GNUstepGUI/GSGormLoading.h"
#import "GNUstepGUI/IMLoading.h"
@implementation NSNib @implementation NSNib
@ -64,8 +62,8 @@
NS_DURING NS_DURING
{ {
NSString *newFileName = [GSModelLoaderFactory supportedModelFileAtPath: fileName]; NSString *newFileName = [GSModelLoaderFactory supportedModelFileAtPath: fileName];
ASSIGN(_nibData, [NSData dataWithContentsOfFile: newFileName]);
ASSIGN(_loader, [GSModelLoaderFactory modelLoaderForFileType: [newFileName pathExtension]]); ASSIGN(_loader, [GSModelLoaderFactory modelLoaderForFileType: [newFileName pathExtension]]);
ASSIGN(_nibData, [_loader dataForFile: newFileName]);
NSDebugLog(@"Loaded data from %@...", newFileName); NSDebugLog(@"Loaded data from %@...", newFileName);
} }
NS_HANDLER NS_HANDLER
@ -75,37 +73,6 @@
NS_ENDHANDLER NS_ENDHANDLER
} }
- (NSDictionary *) _copyTable: (NSDictionary *)dict
{
NSMutableDictionary *ctx = nil;
if (dict != nil)
{
id obj = nil;
// copy the dictionary...
ctx = [NSMutableDictionary dictionaryWithDictionary: dict];
// remove and set the owner...
obj = [ctx objectForKey: @"NSNibOwner"];
if (obj != nil)
{
[ctx removeObjectForKey: @"NSNibOwner"];
[ctx setObject: obj forKey: @"NSOwner"];
}
// Remove and set the top level objects...
obj = [ctx objectForKey: @"NSNibTopLevelObjects"];
if (obj != nil)
{
[ctx removeObjectForKey: @"NSNibTopLevelObjects"];
[ctx setObject: obj forKey: @"NSTopLevelObjects"];
}
}
return ctx;
}
// Public methods... // Public methods...
/** /**
@ -127,10 +94,10 @@
{ {
NS_DURING NS_DURING
{ {
// load the nib data into memory...
_nibData = [NSData dataWithContentsOfURL: nibFileURL];
ASSIGN(_loader, [GSModelLoaderFactory modelLoaderForFileType: ASSIGN(_loader, [GSModelLoaderFactory modelLoaderForFileType:
[[nibFileURL path] pathExtension]]); [[nibFileURL path] pathExtension]]);
// load the nib data into memory...
_nibData = [NSData dataWithContentsOfURL: nibFileURL];
} }
NS_HANDLER NS_HANDLER
{ {
@ -163,6 +130,11 @@
// initialize the bundle... // initialize the bundle...
fileName = [bundle pathForNibResource: nibNamed]; fileName = [bundle pathForNibResource: nibNamed];
if (fileName == nil)
{
DESTROY(self);
return nil;
}
// load the nib data into memory... // load the nib data into memory...
[self _readNibData: fileName]; [self _readNibData: fileName];