/** NSBundleAdditions Implementation of NSBundle Additions Copyright (C) 1997, 1999 Free Software Foundation, Inc. Author: Simon Frankau Date: 1997 Author: Richard Frith-Macdonald Date: 1999 Author: Gregory John Casamento Date: 2000 This file is part of the GNUstep GUI Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; see the file COPYING.LIB. If not, see or write to the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #import "config.h" #import #import #import #import #import #import #import #import #import "AppKit/NSNib.h" #import "AppKit/NSNibLoading.h" #import "GNUstepGUI/GSModelLoaderFactory.h" @implementation NSBundle (NSBundleAdditions) + (BOOL) loadNibFile: (NSString*)fileName externalNameTable: (NSDictionary*)context withZone: (NSZone*)zone { NSNib *nib = [[NSNib alloc] initWithContentsOfURL: [NSURL fileURLWithPath: fileName]]; BOOL loaded = [nib instantiateNibWithExternalNameTable: context withZone: zone]; RELEASE(nib); return loaded; } + (BOOL) loadNibNamed: (NSString *)aNibName owner: (id)owner { NSDictionary *table; NSBundle *bundle; if (owner == nil || aNibName == nil) { return NO; } table = [NSDictionary dictionaryWithObject: owner forKey: NSNibOwner]; /* * First look for the NIB in the bundle corresponding to the owning class, * since the class may have been loaded dynamically and the bundle may * contain class-specific NIB resources as well as code. * If that fails, try to load the NIB from the main application bundle, * which is where most NIB resources are to be found. * Possibly this is the wrong order ... since it's conceivable that an * application may supply an alternative NIB which it would like to have * used in preference to the one in the classes bundle. However I could * not find the behavior documented anywhere and the current order is * most consistent with the the way the code behaved before I changed it. */ bundle = [self bundleForClass: [owner class]]; if (bundle != nil && [bundle loadNibFile: aNibName externalNameTable: table withZone: [owner zone]] == YES) { return YES; } else { bundle = [self mainBundle]; } return [bundle loadNibFile: aNibName externalNameTable: table withZone: [owner zone]]; } - (NSString *) pathForNibResource: (NSString *)fileName { NSEnumerator *enumerator; NSArray *types = [GSModelLoaderFactory supportedTypes]; NSString *ext = [fileName pathExtension]; NSDebugLLog(@"NIB", @"Path for NIB file %@", fileName); if ((ext == nil) || [ext isEqualToString:@""]) { NSString *type; enumerator = [types objectEnumerator]; while ((type = [enumerator nextObject])) { NSDebugLLog(@"NIB", @"Checking type %@", type); NSString *path = [self pathForResource: fileName ofType: type]; if (path != nil) { return path; } } } else { if ([types containsObject: ext]) { NSString *path = [self pathForResource: [fileName stringByDeletingPathExtension] ofType: ext]; if (path != nil) { return path; } } } NSDebugLLog(@"NIB", @"Did not find NIB resource %@", fileName); return nil; } - (BOOL) loadNibFile: (NSString*)fileName externalNameTable: (NSDictionary*)context withZone: (NSZone*)zone { NSString *path = [self pathForNibResource: fileName]; if (path != nil) { return [NSBundle loadNibFile: path externalNameTable: context withZone: (NSZone*)zone]; } else { return NO; } } - (BOOL) loadNibNamed: (NSString *)aNibName owner: (id)owner topLevelObjects: (NSArray **)topLevelObjects { BOOL success = NO; if (owner != nil && aNibName != nil) { NSDictionary *table = nil; NSMutableArray *tlo = nil; // Based on the arguments above, set up the table appropriately... if (owner != nil) { if (topLevelObjects != NULL) { // Here we initialize the array, it is sent in using the dictionary. // In the code below it is pulled back out and assigned to the // reference in the arguments. tlo = [NSMutableArray array]; table = [NSDictionary dictionaryWithObjectsAndKeys: owner, NSNibOwner, tlo, NSNibTopLevelObjects, nil]; } else { table = [NSDictionary dictionaryWithObject: owner forKey: NSNibOwner]; } } // Attempt to load the model file... success = [self loadNibFile: aNibName externalNameTable: table withZone: [owner zone]]; // When using the newer topLevelObjects API, conform to the cocoa standard of letting the caller own // the TLOs these were previously retained by [GSXibLoader awake:withContext:] so we need to // autorelease them. See cocoa docs for loadNibNamed:owner:topLevelObjects: if (success && topLevelObjects && [table objectForKey: NSNibTopLevelObjects]) { *topLevelObjects = [table objectForKey: NSNibTopLevelObjects]; NSEnumerator *en = [*topLevelObjects objectEnumerator]; id obj = nil; while ((obj = [en nextObject]) != nil) { AUTORELEASE(obj); } } } return success; } @end // end of NSBundleAdditions