mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-22 18:11:06 +00:00
Move _customClasses to GSXibKeyedUnarchiver and implement logic to build the _customClasses array for use in Gorm when loading the xib file.
This commit is contained in:
parent
def2c9765d
commit
790b686f0d
4 changed files with 88 additions and 19 deletions
|
@ -41,6 +41,7 @@
|
|||
NSMutableArray *stack;
|
||||
GSXibElement *currentElement;
|
||||
NSMutableDictionary *decoded;
|
||||
NSMutableArray *_customClasses;
|
||||
}
|
||||
|
||||
+ (BOOL) checkXib5: (NSData *)data;
|
||||
|
@ -53,6 +54,7 @@
|
|||
- (id) _decodeArrayOfObjectsForElement: (GSXibElement*)element;
|
||||
- (id) _decodeDictionaryOfObjectsForElement: (GSXibElement*)element;
|
||||
- (id) objectForXib: (GSXibElement*)element;
|
||||
- (NSArray *) customClasses;
|
||||
|
||||
- (NSDictionary *) decoded;
|
||||
@end
|
||||
|
|
|
@ -41,9 +41,7 @@
|
|||
GSXibElement *_runtimeAttributes;
|
||||
NSMutableDictionary *_orderedObjectsDict;
|
||||
NSArray *_resources;
|
||||
NSMutableArray *_customClasses;
|
||||
}
|
||||
|
||||
- (NSRange) decodeRangeForKey: (NSString*)key;
|
||||
- (NSMutableArray *) customClasses;
|
||||
@end
|
||||
|
|
|
@ -750,9 +750,6 @@ static NSArray *XmlBoolDefaultYes = nil;
|
|||
[_IBObjectContainer setElement: _connectionRecords forKey: @"connectionRecords"];
|
||||
[_IBObjectContainer setElement: _objectRecords forKey: @"objectRecords"];
|
||||
[_IBObjectContainer setElement: _flattenedProperties forKey: @"flattenedProperties"];
|
||||
|
||||
// Hold the dictionary which contains custom class information for Gorm/IB.
|
||||
_customClasses = [[NSMutableArray alloc] initWithCapacity: 10];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
|
@ -765,15 +762,9 @@ static NSArray *XmlBoolDefaultYes = nil;
|
|||
RELEASE(_orderedObjects);
|
||||
RELEASE(_orderedObjectsDict);
|
||||
RELEASE(_resources);
|
||||
RELEASE(_customClasses);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSMutableArray *) customClasses
|
||||
{
|
||||
return _customClasses;
|
||||
}
|
||||
|
||||
- (void) createCustomClassRecordForId: (NSString *)theId
|
||||
withParentClass: (NSString *)parentClassName
|
||||
forCustomClass: (NSString *)customClassName
|
||||
|
|
|
@ -83,6 +83,28 @@
|
|||
return AUTORELEASE(unarchiver);
|
||||
}
|
||||
|
||||
- (NSString *) _substituteClassForClassName: (NSString *)className
|
||||
{
|
||||
NSString *result = className;
|
||||
NSEnumerator *en = [_customClasses objectEnumerator];
|
||||
NSDictionary *dict = nil;
|
||||
|
||||
// NSLog(@"_customClasses = %@", _customClasses);
|
||||
while ((dict = [en nextObject]) != nil)
|
||||
{
|
||||
NSString *customClassName = [dict objectForKey: @"customClassName"];
|
||||
|
||||
if ([customClassName isEqualToString: className])
|
||||
{
|
||||
result = [dict objectForKey: @"parentClassName"];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NSDebugLog(@"result = %@", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSData *) _preProcessXib: (NSData *)data
|
||||
{
|
||||
NSData *result = data;
|
||||
|
@ -143,8 +165,46 @@
|
|||
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];
|
||||
NSString *cn = [[xmlObjs objectAtIndex: index] stringValue]; // className
|
||||
|
||||
[customClassDict setObject:cn forKey:key];
|
||||
|
||||
//
|
||||
// If we are in IB/Gorm build the custom classes map so that we don't instantiate
|
||||
// classes which don't exist (yet) in IB/Gorm. This allows editing of the model
|
||||
// in IB/Gorm. If we are in the live app, don't bother as it's a waste of memory.
|
||||
//
|
||||
if ([NSClassSwapper isInInterfaceBuilder] == YES)
|
||||
{
|
||||
NSString *xpath = [NSString stringWithFormat: @"//object[@class=\"IBClassDescriber\"]"
|
||||
@"//string[@key=\"className\"][text()=\"%@\"]"
|
||||
@"/../string[@key=\"superclassName\"]", cn];
|
||||
NSArray *descriptionObjs = [document nodesForXPath: xpath error: NULL];
|
||||
if ([descriptionObjs count] > 0)
|
||||
{
|
||||
NSUInteger idx = [key rangeOfString: @"."].location;
|
||||
if (idx != NSNotFound) // unlikely to be NSNotFound...
|
||||
{
|
||||
NSString *num = [key substringToIndex: idx];
|
||||
NSXMLNode *descriptionNode = [descriptionObjs objectAtIndex: 0];
|
||||
NSString *sc = [descriptionNode stringValue]; // superclassName
|
||||
NSString *refXPath = [NSString stringWithFormat:
|
||||
@"//object[@class=\"IBMutableOrderedSet\"][@key=\"objectRecords\"]"
|
||||
@"/object/object[@class=\"IBObjectRecord\"]/int[@key=\"objectID\"]"
|
||||
@"[text()=\"%@\"]/../reference[@key=\"object\"]/@ref", num];
|
||||
|
||||
NSArray *refNodes = [document nodesForXPath: refXPath error: NULL];
|
||||
if ([refNodes count] > 0)
|
||||
{
|
||||
NSXMLElement *refNode = [refNodes objectAtIndex: 0];
|
||||
NSString *refId = [refNode stringValue];
|
||||
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
refId, @"id", sc, @"parentClassName", cn, @"customClassName", nil];
|
||||
[_customClasses addObject: dict];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -206,14 +266,16 @@
|
|||
|
||||
// If we are in the interface builder app, do not replace
|
||||
// the existing classes with their custom subclasses.
|
||||
if ([NSClassSwapper isInInterfaceBuilder] == NO)
|
||||
NSString *clsName = className;
|
||||
if ([NSClassSwapper isInInterfaceBuilder] == YES)
|
||||
{
|
||||
cls = NSClassFromString(className);
|
||||
clsName = [self _substituteClassForClassName: className];
|
||||
}
|
||||
|
||||
cls = NSClassFromString(clsName);
|
||||
classNode = [classNodes objectAtIndex:0];
|
||||
classAttr = [classNode attributeForName:@"class"];
|
||||
[classAttr setStringValue:className];
|
||||
[classAttr setStringValue: className];
|
||||
|
||||
if (cls != nil)
|
||||
{
|
||||
|
@ -232,7 +294,7 @@
|
|||
id cellAttr = nil;
|
||||
cellNode = [cellNodes objectAtIndex:0];
|
||||
cellAttr = [cellNode attributeForName:@"class"];
|
||||
[cellAttr setStringValue:cellClassString];
|
||||
[cellAttr setStringValue: cellClassString];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -264,6 +326,9 @@
|
|||
NSXMLParser *theParser;
|
||||
NSData *theData = data;
|
||||
|
||||
// Dictionary which contains custom class information for Gorm/IB.
|
||||
_customClasses = [[NSMutableArray alloc] initWithCapacity: 10];
|
||||
|
||||
theData = [self _preProcessXib: data];
|
||||
if (theData == nil)
|
||||
{
|
||||
|
@ -298,6 +363,7 @@
|
|||
DESTROY(objects);
|
||||
DESTROY(stack);
|
||||
DESTROY(decoded);
|
||||
DESTROY(_customClasses);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
@ -364,11 +430,17 @@ didStartElement: (NSString*)elementName
|
|||
}
|
||||
}
|
||||
|
||||
- (id) allocObjectForClassName: (NSString*)classname
|
||||
- (id) allocObjectForClassName: (NSString*)clsname
|
||||
{
|
||||
Class c = nil;
|
||||
id delegate = [self delegate];
|
||||
|
||||
NSString *classname = clsname;
|
||||
|
||||
if ([NSClassSwapper isInInterfaceBuilder] == YES)
|
||||
{
|
||||
classname = [self _substituteClassForClassName: classname];
|
||||
}
|
||||
|
||||
c = [self classForClassName: classname];
|
||||
|
||||
if (c == nil)
|
||||
|
@ -1033,4 +1105,10 @@ didStartElement: (NSString*)elementName
|
|||
{
|
||||
return decoded;
|
||||
}
|
||||
|
||||
- (NSArray *) customClasses
|
||||
{
|
||||
return _customClasses;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in a new issue