Merge branch 'master' of github.com:gnustep/libs-gui into NSStoryboard_branch

This commit is contained in:
Gregory John Casamento 2020-01-24 19:05:13 -05:00
commit 06a38acd43
6 changed files with 107 additions and 132 deletions

View file

@ -1,3 +1,13 @@
2020-01-23 Fred Kiefer <FredKiefer@gmx.de>
* Source/GSXib5KeyedUnarchiver.m: Remove NSWindowTemplate5.
* Source/GSXibLoader.m: Clean up code.
* Headers/Additions/GNUstepGUI/GSXibKeyedUnarchiver.h,
* Source/GSXibKeyedUnarchiver.m: Provide method to load both sorts
of XIB files.
* Source/NSArrayController.m: Add horrible hack to get KVB on
array controller to work.
2020-01-22 Fred Kiefer <FredKiefer@gmx.de> 2020-01-22 Fred Kiefer <FredKiefer@gmx.de>
* Source/GSXib5KeyedUnarchiver.m, * Source/GSXib5KeyedUnarchiver.m,

View file

@ -43,6 +43,9 @@
NSMutableDictionary *decoded; NSMutableDictionary *decoded;
} }
+ (BOOL) checkXib5: (NSData *)data;
+ (NSKeyedUnarchiver *) unarchiverForReadingWithData: (NSData *)data;
- (void) _initCommon; - (void) _initCommon;
- (id) decodeObjectForXib: (GSXibElement*)element - (id) decodeObjectForXib: (GSXibElement*)element
forClassName: (NSString*)classname forClassName: (NSString*)classname

View file

@ -113,50 +113,6 @@ static NSString *ApplicationClass = nil;
@end @end
@interface NSWindowTemplate5 : NSWindowTemplate
{
BOOL _visibleAtLaunch;
}
@end
@implementation NSWindowTemplate5
- (id) initWithCoder: (NSCoder *)coder
{
self = [super initWithCoder: coder];
if (self)
{
_visibleAtLaunch = YES;
if ([coder containsValueForKey: @"visibleAtLaunch"])
{
_visibleAtLaunch = [coder decodeBoolForKey: @"visibleAtLaunch"];
}
}
return self;
}
- (id) nibInstantiate
{
if (_realObject == nil)
{
// Instantiate the real object...
[super nibInstantiate];
// >= XIB 5 - startup visible windows...
if (_visibleAtLaunch)
{
// bring visible windows to front...
[(NSWindow *)_realObject orderFront: self];
}
}
return _realObject;
}
@end
@interface IBActionConnection5 : IBActionConnection @interface IBActionConnection5 : IBActionConnection
{ {
NSString *trigger; NSString *trigger;
@ -360,7 +316,7 @@ static NSArray *XmlBoolDefaultYes = nil;
@"IBOutletConnection5", @"outlet", @"IBOutletConnection5", @"outlet",
@"IBActionConnection5", @"action", @"IBActionConnection5", @"action",
@"NSNibBindingConnector", @"binding", @"NSNibBindingConnector", @"binding",
@"NSWindowTemplate5", @"window", @"NSWindowTemplate", @"window",
@"NSView", @"tableCellView", @"NSView", @"tableCellView",
@"IBUserDefinedRuntimeAttribute5", @"userDefinedRuntimeAttribute", @"IBUserDefinedRuntimeAttribute5", @"userDefinedRuntimeAttribute",
nil]; nil];
@ -631,7 +587,7 @@ static NSArray *XmlBoolDefaultYes = nil;
if (parentId == nil) if (parentId == nil)
{ {
NSLog(@"Missing parent Id for connection on parent @%", parent); NSLog(@"Missing parent Id for connection on parent %@", parent);
// Fake an id for parent // Fake an id for parent
parentId = [[NSUUID UUID] UUIDString]; parentId = [[NSUUID UUID] UUIDString];
[parent setAttribute: parentId forKey: @"id"]; [parent setAttribute: parentId forKey: @"id"];
@ -700,9 +656,14 @@ static NSArray *XmlBoolDefaultYes = nil;
return AUTORELEASE(objectRecord); return AUTORELEASE(objectRecord);
} }
- (void) addRuntimeAttributesForElement: (GSXibElement*)element forID: (NSString*)idString - (NSString*) getRefIDFor: (GSXibElement*)element postFix: (NSString*)postfix
{
id orderedObject = [_orderedObjectsDict objectForKey: [element attributeForKey: @"id"]];
return [NSString stringWithFormat: @"%@.%@", [orderedObject attributeForKey: @"id"], postfix];
}
- (void) addRuntimeAttributesForElement: (GSXibElement*)element forID: (NSString*)refID
{ {
NSString *refID = [NSString stringWithFormat: @"%@.IBAttributePlaceholdersKey", idString];
GSXibElement *objectRecord = (GSXibElement*)[_flattenedProperties elementForKey: refID]; GSXibElement *objectRecord = (GSXibElement*)[_flattenedProperties elementForKey: refID];
// Mimic the old IBAttributePlaceholders instance... // Mimic the old IBAttributePlaceholders instance...
@ -2946,8 +2907,24 @@ didStartElement: (NSString*)elementName
{ {
// Create the flattened property data for the runtime attributes in the OLD XIB format... // Create the flattened property data for the runtime attributes in the OLD XIB format...
id runtimeAttributes = [element elementForKey: @"userDefinedRuntimeAttributes"]; id runtimeAttributes = [element elementForKey: @"userDefinedRuntimeAttributes"];
id orderedObject = [_orderedObjectsDict objectForKey: [element attributeForKey: @"id"]]; NSString *refID = [self getRefIDFor: element postFix: @"%IBAttributePlaceholdersKey"];
[self addRuntimeAttributesForElement: runtimeAttributes forID: [orderedObject attributeForKey: @"id"]];
[self addRuntimeAttributesForElement: runtimeAttributes forID: refID];
}
else if ([[element attributeForKey: @"key"] isEqualToString: @"window"])
{
NSString *refID = [self getRefIDFor: element postFix: @"NSWindowTemplate.visibleAtLaunch"];
id runtimeAttribute = [[GSXibElement alloc] initWithType: @"string"
andAttributes: nil];
id visibleAtLaunch = [element attributeForKey: @"visibleAtLaunch"];
if (visibleAtLaunch == nil)
{
visibleAtLaunch = @"YES";
}
[runtimeAttribute setValue: visibleAtLaunch];
[_flattenedProperties setElement: runtimeAttribute forKey: refID];
} }
return object; return object;

View file

@ -34,12 +34,55 @@
Boston, MA 02110-1301, USA. Boston, MA 02110-1301, USA.
*/ */
#import <Foundation/NSXMLDocument.h>
#import "GNUstepGUI/GSXibKeyedUnarchiver.h" #import "GNUstepGUI/GSXibKeyedUnarchiver.h"
#import "GNUstepGUI/GSXibElement.h" #import "GNUstepGUI/GSXibElement.h"
#import "GNUstepGUI/GSNibLoading.h" #import "GNUstepGUI/GSNibLoading.h"
#import "GSXib5KeyedUnarchiver.h"
@implementation GSXibKeyedUnarchiver @implementation GSXibKeyedUnarchiver
+ (BOOL) checkXib5: (NSData *)data
{
#if GNUSTEP_BASE_HAVE_LIBXML
// Ensure we have a XIB 5 version...first see if we can parse the XML...
NSXMLDocument *document = [[NSXMLDocument alloc] initWithData: data
options: 0
error: NULL];
if (document == nil)
{
return NO;
}
else
{
// Test to see if this is an Xcode 5 XIB...
NSArray *documentNodes = [document nodesForXPath: @"/document" error: NULL];
// Need at LEAST ONE document node...we should find something a bit more
// specific to check here...
return [documentNodes count] != 0;
}
#else
// We now default to checking XIB 5 versions
return YES;
#endif
}
+ (NSKeyedUnarchiver *) unarchiverForReadingWithData: (NSData *)data
{
NSKeyedUnarchiver *unarchiver = nil;
if ([self checkXib5: data])
{
unarchiver = [[GSXib5KeyedUnarchiver alloc] initForReadingWithData: data];
}
else
{
unarchiver = [[GSXibKeyedUnarchiver alloc] initForReadingWithData: data];
}
return AUTORELEASE(unarchiver);
}
- (NSData *) _preProcessXib: (NSData *)data - (NSData *) _preProcessXib: (NSData *)data
{ {
NSData *result = data; NSData *result = data;

View file

@ -35,7 +35,6 @@
#import <Foundation/NSKeyValueCoding.h> #import <Foundation/NSKeyValueCoding.h>
#import <Foundation/NSString.h> #import <Foundation/NSString.h>
#import <Foundation/NSValue.h> #import <Foundation/NSValue.h>
#import <Foundation/NSXMLDocument.h>
#import "AppKit/NSApplication.h" #import "AppKit/NSApplication.h"
#import "AppKit/NSMenu.h" #import "AppKit/NSMenu.h"
@ -44,7 +43,6 @@
#import "GNUstepGUI/GSNibLoading.h" #import "GNUstepGUI/GSNibLoading.h"
#import "GNUstepGUI/GSXibLoading.h" #import "GNUstepGUI/GSXibLoading.h"
#import "GNUstepGUI/GSXibKeyedUnarchiver.h" #import "GNUstepGUI/GSXibKeyedUnarchiver.h"
#import "GSXib5KeyedUnarchiver.h"
@interface NSApplication (NibCompatibility) @interface NSApplication (NibCompatibility)
- (void) _setMainMenu: (NSMenu*)aMenu; - (void) _setMainMenu: (NSMenu*)aMenu;
@ -85,14 +83,11 @@
- (void) awake: (NSArray *)rootObjects - (void) awake: (NSArray *)rootObjects
withContext: (NSDictionary *)context withContext: (NSDictionary *)context
{ {
NSEnumerator *en;
id obj;
NSMutableArray *topLevelObjects = [context objectForKey: NSNibTopLevelObjects]; NSMutableArray *topLevelObjects = [context objectForKey: NSNibTopLevelObjects];
id owner = [context objectForKey: NSNibOwner]; id owner = [context objectForKey: NSNibOwner];
id first = nil; NSEnumerator *en;
id app = nil; id obj;
NSCustomObject *object; NSUInteger index = 0;
NSString *className;
if ([rootObjects count] == 0) if ([rootObjects count] == 0)
{ {
@ -100,42 +95,21 @@
return; return;
} }
// Get the file's owner and NSApplication object references...
object = (NSCustomObject*)[rootObjects objectAtIndex: 1];
if ([[object className] isEqualToString: @"FirstResponder"])
{
first = [object realObject];
}
else
{
NSLog(@"%s:first responder missing\n", __PRETTY_FUNCTION__);
}
object = (NSCustomObject*)[rootObjects objectAtIndex: 2];
className = [object className];
if ([className isEqualToString: @"NSApplication"] ||
[NSClassFromString(className) isSubclassOfClass:[NSApplication class]])
{
app = [object realObject];
}
else
{
NSLog(@"%s:NSApplication missing '%@'\n", __PRETTY_FUNCTION__, className);
}
// Use the owner as first root object // Use the owner as first root object
[(NSCustomObject*)[rootObjects objectAtIndex: 0] setRealObject: owner]; [(NSCustomObject*)[rootObjects objectAtIndex: 0] setRealObject: owner];
en = [rootObjects objectEnumerator]; en = [rootObjects objectEnumerator];
while ((obj = [en nextObject]) != nil) while ((obj = [en nextObject]) != nil)
{ {
index++;
if ([obj respondsToSelector: @selector(nibInstantiate)]) if ([obj respondsToSelector: @selector(nibInstantiate)])
{ {
obj = [obj nibInstantiate]; obj = [obj nibInstantiate];
} }
// IGNORE file's owner, first responder and NSApplication instances... // IGNORE file's owner, first responder and NSApplication instances...
if ((obj != nil) && (obj != owner) && (obj != first) && (obj != app)) if ((obj != nil) && (index > 3))
{ {
[topLevelObjects addObject: obj]; [topLevelObjects addObject: obj];
// All top level objects must be released by the caller to avoid // All top level objects must be released by the caller to avoid
@ -166,51 +140,17 @@
} }
} }
- (BOOL) checkXib5: (NSData *)data
{
#if GNUSTEP_BASE_HAVE_LIBXML
// Ensure we have a XIB 5 version...first see if we can parse the XML...
NSXMLDocument *document = [[NSXMLDocument alloc] initWithData: data
options: 0
error: NULL];
if (document == nil)
{
return NO;
}
else
{
// Test to see if this is an Xcode 5 XIB...
NSArray *documentNodes = [document nodesForXPath: @"/document" error: NULL];
// Need at LEAST ONE document node...we should find something a bit more
// specific to check here...
return [documentNodes count] != 0;
}
#else
// We now default to checking XIB 5 versions
return YES;
#endif
}
- (BOOL) loadModelData: (NSData *)data - (BOOL) loadModelData: (NSData *)data
externalNameTable: (NSDictionary *)context externalNameTable: (NSDictionary *)context
withZone: (NSZone *)zone; withZone: (NSZone *)zone;
{ {
BOOL loaded = NO; BOOL loaded = NO;
NSKeyedUnarchiver *unarchiver = nil;
NS_DURING NS_DURING
{ {
if (data != nil) if (data != nil)
{ {
if ([self checkXib5: data]) NSKeyedUnarchiver *unarchiver = [GSXibKeyedUnarchiver unarchiverForReadingWithData: data];
{
unarchiver = [[GSXib5KeyedUnarchiver alloc] initForReadingWithData: data];
}
else
{
unarchiver = [[GSXibKeyedUnarchiver alloc] initForReadingWithData: data];
}
if (unarchiver != nil) if (unarchiver != nil)
{ {
@ -226,7 +166,6 @@
inContainer: objects inContainer: objects
withContext: context]; withContext: context];
loaded = YES; loaded = YES;
RELEASE(unarchiver);
} }
else else
{ {
@ -241,7 +180,6 @@
NS_HANDLER NS_HANDLER
{ {
NSLog(@"Exception occurred while loading model: %@",[localException reason]); NSLog(@"Exception occurred while loading model: %@",[localException reason]);
// TEST_RELEASE(unarchiver);
} }
NS_ENDHANDLER NS_ENDHANDLER

View file

@ -2,7 +2,7 @@
<abstract>Controller class for arrays</abstract> <abstract>Controller class for arrays</abstract>
Copyright <copy>(C) 2006 Free Software Foundation, Inc.</copy> Copyright <copy>(C) 2006, 2020 Free Software Foundation, Inc.</copy>
Author: Fred Kiefer <fredkiefer@gmx.de> Author: Fred Kiefer <fredkiefer@gmx.de>
Date: June 2006 Date: June 2006
@ -88,7 +88,11 @@
if ([result isKindOfClass: [NSArray class]]) if ([result isKindOfClass: [NSArray class]])
{ {
return AUTORELEASE([[GSObservableArray alloc] // FIXME: Using the correct memory management here
// Leads to an issue inside of KVO. For now we leak the
// object until this gets fixed.
//return AUTORELEASE([[GSObservableArray alloc]
return ([[GSObservableArray alloc]
initWithArray: result]); initWithArray: result]);
} }
@ -152,7 +156,6 @@
{ {
if ((self = [super initWithContent: content]) != nil) if ((self = [super initWithContent: content]) != nil)
{ {
[self rearrangeObjects];
[self setSelectsInsertedObjects: YES]; [self setSelectsInsertedObjects: YES];
} }
@ -187,8 +190,7 @@
} }
else else
{ {
// FIXME: Should check whether _arranged_objects is mutable DESTROY(_arranged_objects);
ASSIGN(_arranged_objects, [_arranged_objects arrayByAddingObject: obj]);
} }
if ([self selectsInsertedObjects]) if ([self selectsInsertedObjects])
{ {
@ -207,8 +209,7 @@
} }
else else
{ {
// FIXME: Should check whether _arranged_objects is mutable DESTROY(_arranged_objects);
ASSIGN(_arranged_objects, [_arranged_objects arrayByAddingObjectsFromArray: obj]);
} }
if ([self selectsInsertedObjects]) if ([self selectsInsertedObjects])
{ {
@ -228,8 +229,7 @@
} }
else else
{ {
// FIXME DESTROY(_arranged_objects);
//[_arranged_objects removeObject: obj];
} }
[self didChangeValueForKey: NSContentBinding]; [self didChangeValueForKey: NSContentBinding];
} }
@ -245,8 +245,7 @@
} }
else else
{ {
// FIXME DESTROY(_arranged_objects);
//[_arranged_objects removeObjectsInArray: obj];
} }
[self didChangeValueForKey: NSContentBinding]; [self didChangeValueForKey: NSContentBinding];
} }
@ -385,7 +384,7 @@
- (NSArray*) selectedObjects - (NSArray*) selectedObjects
{ {
// We make the selection work on the arranged objects // We make the selection work on the arranged objects
return [_arranged_objects objectsAtIndexes: _selection_indexes]; return [[self arrangedObjects] objectsAtIndexes: _selection_indexes];
} }
- (NSUInteger) selectionIndex - (NSUInteger) selectionIndex
@ -472,14 +471,19 @@
- (id) arrangedObjects - (id) arrangedObjects
{ {
if (_arranged_objects == nil)
{
[self rearrangeObjects];
}
return _arranged_objects; return _arranged_objects;
} }
- (void) rearrangeObjects - (void) rearrangeObjects
{ {
[self willChangeValueForKey: @"arrangedObjects"]; [self willChangeValueForKey: @"arrangedObjects"];
DESTROY(_arranged_objects);
_arranged_objects = [[GSObservableArray alloc] _arranged_objects = [[GSObservableArray alloc]
initWithArray: [self arrangeObjects: _content]]; initWithArray: [self arrangeObjects: _content]];
[self didChangeValueForKey: @"arrangedObjects"]; [self didChangeValueForKey: @"arrangedObjects"];
} }