mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-31 17:01:07 +00:00
Fix to ignore storyboard instantiation with blank id, refactoring on another branch
This commit is contained in:
parent
7850f8e61b
commit
e97aee7bca
1 changed files with 98 additions and 98 deletions
|
@ -1,21 +1,21 @@
|
||||||
/* Implementation of class NSStoryboard
|
/* Implementation of class NSStoryboard
|
||||||
Copyright (C) 2020 Free Software Foundation, Inc.
|
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
By: Gregory Casamento
|
By: Gregory Casamento
|
||||||
Date: Mon Jan 20 15:57:37 EST 2020
|
Date: Mon Jan 20 15:57:37 EST 2020
|
||||||
|
|
||||||
This file is part of the GNUstep Library.
|
This file is part of the GNUstep Library.
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Lesser General Public
|
modify it under the terms of the GNU Lesser General Public
|
||||||
License as published by the Free Software Foundation; either
|
License as published by the Free Software Foundation; either
|
||||||
version 2 of the License, or (at your option) any later version.
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
This library is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
Lesser General Public License for more details.
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
You should have received a copy of the GNU Lesser General Public
|
||||||
License along with this library; if not, write to the Free
|
License along with this library; if not, write to the Free
|
||||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
@ -105,13 +105,13 @@ static NSStoryboard *__mainStoryboard = nil;
|
||||||
|
|
||||||
// Private instance methods...
|
// Private instance methods...
|
||||||
- (id) initWithName: (NSStoryboardName)name
|
- (id) initWithName: (NSStoryboardName)name
|
||||||
bundle: (NSBundle *)bundle
|
bundle: (NSBundle *)bundle
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (self != nil)
|
if (self != nil)
|
||||||
{
|
{
|
||||||
NSString *path = [bundle pathForResource: name
|
NSString *path = [bundle pathForResource: name
|
||||||
ofType: @"storyboard"];
|
ofType: @"storyboard"];
|
||||||
NSData *data = [NSData dataWithContentsOfFile: path];
|
NSData *data = [NSData dataWithContentsOfFile: path];
|
||||||
_transform = [[GSStoryboardTransform alloc] initWithData: data];
|
_transform = [[GSStoryboardTransform alloc] initWithData: data];
|
||||||
}
|
}
|
||||||
|
@ -133,10 +133,10 @@ static NSStoryboard *__mainStoryboard = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (instancetype) storyboardWithName: (NSStoryboardName)name
|
+ (instancetype) storyboardWithName: (NSStoryboardName)name
|
||||||
bundle: (NSBundle *)bundle
|
bundle: (NSBundle *)bundle
|
||||||
{
|
{
|
||||||
return AUTORELEASE([[NSStoryboard alloc] initWithName: name
|
return AUTORELEASE([[NSStoryboard alloc] initWithName: name
|
||||||
bundle: bundle]);
|
bundle: bundle]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instance methods...
|
// Instance methods...
|
||||||
|
@ -159,112 +159,112 @@ static NSStoryboard *__mainStoryboard = nil;
|
||||||
- (id) instantiateInitialControllerWithCreator: (NSStoryboardControllerCreator)block
|
- (id) instantiateInitialControllerWithCreator: (NSStoryboardControllerCreator)block
|
||||||
{
|
{
|
||||||
return [self instantiateControllerWithIdentifier: [_transform initialViewControllerId]
|
return [self instantiateControllerWithIdentifier: [_transform initialViewControllerId]
|
||||||
creator: block];
|
creator: block];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) instantiateControllerWithIdentifier: (NSStoryboardSceneIdentifier)identifier
|
- (id) instantiateControllerWithIdentifier: (NSStoryboardSceneIdentifier)identifier
|
||||||
{
|
{
|
||||||
if (identifier != nil)
|
return [self instantiateControllerWithIdentifier: identifier
|
||||||
{
|
|
||||||
return [self instantiateControllerWithIdentifier: identifier
|
|
||||||
creator: nil];
|
creator: nil];
|
||||||
}
|
|
||||||
|
|
||||||
return nil;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) instantiateControllerWithIdentifier: (NSStoryboardSceneIdentifier)identifier
|
- (id) instantiateControllerWithIdentifier: (NSStoryboardSceneIdentifier)identifier
|
||||||
creator: (NSStoryboardControllerCreator)block
|
creator: (NSStoryboardControllerCreator)block
|
||||||
{
|
{
|
||||||
id result = nil;
|
id result = nil;
|
||||||
NSMutableArray *topLevelObjects = [NSMutableArray arrayWithCapacity: 5];
|
|
||||||
NSDictionary *table = [NSDictionary dictionaryWithObjectsAndKeys: topLevelObjects,
|
if (identifier != nil)
|
||||||
NSNibTopLevelObjects,
|
|
||||||
NSApp,
|
|
||||||
NSNibOwner,
|
|
||||||
nil];
|
|
||||||
GSModelLoader *loader = [GSModelLoaderFactory modelLoaderForFileType: @"xib"];
|
|
||||||
BOOL success = [loader loadModelData: [_transform dataForIdentifier: identifier]
|
|
||||||
externalNameTable: table
|
|
||||||
withZone: [self zone]];
|
|
||||||
|
|
||||||
if (success)
|
|
||||||
{
|
{
|
||||||
NSMutableArray *seguesToPerform = [NSMutableArray array];
|
NSMutableArray *topLevelObjects = [NSMutableArray arrayWithCapacity: 5];
|
||||||
NSMapTable *segueMap = [_transform segueMapForIdentifier: identifier];
|
NSDictionary *table = [NSDictionary dictionaryWithObjectsAndKeys: topLevelObjects,
|
||||||
NSWindowController *wc = nil;
|
NSNibTopLevelObjects,
|
||||||
NSViewController *vc = nil;
|
NSApp,
|
||||||
NSWindow *w = nil;
|
NSNibOwner,
|
||||||
|
nil];
|
||||||
FOR_IN(id, o, topLevelObjects)
|
GSModelLoader *loader = [GSModelLoaderFactory modelLoaderForFileType: @"xib"];
|
||||||
if ([o isKindOfClass: [NSWindowController class]])
|
BOOL success = [loader loadModelData: [_transform dataForIdentifier: identifier]
|
||||||
{
|
externalNameTable: table
|
||||||
wc = (NSWindowController *)o;
|
withZone: [self zone]];
|
||||||
[wc _setSegueMap: segueMap];
|
|
||||||
[wc _setTopLevelObjects: topLevelObjects];
|
|
||||||
[wc _setStoryboard: self];
|
|
||||||
[wc _setOwner: NSApp];
|
|
||||||
result = o;
|
|
||||||
}
|
|
||||||
else if ([o isKindOfClass: [NSViewController class]])
|
|
||||||
{
|
|
||||||
vc = (NSViewController *)o;
|
|
||||||
[vc _setSegueMap: segueMap];
|
|
||||||
[vc _setTopLevelObjects: topLevelObjects];
|
|
||||||
[vc _setStoryboard: self];
|
|
||||||
result = o;
|
|
||||||
}
|
|
||||||
else if ([o isKindOfClass: [NSWindow class]])
|
|
||||||
{
|
|
||||||
w = (NSWindow *)o;
|
|
||||||
}
|
|
||||||
else if ([o isKindOfClass: [NSControllerPlaceholder class]])
|
|
||||||
{
|
|
||||||
NSControllerPlaceholder *ph = (NSControllerPlaceholder *)o;
|
|
||||||
result = [ph instantiate];
|
|
||||||
}
|
|
||||||
END_FOR_IN(topLevelObjects);
|
|
||||||
|
|
||||||
// Process action proxies after so we know we have the windowController...
|
if (success)
|
||||||
FOR_IN(id, o, topLevelObjects)
|
{
|
||||||
if ([o isKindOfClass: [NSStoryboardSeguePerformAction class]])
|
NSMutableArray *seguesToPerform = [NSMutableArray array];
|
||||||
{
|
NSMapTable *segueMap = [_transform segueMapForIdentifier: identifier];
|
||||||
NSStoryboardSeguePerformAction *ssa = (NSStoryboardSeguePerformAction *)o;
|
NSWindowController *wc = nil;
|
||||||
NSMapTable *mapTable = [_transform segueMapForIdentifier: identifier];
|
NSViewController *vc = nil;
|
||||||
NSStoryboardSegue *ss = [mapTable objectForKey: [ssa identifier]];
|
NSWindow *w = nil;
|
||||||
|
|
||||||
[ssa setSender: result]; // resolve controller here...
|
|
||||||
[ssa setStoryboardSegue: ss];
|
|
||||||
[ssa setStoryboard: self];
|
|
||||||
if ([[ssa kind] isEqualToString: @"relationship"]) // if it is a relationship, perform immediately
|
|
||||||
{
|
|
||||||
[seguesToPerform addObject: ssa];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
END_FOR_IN(topLevelObjects);
|
|
||||||
|
|
||||||
// Depending on which kind of controller we have, do the correct thing....
|
FOR_IN(id, o, topLevelObjects)
|
||||||
if (w != nil && wc != nil)
|
if ([o isKindOfClass: [NSWindowController class]])
|
||||||
{
|
{
|
||||||
[wc setWindow: w];
|
wc = (NSWindowController *)o;
|
||||||
}
|
[wc _setSegueMap: segueMap];
|
||||||
|
[wc _setTopLevelObjects: topLevelObjects];
|
||||||
|
[wc _setStoryboard: self];
|
||||||
|
[wc _setOwner: NSApp];
|
||||||
|
result = o;
|
||||||
|
}
|
||||||
|
else if ([o isKindOfClass: [NSViewController class]])
|
||||||
|
{
|
||||||
|
vc = (NSViewController *)o;
|
||||||
|
[vc _setSegueMap: segueMap];
|
||||||
|
[vc _setTopLevelObjects: topLevelObjects];
|
||||||
|
[vc _setStoryboard: self];
|
||||||
|
result = o;
|
||||||
|
}
|
||||||
|
else if ([o isKindOfClass: [NSWindow class]])
|
||||||
|
{
|
||||||
|
w = (NSWindow *)o;
|
||||||
|
}
|
||||||
|
else if ([o isKindOfClass: [NSControllerPlaceholder class]])
|
||||||
|
{
|
||||||
|
NSControllerPlaceholder *ph = (NSControllerPlaceholder *)o;
|
||||||
|
result = [ph instantiate];
|
||||||
|
}
|
||||||
|
END_FOR_IN(topLevelObjects);
|
||||||
|
|
||||||
// perform segues after all is initialized.
|
// Process action proxies after so we know we have the windowController...
|
||||||
FOR_IN(NSStoryboardSeguePerformAction*, ssa, seguesToPerform)
|
FOR_IN(id, o, topLevelObjects)
|
||||||
[ssa doAction: result]; // this will, as far as I know, only happen with window controllers, to set content.
|
if ([o isKindOfClass: [NSStoryboardSeguePerformAction class]])
|
||||||
END_FOR_IN(seguesToPerform);
|
{
|
||||||
}
|
NSStoryboardSeguePerformAction *ssa = (NSStoryboardSeguePerformAction *)o;
|
||||||
else
|
NSMapTable *mapTable = [_transform segueMapForIdentifier: identifier];
|
||||||
{
|
NSStoryboardSegue *ss = [mapTable objectForKey: [ssa identifier]];
|
||||||
[NSException raise: NSInternalInconsistencyException
|
|
||||||
format: @"Couldn't load controller scene identifier = %@", identifier];
|
[ssa setSender: result]; // resolve controller here...
|
||||||
|
[ssa setStoryboardSegue: ss];
|
||||||
|
[ssa setStoryboard: self];
|
||||||
|
if ([[ssa kind] isEqualToString: @"relationship"]) // if it is a relationship, perform immediately
|
||||||
|
{
|
||||||
|
[seguesToPerform addObject: ssa];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END_FOR_IN(topLevelObjects);
|
||||||
|
|
||||||
|
// Depending on which kind of controller we have, do the correct thing....
|
||||||
|
if (w != nil && wc != nil)
|
||||||
|
{
|
||||||
|
[wc setWindow: w];
|
||||||
|
}
|
||||||
|
|
||||||
|
// perform segues after all is initialized.
|
||||||
|
FOR_IN(NSStoryboardSeguePerformAction*, ssa, seguesToPerform)
|
||||||
|
[ssa doAction: result]; // this will, as far as I know, only happen with window controllers, to set content.
|
||||||
|
END_FOR_IN(seguesToPerform);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"Couldn't load controller scene identifier = %@", identifier];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the block if it's set...
|
||||||
|
if (block != nil)
|
||||||
|
{
|
||||||
|
CALL_BLOCK(block, self);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute the block if it's set...
|
|
||||||
if (block != nil)
|
|
||||||
{
|
|
||||||
CALL_BLOCK(block, self);
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue