mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-23 07:00:46 +00:00
Initial code for XIB 5 support.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@37761 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
51c43eae39
commit
3931ffd3eb
9 changed files with 550 additions and 234 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
|||
2014-03-25 03:56-EDT Gregory John Casamento <greg.casamento@gmail.com>
|
||||
|
||||
* Headers/Additions/GNUstepGUI/GSXibElement.h
|
||||
* Headers/Additions/GNUstepGUI/GSXibLoading.h
|
||||
* Headers/Additions/GNUstepGUI/GSXibObjectContainer.h
|
||||
* Headers/Additions/GNUstepGUI/GSXibParser.h
|
||||
* Source/GNUmakefile: Add new files to makefile.
|
||||
* Source/GSXibElement.m: Refactored out of GSXibLoader.m
|
||||
* Source/GSXibLoader.m: Remove some code and move into
|
||||
separate files.
|
||||
* Source/GSXibParser.m: Version 5 XIB support. Initial code. This
|
||||
currently doesn't work, but it illustrates the direction I am
|
||||
taking with solving this.
|
||||
|
||||
2014-02-23 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Headers/AppKit/NSTextAttachment.h
|
||||
|
|
59
Headers/Additions/GNUstepGUI/GSXibElement.h
Normal file
59
Headers/Additions/GNUstepGUI/GSXibElement.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* <title>GSXibLoading</title>
|
||||
|
||||
<abstract>Xib (Cocoa XML) model loader</abstract>
|
||||
|
||||
Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Fred Kiefer <FredKiefer@gmx.de>
|
||||
Created: March 2010
|
||||
Refactored slightly by: Gregory Casamento <greg.casamento@gmail.com>
|
||||
Created: May 2010
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
||||
*/
|
||||
|
||||
#ifndef _GNUstep_H_GSXibElement
|
||||
#define _GNUstep_H_GSXibElement
|
||||
|
||||
#import <Foundation/NSObject.h>
|
||||
|
||||
@class NSString, NSDictionary, NSMutableDictionary, NSMutableArray;
|
||||
|
||||
@interface GSXibElement: NSObject
|
||||
{
|
||||
NSString *type;
|
||||
NSDictionary *attributes;
|
||||
NSString *value;
|
||||
NSMutableDictionary *elements;
|
||||
NSMutableArray *values;
|
||||
}
|
||||
|
||||
- (GSXibElement*) initWithType: (NSString*)typeName
|
||||
andAttributes: (NSDictionary*)attribs;
|
||||
- (NSString*) type;
|
||||
- (NSString*) value;
|
||||
- (NSDictionary*) elements;
|
||||
- (NSArray*) values;
|
||||
- (void) addElement: (GSXibElement*)element;
|
||||
- (void) setElement: (GSXibElement*)element forKey: (NSString*)key;
|
||||
- (void) setValue: (NSString*)text;
|
||||
- (NSString*) attributeForKey: (NSString*)key;
|
||||
- (GSXibElement*) elementForKey: (NSString*)key;
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
@class NSString, NSDictionary, NSArray, NSMutableDictionary, NSMutableArray;
|
||||
@class NSNibBindingConnector;
|
||||
@class GSXibElement;
|
||||
|
||||
// Hack: This allows the class name FirstResponder in NSCustomObject and
|
||||
// correctly returns nil as the corresponding object.
|
||||
|
@ -155,25 +156,6 @@
|
|||
- (NSEnumerator *) objectRecordEnumerator;
|
||||
@end
|
||||
|
||||
@interface GSXibElement: NSObject
|
||||
{
|
||||
NSString *type;
|
||||
NSDictionary *attributes;
|
||||
NSString *value;
|
||||
NSMutableDictionary *elements;
|
||||
NSMutableArray *values;
|
||||
}
|
||||
- (NSString*) type;
|
||||
- (NSString*) value;
|
||||
- (NSDictionary*) elements;
|
||||
- (NSArray*) values;
|
||||
- (void) addElement: (GSXibElement*)element;
|
||||
- (void) setElement: (GSXibElement*)element forKey: (NSString*)key;
|
||||
- (void) setValue: (NSString*)text;
|
||||
- (NSString*) attributeForKey: (NSString*)key;
|
||||
- (GSXibElement*) elementForKey: (NSString*)key;
|
||||
@end
|
||||
|
||||
@interface GSXibKeyedUnarchiver: NSKeyedUnarchiver
|
||||
{
|
||||
NSMutableDictionary *objects;
|
||||
|
|
30
Headers/Additions/GNUstepGUI/GSXibObjectContainer.h
Normal file
30
Headers/Additions/GNUstepGUI/GSXibObjectContainer.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* <title>GSXibObjectContainer</title>
|
||||
|
||||
<abstract>Xib v5 (Cocoa XML) container</abstract>
|
||||
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Gregory Casamento <greg.casamento@gmail.com>
|
||||
Created: March 2014
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSObject.h>
|
||||
|
||||
@interface GSXibObjectContainer : NSObject
|
||||
@end
|
51
Headers/Additions/GNUstepGUI/GSXibParser.h
Normal file
51
Headers/Additions/GNUstepGUI/GSXibParser.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/* <title>GSXibParser</title>
|
||||
|
||||
<abstract>Xib v5 (Cocoa XML) parser</abstract>
|
||||
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Gregory Casamento <greg.casamento@gmail.com>
|
||||
Created: March 2014
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
||||
*/
|
||||
|
||||
#ifndef _GNUstep_H_GSXibParser
|
||||
#define _GNUstep_H_GSXibParser
|
||||
|
||||
#import <Foundation/NSObject.h>
|
||||
|
||||
@class NSData;
|
||||
@class NSXMLParser;
|
||||
@class NSMutableDictionary;
|
||||
@class GSXibElement;
|
||||
@class NSMutableArray;
|
||||
|
||||
@interface GSXibParser : NSObject
|
||||
{
|
||||
NSMutableDictionary *objects;
|
||||
GSXibElement *currentElement;
|
||||
NSMutableArray *stack;
|
||||
NSXMLParser *theParser;
|
||||
}
|
||||
|
||||
- (id) initWithData: (NSData *)data;
|
||||
- (NSDictionary *) parse;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
|
@ -247,8 +247,10 @@ GSModelLoaderFactory.m \
|
|||
GSGormLoader.m \
|
||||
GSGModelLoader.m \
|
||||
GSNibLoader.m \
|
||||
GSXibElement.m \
|
||||
GSXibLoader.m \
|
||||
GSXibLoading.m \
|
||||
GSXibParser.m \
|
||||
GSHelpAttachment.m
|
||||
|
||||
# Turn off NSMenuItem warning that NSMenuItem conforms to <NSObject>,
|
||||
|
@ -464,7 +466,9 @@ GSInstantiator.h \
|
|||
GSSoundSink.h \
|
||||
GSSoundSource.h \
|
||||
GSWindowDecorationView.h \
|
||||
GSXibElement.h \
|
||||
GSXibLoading.h \
|
||||
GSXibParser.h \
|
||||
GSHelpAttachment.h
|
||||
|
||||
libgnustep-gui_HEADER_FILES = ${GUI_HEADERS}
|
||||
|
|
111
Source/GSXibElement.m
Normal file
111
Source/GSXibElement.m
Normal file
|
@ -0,0 +1,111 @@
|
|||
/* <title>GSXibElement</title>
|
||||
|
||||
<abstract>Xib element</abstract>
|
||||
|
||||
Copyright (C) 2010, 2011 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Fred Kiefer <FredKiefer@gmx.de>
|
||||
Created: March 2010
|
||||
Written by: Gregory Casamento <greg.casamento@gmail.com>
|
||||
Created: March 2014
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
#import "GNUstepGUI/GSXibElement.h"
|
||||
|
||||
@implementation GSXibElement
|
||||
|
||||
- (GSXibElement*) initWithType: (NSString*)typeName
|
||||
andAttributes: (NSDictionary*)attribs
|
||||
{
|
||||
ASSIGN(type, typeName);
|
||||
ASSIGN(attributes, attribs);
|
||||
elements = [[NSMutableDictionary alloc] init];
|
||||
values = [[NSMutableArray alloc] init];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
DESTROY(type);
|
||||
DESTROY(attributes);
|
||||
DESTROY(elements);
|
||||
DESTROY(values);
|
||||
DESTROY(value);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSString*) type
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
- (NSString*) value
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
- (NSDictionary*) elements
|
||||
{
|
||||
return elements;
|
||||
}
|
||||
|
||||
- (NSArray*) values
|
||||
{
|
||||
return values;
|
||||
}
|
||||
|
||||
- (void) addElement: (GSXibElement*)element
|
||||
{
|
||||
[values addObject: element];
|
||||
}
|
||||
|
||||
- (void) setElement: (GSXibElement*)element forKey: (NSString*)key
|
||||
{
|
||||
[elements setObject: element forKey: key];
|
||||
}
|
||||
|
||||
- (void) setValue: (NSString*)text
|
||||
{
|
||||
ASSIGN(value, text);
|
||||
}
|
||||
|
||||
- (NSString*) attributeForKey: (NSString*)key
|
||||
{
|
||||
return [attributes objectForKey: key];
|
||||
}
|
||||
|
||||
- (GSXibElement*) elementForKey: (NSString*)key
|
||||
{
|
||||
return [elements objectForKey: key];
|
||||
}
|
||||
|
||||
- (NSString*) description
|
||||
{
|
||||
return [NSString stringWithFormat:
|
||||
@"GSXibElement <%@> attrs (%@) elements [%@] values [%@] %@",
|
||||
type, attributes, elements, values, value, nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -45,6 +45,9 @@
|
|||
#import "GNUstepGUI/GSModelLoaderFactory.h"
|
||||
#import "GNUstepGUI/GSNibLoading.h"
|
||||
#import "GNUstepGUI/GSXibLoading.h"
|
||||
#import "GNUstepGUI/GSXibParser.h"
|
||||
#import "GNUstepGUI/GSXibObjectContainer.h"
|
||||
#import "GNUstepGUI/GSXibElement.h"
|
||||
|
||||
@interface NSApplication (NibCompatibility)
|
||||
- (void) _setMainMenu: (NSMenu*)aMenu;
|
||||
|
@ -853,7 +856,7 @@
|
|||
}
|
||||
|
||||
- (void) awake: (NSArray *)rootObjects
|
||||
inContainer: (IBObjectContainer *)objects
|
||||
inContainer: (id)objects
|
||||
withContext: (NSDictionary *)context
|
||||
{
|
||||
NSEnumerator *en;
|
||||
|
@ -903,7 +906,10 @@
|
|||
}
|
||||
|
||||
// Load connections and awaken objects
|
||||
[objects nibInstantiate];
|
||||
if ([objects respondsToSelector:@selector(nibInstantiate)])
|
||||
{
|
||||
[objects nibInstantiate];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) loadModelData: (NSData *)data
|
||||
|
@ -928,13 +934,28 @@
|
|||
rootObjects = [unarchiver decodeObjectForKey: @"IBDocument.RootObjects"];
|
||||
objects = [unarchiver decodeObjectForKey: @"IBDocument.Objects"];
|
||||
NSDebugLLog(@"XIB", @"rootObjects %@", rootObjects);
|
||||
[self awake: rootObjects inContainer: objects withContext: context];
|
||||
[self awake: rootObjects
|
||||
inContainer: objects
|
||||
withContext: context];
|
||||
loaded = YES;
|
||||
RELEASE(unarchiver);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"Could not instantiate Xib unarchiver.");
|
||||
GSXibParser *parser = [[GSXibParser alloc] initWithData: data];
|
||||
NSDictionary *result = [parser parse];
|
||||
if (result != nil)
|
||||
{
|
||||
NSArray *rootObjects = [result objectForKey: @"IBDocument.RootObjects"];
|
||||
GSXibObjectContainer *objects = [result objectForKey: @"IBDocument.Objects"];
|
||||
[self awake: rootObjects
|
||||
inContainer: objects
|
||||
withContext: context];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"Could not instantiate Xib unarchiver/Unable to parse Xib.");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -983,83 +1004,6 @@
|
|||
|
||||
@end
|
||||
|
||||
@implementation GSXibElement
|
||||
|
||||
- (GSXibElement*) initWithType: (NSString*)typeName
|
||||
andAttributes: (NSDictionary*)attribs
|
||||
{
|
||||
ASSIGN(type, typeName);
|
||||
ASSIGN(attributes, attribs);
|
||||
elements = [[NSMutableDictionary alloc] init];
|
||||
values = [[NSMutableArray alloc] init];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
DESTROY(type);
|
||||
DESTROY(attributes);
|
||||
DESTROY(elements);
|
||||
DESTROY(values);
|
||||
DESTROY(value);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSString*) type
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
- (NSString*) value
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
- (NSDictionary*) elements
|
||||
{
|
||||
return elements;
|
||||
}
|
||||
|
||||
- (NSArray*) values
|
||||
{
|
||||
return values;
|
||||
}
|
||||
|
||||
- (void) addElement: (GSXibElement*)element
|
||||
{
|
||||
[values addObject: element];
|
||||
}
|
||||
|
||||
- (void) setElement: (GSXibElement*)element forKey: (NSString*)key
|
||||
{
|
||||
[elements setObject: element forKey: key];
|
||||
}
|
||||
|
||||
- (void) setValue: (NSString*)text
|
||||
{
|
||||
ASSIGN(value, text);
|
||||
}
|
||||
|
||||
- (NSString*) attributeForKey: (NSString*)key
|
||||
{
|
||||
return [attributes objectForKey: key];
|
||||
}
|
||||
|
||||
- (GSXibElement*) elementForKey: (NSString*)key
|
||||
{
|
||||
return [elements objectForKey: key];
|
||||
}
|
||||
|
||||
- (NSString*) description
|
||||
{
|
||||
return [NSString stringWithFormat:
|
||||
@"GSXibElement <%@> attrs (%@) elements [%@] values [%@] %@",
|
||||
type, attributes, elements, values, value, nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation GSXibKeyedUnarchiver
|
||||
|
||||
- (NSData *) _preProcessXib: (NSData *)data
|
||||
|
@ -1074,143 +1018,154 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
NSArray *customClassNodes = [document nodesForXPath:@"//dictionary[@key=\"flattenedProperties\"]/"
|
||||
@"string[contains(@key,\"CustomClassName\")]"
|
||||
error:NULL];
|
||||
NSMutableDictionary *customClassDict = [NSMutableDictionary dictionary];
|
||||
if (customClassNodes)
|
||||
{
|
||||
NSDebugLLog(@"PREXIB", @"%s:customClassNodes: %@\n", __PRETTY_FUNCTION__, customClassNodes);
|
||||
|
||||
// Replace the NSXMLNodes with a dictionary...
|
||||
NSInteger index = 0;
|
||||
for (index = 0; index < [customClassNodes count]; ++index)
|
||||
{
|
||||
id node = [customClassNodes objectAtIndex:index];
|
||||
if ([node isMemberOfClass:[NSXMLElement class]])
|
||||
{
|
||||
NSString *key = [[node attributeForName:@"key"] stringValue];
|
||||
if ([key rangeOfString:@"CustomClassName"].location != NSNotFound)
|
||||
// Test to see if this is an Xcode 5 XIB...
|
||||
NSArray *documentNodes = [document nodesForXPath:@"/document"
|
||||
error:NULL];
|
||||
if ([documentNodes count] > 0)
|
||||
{
|
||||
NSLog(@"Unsupported... This is an XCode 5 XIB file.");
|
||||
return nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSArray *customClassNodes = [document nodesForXPath:@"//dictionary[@key=\"flattenedProperties\"]/"
|
||||
@"string[contains(@key,\"CustomClassName\")]"
|
||||
error:NULL];
|
||||
NSMutableDictionary *customClassDict = [NSMutableDictionary dictionary];
|
||||
if (customClassNodes)
|
||||
{
|
||||
NSDebugLLog(@"PREXIB", @"%s:customClassNodes: %@\n", __PRETTY_FUNCTION__, customClassNodes);
|
||||
|
||||
// Replace the NSXMLNodes with a dictionary...
|
||||
NSInteger index = 0;
|
||||
for (index = 0; index < [customClassNodes count]; ++index)
|
||||
{
|
||||
id node = [customClassNodes objectAtIndex:index];
|
||||
if ([node isMemberOfClass:[NSXMLElement class]])
|
||||
{
|
||||
[customClassDict setObject:[node stringValue] forKey:key];
|
||||
NSString *key = [[node attributeForName:@"key"] stringValue];
|
||||
if ([key rangeOfString:@"CustomClassName"].location != NSNotFound)
|
||||
{
|
||||
[customClassDict setObject:[node stringValue] forKey:key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NSArray *flatProps = [document nodesForXPath:@"//object[@key=\"flattenedProperties\"]" error:NULL];
|
||||
if ([flatProps count] == 1)
|
||||
{
|
||||
NSInteger index = 0;
|
||||
NSArray *xmlKeys = [[flatProps objectAtIndex:0] nodesForXPath:@"//object[@key=\"flattenedProperties\"]/object[@key=\"dict.sortedKeys\"]/*" error:NULL];
|
||||
NSArray *xmlObjs = [[flatProps objectAtIndex:0] nodesForXPath:@"//object[@key=\"flattenedProperties\"]/object[@key=\"dict.values\"]/*" error:NULL];
|
||||
if ([xmlKeys count] != [xmlObjs count])
|
||||
{
|
||||
NSLog(@"%s:keys to objs count mismatch - keys: %d objs: %d\n", __PRETTY_FUNCTION__,
|
||||
(int)[xmlKeys count], (int)[xmlObjs count]);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (index = 0; index < [xmlKeys count]; ++index)
|
||||
{
|
||||
id key = [[xmlKeys objectAtIndex:index] stringValue];
|
||||
if ([key rangeOfString:@"CustomClassName"].location != NSNotFound)
|
||||
{
|
||||
// NSString *obj = [[xmlObjs objectAtIndex:index] stringValue];
|
||||
[customClassDict setObject:[[xmlObjs objectAtIndex:index] stringValue] forKey:key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NSDebugLLog(@"PREXIB", @"%s:customClassDict: %@\n", __PRETTY_FUNCTION__, customClassDict);
|
||||
|
||||
if ([customClassDict count] > 0)
|
||||
{
|
||||
NSArray *objectRecords = nil;
|
||||
NSEnumerator *en = [[customClassDict allKeys] objectEnumerator];
|
||||
NSString *key = nil;
|
||||
|
||||
while ((key = [en nextObject]) != nil)
|
||||
{
|
||||
NSString *keyValue = [key stringByReplacingOccurrencesOfString:@".CustomClassName" withString:@""];
|
||||
NSString *className = [customClassDict objectForKey: key];
|
||||
NSString *objectRecordXpath = nil;
|
||||
|
||||
objectRecordXpath = [NSString stringWithFormat: @"//object[@class=\"IBObjectRecord\"]/"
|
||||
@"int[@key=\"objectID\"][text()=\"%@\"]/../reference",
|
||||
keyValue];
|
||||
|
||||
objectRecords = [document nodesForXPath: objectRecordXpath error: NULL];
|
||||
|
||||
if (objectRecords == nil)
|
||||
{
|
||||
// If that didn't work then it could be a 4.6+ XIB...
|
||||
objectRecordXpath = [NSString stringWithFormat: @"//object[@class=\"IBObjectRecord\"]/"
|
||||
@"string[@key=\"id\"][text()=\"%@\"]/../reference",
|
||||
keyValue];
|
||||
objectRecords = [document nodesForXPath: objectRecordXpath error: NULL];
|
||||
}
|
||||
|
||||
NSString *refId = nil;
|
||||
if ([objectRecords count] > 0)
|
||||
{
|
||||
id record = nil;
|
||||
NSEnumerator *oen = [objectRecords objectEnumerator];
|
||||
while ((record = [oen nextObject]) != nil)
|
||||
{
|
||||
if ([record isMemberOfClass:[NSXMLElement class]])
|
||||
{
|
||||
if([[[record attributeForName:@"key"] stringValue] isEqualToString:@"object"])
|
||||
{
|
||||
NSArray *classNodes = nil;
|
||||
id classNode = nil;
|
||||
NSString *refXpath = nil;
|
||||
|
||||
refId = [[record attributeForName:@"ref"] stringValue];
|
||||
refXpath = [NSString stringWithFormat:@"//object[@id=\"%@\"]",refId];
|
||||
classNodes = [document nodesForXPath:refXpath
|
||||
error:NULL];
|
||||
if([classNodes count] > 0)
|
||||
{
|
||||
id classAttr = nil;
|
||||
Class cls = NSClassFromString(className);
|
||||
|
||||
classNode = [classNodes objectAtIndex:0];
|
||||
classAttr = [classNode attributeForName:@"class"];
|
||||
[classAttr setStringValue:className];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSArray *flatProps = [document nodesForXPath:@"//object[@key=\"flattenedProperties\"]" error:NULL];
|
||||
if ([flatProps count] == 1)
|
||||
{
|
||||
NSInteger index = 0;
|
||||
NSArray *xmlKeys = [[flatProps objectAtIndex:0] nodesForXPath:@"//object[@key=\"flattenedProperties\"]/object[@key=\"dict.sortedKeys\"]/*" error:NULL];
|
||||
NSArray *xmlObjs = [[flatProps objectAtIndex:0] nodesForXPath:@"//object[@key=\"flattenedProperties\"]/object[@key=\"dict.values\"]/*" error:NULL];
|
||||
if ([xmlKeys count] != [xmlObjs count])
|
||||
{
|
||||
NSLog(@"%s:keys to objs count mismatch - keys: %d objs: %d\n", __PRETTY_FUNCTION__,
|
||||
(int)[xmlKeys count], (int)[xmlObjs count]);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (index = 0; index < [xmlKeys count]; ++index)
|
||||
{
|
||||
id key = [[xmlKeys objectAtIndex:index] stringValue];
|
||||
if ([key rangeOfString:@"CustomClassName"].location != NSNotFound)
|
||||
{
|
||||
// NSString *obj = [[xmlObjs objectAtIndex:index] stringValue];
|
||||
[customClassDict setObject:[[xmlObjs objectAtIndex:index] stringValue] forKey:key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NSDebugLLog(@"PREXIB", @"%s:customClassDict: %@\n", __PRETTY_FUNCTION__, customClassDict);
|
||||
|
||||
if ([customClassDict count] > 0)
|
||||
{
|
||||
NSArray *objectRecords = nil;
|
||||
NSEnumerator *en = [[customClassDict allKeys] objectEnumerator];
|
||||
NSString *key = nil;
|
||||
|
||||
while ((key = [en nextObject]) != nil)
|
||||
{
|
||||
NSString *keyValue = [key stringByReplacingOccurrencesOfString:@".CustomClassName" withString:@""];
|
||||
NSString *className = [customClassDict objectForKey: key];
|
||||
NSString *objectRecordXpath = nil;
|
||||
|
||||
objectRecordXpath = [NSString stringWithFormat: @"//object[@class=\"IBObjectRecord\"]/"
|
||||
@"int[@key=\"objectID\"][text()=\"%@\"]/../reference",
|
||||
keyValue];
|
||||
|
||||
objectRecords = [document nodesForXPath: objectRecordXpath error: NULL];
|
||||
|
||||
if (objectRecords == nil)
|
||||
{
|
||||
// If that didn't work then it could be a 4.6+ XIB...
|
||||
objectRecordXpath = [NSString stringWithFormat: @"//object[@class=\"IBObjectRecord\"]/"
|
||||
@"string[@key=\"id\"][text()=\"%@\"]/../reference",
|
||||
keyValue];
|
||||
objectRecords = [document nodesForXPath: objectRecordXpath error: NULL];
|
||||
}
|
||||
|
||||
NSString *refId = nil;
|
||||
if ([objectRecords count] > 0)
|
||||
{
|
||||
id record = nil;
|
||||
NSEnumerator *oen = [objectRecords objectEnumerator];
|
||||
while ((record = [oen nextObject]) != nil)
|
||||
{
|
||||
if ([record isMemberOfClass:[NSXMLElement class]])
|
||||
{
|
||||
if([[[record attributeForName:@"key"] stringValue] isEqualToString:@"object"])
|
||||
{
|
||||
NSArray *classNodes = nil;
|
||||
id classNode = nil;
|
||||
NSString *refXpath = nil;
|
||||
|
||||
if (cls != nil)
|
||||
refId = [[record attributeForName:@"ref"] stringValue];
|
||||
refXpath = [NSString stringWithFormat:@"//object[@id=\"%@\"]",refId];
|
||||
classNodes = [document nodesForXPath:refXpath
|
||||
error:NULL];
|
||||
if([classNodes count] > 0)
|
||||
{
|
||||
if ([cls respondsToSelector:@selector(cellClass)])
|
||||
id classAttr = nil;
|
||||
Class cls = NSClassFromString(className);
|
||||
|
||||
classNode = [classNodes objectAtIndex:0];
|
||||
classAttr = [classNode attributeForName:@"class"];
|
||||
[classAttr setStringValue:className];
|
||||
|
||||
if (cls != nil)
|
||||
{
|
||||
NSArray *cellNodes = nil;
|
||||
id cellNode = nil;
|
||||
id cellClass = [cls cellClass];
|
||||
NSString *cellXpath = [NSString stringWithFormat:@"//object[@id=\"%@\"]/object[@key=\"NSCell\"]",refId];
|
||||
cellNodes = [document nodesForXPath:cellXpath
|
||||
error:NULL];
|
||||
if ([cellNodes count] > 0)
|
||||
if ([cls respondsToSelector:@selector(cellClass)])
|
||||
{
|
||||
NSString *cellClassString = NSStringFromClass(cellClass);
|
||||
id cellAttr = nil;
|
||||
cellNode = [cellNodes objectAtIndex:0];
|
||||
cellAttr = [cellNode attributeForName:@"class"];
|
||||
[cellAttr setStringValue:cellClassString];
|
||||
NSArray *cellNodes = nil;
|
||||
id cellNode = nil;
|
||||
id cellClass = [cls cellClass];
|
||||
NSString *cellXpath = [NSString stringWithFormat:@"//object[@id=\"%@\"]/object[@key=\"NSCell\"]",refId];
|
||||
cellNodes = [document nodesForXPath:cellXpath
|
||||
error:NULL];
|
||||
if ([cellNodes count] > 0)
|
||||
{
|
||||
NSString *cellClassString = NSStringFromClass(cellClass);
|
||||
id cellAttr = nil;
|
||||
cellNode = [cellNodes objectAtIndex:0];
|
||||
cellAttr = [cellNode attributeForName:@"class"];
|
||||
[cellAttr setStringValue:cellClassString];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result = [document XMLData];
|
||||
RELEASE(document);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result = [document XMLData];
|
||||
RELEASE(document);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -1223,11 +1178,16 @@
|
|||
|
||||
// If we are in the interface builder app, do not replace
|
||||
// the existing classes with their custom subclasses.
|
||||
if([NSClassSwapper isInInterfaceBuilder] == NO)
|
||||
if ([NSClassSwapper isInInterfaceBuilder] == NO)
|
||||
{
|
||||
theData = [self _preProcessXib: data];
|
||||
}
|
||||
|
||||
if (theData == nil)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
objects = [[NSMutableDictionary alloc] init];
|
||||
stack = [[NSMutableArray alloc] init];
|
||||
decoded = [[NSMutableDictionary alloc] init];
|
||||
|
@ -1281,12 +1241,6 @@ didStartElement: (NSString*)elementName
|
|||
// FIXME: We should use proper memory management here
|
||||
AUTORELEASE(element);
|
||||
|
||||
if ([@"document" isEqualToString: elementName])
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"Cannot decode XIB 5 format."];
|
||||
}
|
||||
|
||||
if (key != nil)
|
||||
{
|
||||
[currentElement setElement: element forKey: key];
|
||||
|
|
111
Source/GSXibParser.m
Normal file
111
Source/GSXibParser.m
Normal file
|
@ -0,0 +1,111 @@
|
|||
/* <title>GSXibParser</title>
|
||||
|
||||
<abstract>Xib v5 (Cocoa XML) parser</abstract>
|
||||
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Gregory Casamento <greg.casamento@gmail.com>
|
||||
Created: March 2014
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSData.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSXMLParser.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSException.h>
|
||||
|
||||
#import "GNUstepGUI/GSXibParser.h"
|
||||
#import "GNUstepGUI/GSXibElement.h"
|
||||
|
||||
@implementation GSXibParser
|
||||
|
||||
- (id) initWithData: (NSData *)data
|
||||
{
|
||||
if ((self = [super init]) != nil)
|
||||
{
|
||||
theParser = [[NSXMLParser alloc] initWithData: data];
|
||||
[theParser setDelegate: self];
|
||||
|
||||
objects = [[NSMutableDictionary alloc] initWithCapacity: 100];
|
||||
stack = [[NSMutableArray alloc] initWithCapacity: 100];
|
||||
currentElement = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSDictionary *) parse
|
||||
{
|
||||
NS_DURING
|
||||
{
|
||||
[theParser parse];
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
NSLog(@"%@",[localException reason]);
|
||||
}
|
||||
NS_ENDHANDLER;
|
||||
|
||||
return objects;
|
||||
}
|
||||
|
||||
- (void) parser: (NSXMLParser*)parser
|
||||
foundCharacters: (NSString*)string
|
||||
{
|
||||
[currentElement setValue: string];
|
||||
}
|
||||
|
||||
- (void) parser: (NSXMLParser*)parser
|
||||
didStartElement: (NSString*)elementName
|
||||
namespaceURI: (NSString*)namespaceURI
|
||||
qualifiedName: (NSString*)qualifiedName
|
||||
attributes: (NSDictionary*)attributeDict
|
||||
{
|
||||
GSXibElement *element = [[GSXibElement alloc] initWithType: elementName
|
||||
andAttributes: attributeDict];
|
||||
NSString *key = [attributeDict objectForKey: @"id"];
|
||||
|
||||
// FIXME: We should use proper memory management here
|
||||
AUTORELEASE(element);
|
||||
|
||||
if (key != nil)
|
||||
{
|
||||
[currentElement setElement: element forKey: key];
|
||||
}
|
||||
else
|
||||
{
|
||||
// For Arrays
|
||||
[currentElement addElement: element];
|
||||
}
|
||||
|
||||
// Maintain the stack...
|
||||
[stack addObject: currentElement];
|
||||
currentElement = element;
|
||||
}
|
||||
|
||||
- (void) parser: (NSXMLParser*)parser
|
||||
didEndElement: (NSString*)elementName
|
||||
namespaceURI: (NSString*)namespaceURI
|
||||
qualifiedName: (NSString*)qName
|
||||
{
|
||||
currentElement = [stack lastObject];
|
||||
[stack removeLastObject];
|
||||
}
|
||||
@end
|
Loading…
Reference in a new issue