mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-30 16:30:53 +00:00
Temporary removal of NSNib pending bugfix. :)
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@18568 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
b827f3792f
commit
4ab36d5d73
4 changed files with 150 additions and 49 deletions
|
@ -45,10 +45,8 @@
|
|||
#include <Foundation/NSUserDefaults.h>
|
||||
#include <Foundation/NSKeyValueCoding.h>
|
||||
#include <Foundation/NSNotification.h>
|
||||
#include <Foundation/NSURL.h>
|
||||
#include "AppKit/NSNibConnector.h"
|
||||
#include "AppKit/NSNibLoading.h"
|
||||
#include "AppKit/NSNib.h"
|
||||
#include "GNUstepGUI/GSNibTemplates.h"
|
||||
#include "GNUstepGUI/IMLoading.h"
|
||||
|
||||
|
@ -187,11 +185,66 @@
|
|||
}
|
||||
@end
|
||||
|
||||
// declare this here to avoid a compiler warning...
|
||||
@interface NSNib (GNUstepPrivate)
|
||||
+ (NSString *) _nibFilename: (NSString *)fileName;
|
||||
/*
|
||||
* 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
|
||||
|
@ -230,15 +283,11 @@ Class gmodel_class(void)
|
|||
externalNameTable: (NSDictionary*)context
|
||||
withZone: (NSZone*)zone
|
||||
{
|
||||
NSString *ext = [fileName pathExtension];
|
||||
NSNib *nib = nil;
|
||||
BOOL result = NO;
|
||||
NSMutableDictionary *ctx = nil;
|
||||
BOOL loaded = NO;
|
||||
NSUnarchiver *unarchiver = nil;
|
||||
NSString *ext = [fileName pathExtension];
|
||||
id nibitems = nil;
|
||||
|
||||
/*
|
||||
* Determine if we're loading a .gorm or a .gmodel
|
||||
* if the extension is .nib.
|
||||
*/
|
||||
if ([ext isEqual: @"nib"])
|
||||
{
|
||||
NSFileManager *mgr = [NSFileManager defaultManager];
|
||||
|
@ -264,42 +313,78 @@ Class gmodel_class(void)
|
|||
if ([ext isEqualToString: @"gmodel"])
|
||||
{
|
||||
return [gmodel_class() loadIMFile: fileName
|
||||
owner: [context objectForKey: @"NSOwner"]];
|
||||
owner: [context objectForKey: @"NSOwner"]];
|
||||
}
|
||||
|
||||
// Create a temporary context dictionary, containing all of the entries of the
|
||||
// one passed in, but replacing the NSOwner and NSTopLevelObjects entries with
|
||||
// the ones used by the NSNib class. We want *all* nib handling to happen in
|
||||
// one unified place within NSNib. GJC
|
||||
if(context != nil)
|
||||
|
||||
NSDebugLog(@"Loading Nib `%@'...\n", fileName);
|
||||
NS_DURING
|
||||
{
|
||||
id obj = nil;
|
||||
NSFileManager *mgr = [NSFileManager defaultManager];
|
||||
BOOL isDir = NO;
|
||||
|
||||
ctx = [NSMutableDictionary dictionaryWithDictionary: context];
|
||||
|
||||
// remove and set the owner...
|
||||
obj = [ctx objectForKey: @"NSOwner"];
|
||||
if(obj != nil)
|
||||
if([mgr fileExistsAtPath: fileName isDirectory: &isDir])
|
||||
{
|
||||
[ctx removeObjectForKey: @"NSOwner"];
|
||||
[ctx setObject: obj forKey: @"NSNibOwner"];
|
||||
}
|
||||
NSData *data = nil;
|
||||
|
||||
// if the data is in a directory, then load from objects.gorm in the directory
|
||||
if(isDir == NO)
|
||||
{
|
||||
data = [NSData dataWithContentsOfFile: fileName];
|
||||
NSDebugLog(@"Loaded data from file...");
|
||||
}
|
||||
else
|
||||
{
|
||||
NSString *newFileName = [fileName stringByAppendingPathComponent: @"objects.gorm"];
|
||||
data = [NSData dataWithContentsOfFile: newFileName];
|
||||
NSDebugLog(@"Loaded data from %@...",newFileName);
|
||||
}
|
||||
|
||||
// Remove and set the top level objects...
|
||||
obj = [ctx objectForKey: @"NSTopLevelObjects"];
|
||||
if(obj != nil)
|
||||
{
|
||||
[ctx removeObjectForKey: @"NSTopLevelObjects"];
|
||||
[ctx setObject: obj forKey: @"NSNibTopLevelObjects"];
|
||||
if (data != nil)
|
||||
{
|
||||
unarchiver = [[NSUnarchiver alloc] initForReadingWithData: data];
|
||||
if (unarchiver != nil)
|
||||
{
|
||||
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];
|
||||
loaded = YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"Nib '%@' without container object!", fileName);
|
||||
}
|
||||
}
|
||||
RELEASE(nibitems);
|
||||
RELEASE(unarchiver);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
NSLog(@"Exception occured while loading model: %@",[localException reason]);
|
||||
TEST_RELEASE(nibitems);
|
||||
TEST_RELEASE(unarchiver);
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
|
||||
// Load and instantiate the nib... release the NSNib object.
|
||||
nib = [[NSNib alloc] initWithContentsOfURL: [NSURL fileURLWithPath: [NSNib _nibFilename: fileName]]];
|
||||
result = [nib instantiateNibWithExternalNameTable: ctx withZone: zone];
|
||||
RELEASE(nib);
|
||||
|
||||
return result;
|
||||
if (loaded == NO)
|
||||
{
|
||||
NSLog(@"Failed to load Nib\n");
|
||||
}
|
||||
return loaded;
|
||||
}
|
||||
|
||||
+ (BOOL) loadNibNamed: (NSString *)aNibName
|
||||
|
@ -405,13 +490,17 @@ Class gmodel_class(void)
|
|||
withZone: (NSZone*)zone
|
||||
{
|
||||
NSString *path = [self pathForNibResource: fileName];
|
||||
if (fileName != nil)
|
||||
|
||||
if (path != nil)
|
||||
{
|
||||
return [NSBundle loadNibFile: path
|
||||
externalNameTable: context
|
||||
withZone: (NSZone*)zone];
|
||||
}
|
||||
return NO;
|
||||
else
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
@end
|
||||
// end of NSBundleAdditions
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue