mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-23 09:51:08 +00:00
Rewrite of top level object handling in NIB/Gorm/Xib loading.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@30070 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
d1c9ba660b
commit
504a5c2064
8 changed files with 55 additions and 84 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2010-03-28 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Headers/AppKit/NSNib.h,
|
||||
* Source/externs.m: Define new string constants NSNibOwner and NSNibTopLevelObjects.
|
||||
* Source/NSBundleAdditions.m,
|
||||
* Source/NSNib.m: Use these constants.
|
||||
* Source/GSNibLoading.m,
|
||||
* Source/GSGormLoading.m,
|
||||
* Source/GSXibLoader.m: Rewrite of top level objects handling to
|
||||
fit documentations as cited by Wolfgang Lux <wolfgang.lux@gmail.com>.
|
||||
|
||||
2010-03-28 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Source/NSPasteboard.m (-writeObjects:): Add a return statement
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
#import <Foundation/NSObject.h>
|
||||
#import <Foundation/NSZone.h>
|
||||
#import <AppKit/AppKitDefines.h>
|
||||
|
||||
@class NSData;
|
||||
@class NSDictionary;
|
||||
|
@ -54,6 +55,9 @@
|
|||
@class NSArray;
|
||||
@class NSMutableArray;
|
||||
|
||||
APPKIT_EXPORT NSString *NSNibTopLevelObjects;
|
||||
APPKIT_EXPORT NSString *NSNibOwner;
|
||||
|
||||
@interface NSNib : NSObject <NSCoding>
|
||||
{
|
||||
NSData *_nibData;
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#import "AppKit/NSApplication.h"
|
||||
#import "AppKit/NSControl.h"
|
||||
#import "AppKit/NSMenu.h"
|
||||
#import "AppKit/NSNib.h"
|
||||
#import "AppKit/NSNibLoading.h"
|
||||
#import "AppKit/NSNibConnector.h"
|
||||
#import "AppKit/NSScreen.h"
|
||||
|
@ -156,16 +157,8 @@ static NSString *GSInternalNibItemAddedNotification = @"_GSInternalNibItemAddedN
|
|||
|
||||
// Add these objects with there old names as the code expects them
|
||||
context = AUTORELEASE([context mutableCopyWithZone: [context zone]]);
|
||||
obj = [context objectForKey: @"NSNibTopLevelObjects"];
|
||||
if (obj != nil)
|
||||
{
|
||||
[(NSMutableDictionary*)context setObject: obj forKey: @"NSTopLevelObjects"];
|
||||
}
|
||||
obj = [context objectForKey: @"NSNibOwner"];
|
||||
if (obj != nil)
|
||||
{
|
||||
[(NSMutableDictionary*)context setObject: obj forKey: @"NSOwner"];
|
||||
}
|
||||
obj = [context objectForKey: NSNibTopLevelObjects];
|
||||
obj = [context objectForKey: NSNibOwner];
|
||||
|
||||
isAwake = YES;
|
||||
/*
|
||||
|
@ -226,12 +219,11 @@ static NSString *GSInternalNibItemAddedNotification = @"_GSInternalNibItemAddedN
|
|||
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* See if the user has passed in the NSNibTopLevelObjects key.
|
||||
* This is an implementation of a commonly used feature to give access to
|
||||
* all top level objects of a nib file.
|
||||
*/
|
||||
obj = [context objectForKey: @"NSTopLevelObjects"];
|
||||
obj = [context objectForKey: NSNibTopLevelObjects];
|
||||
if ([obj isKindOfClass: [NSMutableArray class]])
|
||||
{
|
||||
topObjects = obj;
|
||||
|
@ -250,12 +242,12 @@ static NSString *GSInternalNibItemAddedNotification = @"_GSInternalNibItemAddedN
|
|||
while ((key = [enumerator nextObject]) != nil)
|
||||
{
|
||||
if ([context objectForKey: key] == nil ||
|
||||
[key isEqualToString: @"NSOwner"]) // we want to send the message to the owner
|
||||
[key isEqualToString: NSNibOwner]) // we want to send the message to the owner
|
||||
{
|
||||
// we don't want to send a message to these menus twice, if they're custom classes.
|
||||
if ([key isEqualToString: @"NSWindowsMenu"] == NO &&
|
||||
[key isEqualToString: @"NSServicesMenu"] == NO &&
|
||||
[key isEqualToString: @"NSTopLevelObjects"] == NO)
|
||||
[key isEqualToString: NSNibTopLevelObjects] == NO)
|
||||
{
|
||||
id o = [nameTable objectForKey: key];
|
||||
|
||||
|
@ -272,30 +264,22 @@ static NSString *GSInternalNibItemAddedNotification = @"_GSInternalNibItemAddedN
|
|||
* We don't want to retain the owner.
|
||||
*
|
||||
* Please note: It is encumbent upon the developer of an application to
|
||||
* release these objects. Instantiating a window manually or loading in a .gorm
|
||||
* file are equivalent processes. These objects need to be released in their
|
||||
* respective controllers. If the developer has used the "NSTopLevelObjects" feature,
|
||||
* then he will get the objects back in an array which he merely must release in
|
||||
* order to release the objects held within. GJC
|
||||
* release these objects. Instantiating a window manually or loading in a .gorm
|
||||
* file are equivalent processes. These objects need to be released in their
|
||||
* respective controllers. If the developer has used the NSNibTopLevelObjects feature,
|
||||
* then she will get the objects back in an array. She will will have to first release
|
||||
* all the objects in the array and then the array itself in order to release the
|
||||
* objects held within.
|
||||
*/
|
||||
if ([key isEqualToString: @"NSOwner"] == NO)
|
||||
if ([key isEqualToString: NSNibOwner] == 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];
|
||||
}
|
||||
[topObjects addObject: o];
|
||||
// All top level objects (that are not retained and
|
||||
// released by other nib objects) must be released by
|
||||
// the caller to avoid leaking.
|
||||
RETAIN(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
#import "AppKit/NSImage.h"
|
||||
#import "AppKit/NSMenuItem.h"
|
||||
#import "AppKit/NSMenuView.h"
|
||||
#import "AppKit/NSNib.h"
|
||||
#import "AppKit/NSScreen.h"
|
||||
#import "AppKit/NSSound.h"
|
||||
#import "GNUstepGUI/GSInstantiator.h"
|
||||
|
@ -1909,15 +1910,10 @@ static BOOL _isInInterfaceBuilder = NO;
|
|||
// Object is top level if it isn't the owner but points to it.
|
||||
if ((v == owner || v == _root) && (obj != owner) && (obj != _root))
|
||||
{
|
||||
if (topLevelObjects == nil)
|
||||
{
|
||||
// When there is no top level object array, just retain these objects
|
||||
RETAIN(obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
[topLevelObjects addObject: obj];
|
||||
}
|
||||
[topLevelObjects addObject: obj];
|
||||
// All top level objects must be released by
|
||||
// the caller to avoid leaking.
|
||||
RETAIN(obj);
|
||||
}
|
||||
|
||||
// awaken the object.
|
||||
|
@ -1950,19 +1946,8 @@ static BOOL _isInInterfaceBuilder = NO;
|
|||
*/
|
||||
- (void) awakeWithContext: (NSDictionary *)context
|
||||
{
|
||||
NSMutableArray *tlo = [context objectForKey: @"NSTopLevelObjects"];
|
||||
id owner = [context objectForKey: @"NSOwner"];
|
||||
|
||||
// get using the alternate names.
|
||||
if (tlo == nil)
|
||||
{
|
||||
tlo = [context objectForKey: @"NSNibTopLevelObjects"];
|
||||
}
|
||||
|
||||
if (owner == nil)
|
||||
{
|
||||
owner = [context objectForKey: @"NSNibOwner"];
|
||||
}
|
||||
NSMutableArray *tlo = [context objectForKey: NSNibTopLevelObjects];
|
||||
id owner = [context objectForKey: NSNibOwner];
|
||||
|
||||
// instantiate...
|
||||
[self nibInstantiateWithOwner: owner topLevelObjects: tlo];
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#import <GNUstepBase/GSMime.h>
|
||||
|
||||
#import "AppKit/NSApplication.h"
|
||||
#import "AppKit/NSNib.h"
|
||||
#import "AppKit/NSNibLoading.h"
|
||||
#import "GNUstepGUI/GSModelLoaderFactory.h"
|
||||
#import "GNUstepGUI/GSNibLoading.h"
|
||||
|
@ -576,19 +577,8 @@
|
|||
NSEnumerator *en;
|
||||
id obj;
|
||||
IBObjectContainer *objects;
|
||||
NSMutableArray *topLevelObjects = [context objectForKey: @"NSTopLevelObjects"];
|
||||
id owner = [context objectForKey: @"NSOwner"];
|
||||
|
||||
// get using the alternate names.
|
||||
if (topLevelObjects == nil)
|
||||
{
|
||||
topLevelObjects = [context objectForKey: @"NSNibTopLevelObjects"];
|
||||
}
|
||||
|
||||
if (owner == nil)
|
||||
{
|
||||
owner = [context objectForKey: @"NSNibOwner"];
|
||||
}
|
||||
NSMutableArray *topLevelObjects = [context objectForKey: NSNibTopLevelObjects];
|
||||
//id owner = [context objectForKey: NSNibOwner];
|
||||
|
||||
objects = [data objectForKey: @"IBDocument.Objects"];
|
||||
[objects nibInstantiate];
|
||||
|
@ -602,15 +592,8 @@
|
|||
if ([obj respondsToSelector: @selector(nibInstantiate)])
|
||||
{
|
||||
obj = [obj nibInstantiate];
|
||||
if (topLevelObjects == nil)
|
||||
{
|
||||
// When there is no top level object array, just retain these objects
|
||||
RETAIN(obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
[topLevelObjects addObject: obj];
|
||||
}
|
||||
[topLevelObjects addObject: obj];
|
||||
RETAIN(obj);
|
||||
}
|
||||
|
||||
// instantiate all windows and fill in the top level array.
|
||||
|
|
|
@ -249,7 +249,7 @@
|
|||
{
|
||||
return NO;
|
||||
}
|
||||
table = [NSDictionary dictionaryWithObject: owner forKey: @"NSNibOwner"];
|
||||
table = [NSDictionary dictionaryWithObject: owner forKey: NSNibOwner];
|
||||
|
||||
/*
|
||||
* First look for the NIB in the bundle corresponding to the owning class,
|
||||
|
|
|
@ -178,12 +178,12 @@
|
|||
NSMutableDictionary *externalNameTable = [NSMutableDictionary dictionary];
|
||||
|
||||
// add the necessary things to the table...
|
||||
[externalNameTable setObject: owner forKey: @"NSNibOwner"];
|
||||
[externalNameTable setObject: owner forKey: NSNibOwner];
|
||||
|
||||
if (topLevelObjects != 0)
|
||||
{
|
||||
*topLevelObjects = [NSMutableArray array];
|
||||
[externalNameTable setObject: *topLevelObjects forKey: @"NSNibTopLevelObjects"];
|
||||
[externalNameTable setObject: *topLevelObjects forKey: NSNibTopLevelObjects];
|
||||
}
|
||||
|
||||
return [self instantiateNibWithExternalNameTable: externalNameTable];
|
||||
|
|
|
@ -659,6 +659,10 @@ id NSNoSelectionMarker = @"NSNoSelectionMarker";
|
|||
id NSNotApplicableMarker = @"NSNotApplicableMarker";
|
||||
|
||||
|
||||
// NSNib
|
||||
NSString *NSNibTopLevelObjects = @"NSTopLevelObjects";
|
||||
NSString *NSNibOwner = @"NSOwner";
|
||||
|
||||
extern void __objc_gui_force_linking (void);
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue