mirror of
https://github.com/gnustep/apps-gorm.git
synced 2025-04-23 06:20:47 +00:00
* GormCore/GormWrapperLoader.m: Allow handling of wrappers which
are not directories. * Plugins/Gorm/GormGormWrapperLoader.m: Change logic to accommodate previous generation of .gorm files which were not packages. Also correct the code so that a return is not made within the NS_DURING block. * Plugins/Nib/GormNibWrapperLoader.m: Do not load if the wrapper is not a directory. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/apps/gorm/trunk@28101 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
f725e855b7
commit
dab982b111
4 changed files with 280 additions and 239 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2009-03-19 23:39-EDT Gregory John Casamento <greg_casamento@yahoo.com>
|
||||
|
||||
* GormCore/GormWrapperLoader.m: Allow handling of wrappers which
|
||||
are not directories.
|
||||
* Plugins/Gorm/GormGormWrapperLoader.m: Change logic to accommodate
|
||||
previous generation of .gorm files which were not packages. Also
|
||||
correct the code so that a return is not made within the NS_DURING
|
||||
block.
|
||||
* Plugins/Nib/GormNibWrapperLoader.m: Do not load if the
|
||||
wrapper is not a directory.
|
||||
|
||||
2009-03-17 01:05-EDT Gregory John Casamento <greg_casamento@yahoo.com>
|
||||
|
||||
* Plugins/Nib/GormNibWrapperLoader.m: Correct the code so that
|
||||
|
|
|
@ -54,52 +54,58 @@ static GormWrapperLoaderFactory *_sharedWrapperLoaderFactory = nil;
|
|||
|
||||
- (BOOL) loadFileWrapper: (NSFileWrapper *)wrapper withDocument: (GormDocument *)doc
|
||||
{
|
||||
if ([wrapper isDirectory])
|
||||
NS_DURING
|
||||
{
|
||||
NSDictionary *fileWrappers = nil;
|
||||
NSString *key = nil;
|
||||
NSArray *imageFileTypes = [NSImage imageFileTypes];
|
||||
NSArray *soundFileTypes = [NSSound soundUnfilteredFileTypes];
|
||||
NSMutableArray *images = [NSMutableArray array];
|
||||
NSMutableArray *sounds = [NSMutableArray array];
|
||||
NSEnumerator *enumerator = nil;
|
||||
|
||||
document = doc; // don't retain...
|
||||
key = nil;
|
||||
fileWrappers = [wrapper fileWrappers];
|
||||
|
||||
[self saveSCMDirectory: fileWrappers];
|
||||
|
||||
enumerator = [fileWrappers keyEnumerator];
|
||||
while((key = [enumerator nextObject]) != nil)
|
||||
if ([wrapper isDirectory])
|
||||
{
|
||||
NSFileWrapper *fw = [fileWrappers objectForKey: key];
|
||||
if([fw isRegularFile])
|
||||
NSDictionary *fileWrappers = nil;
|
||||
NSString *key = nil;
|
||||
NSArray *imageFileTypes = [NSImage imageFileTypes];
|
||||
NSArray *soundFileTypes = [NSSound soundUnfilteredFileTypes];
|
||||
NSEnumerator *enumerator = nil;
|
||||
|
||||
key = nil;
|
||||
fileWrappers = [wrapper fileWrappers];
|
||||
|
||||
[self saveSCMDirectory: fileWrappers];
|
||||
|
||||
enumerator = [fileWrappers keyEnumerator];
|
||||
while((key = [enumerator nextObject]) != nil)
|
||||
{
|
||||
NSData *fileData = [fw regularFileContents];
|
||||
if ([imageFileTypes containsObject: [key pathExtension]])
|
||||
NSFileWrapper *fw = [fileWrappers objectForKey: key];
|
||||
if([fw isRegularFile])
|
||||
{
|
||||
[images addObject: [GormImage imageForData: fileData
|
||||
withFileName: key
|
||||
inWrapper: YES]];
|
||||
}
|
||||
else if ([soundFileTypes containsObject: [key pathExtension]])
|
||||
{
|
||||
[sounds addObject: [GormSound soundForData: fileData
|
||||
withFileName: key
|
||||
inWrapper: YES]];
|
||||
NSData *fileData = [fw regularFileContents];
|
||||
if ([imageFileTypes containsObject: [key pathExtension]])
|
||||
{
|
||||
[images addObject: [GormImage imageForData: fileData
|
||||
withFileName: key
|
||||
inWrapper: YES]];
|
||||
}
|
||||
else if ([soundFileTypes containsObject: [key pathExtension]])
|
||||
{
|
||||
[sounds addObject: [GormSound soundForData: fileData
|
||||
withFileName: key
|
||||
inWrapper: YES]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fill in the images and sounds arrays...
|
||||
[document setSounds: sounds];
|
||||
[document setImages: images];
|
||||
}
|
||||
else
|
||||
NS_HANDLER
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
NS_ENDHANDLER;
|
||||
|
||||
return YES;
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -329,6 +329,8 @@
|
|||
|
||||
- (BOOL) loadFileWrapper: (NSFileWrapper *)wrapper withDocument: (GormDocument *) doc
|
||||
{
|
||||
BOOL result = NO;
|
||||
|
||||
NS_DURING
|
||||
{
|
||||
NSData *data = nil;
|
||||
|
@ -361,234 +363,255 @@
|
|||
GormClassManager *classManager = [document classManager];
|
||||
|
||||
key = nil;
|
||||
fileWrappers = [wrapper fileWrappers];
|
||||
|
||||
enumerator = [fileWrappers keyEnumerator];
|
||||
while((key = [enumerator nextObject]) != nil)
|
||||
if ([wrapper isDirectory])
|
||||
{
|
||||
NSFileWrapper *fw = [fileWrappers objectForKey: key];
|
||||
if([fw isRegularFile])
|
||||
fileWrappers = [wrapper fileWrappers];
|
||||
|
||||
enumerator = [fileWrappers keyEnumerator];
|
||||
while((key = [enumerator nextObject]) != nil)
|
||||
{
|
||||
NSData *fileData = [fw regularFileContents];
|
||||
if([key isEqual: @"objects.gorm"])
|
||||
NSFileWrapper *fw = [fileWrappers objectForKey: key];
|
||||
if([fw isRegularFile])
|
||||
{
|
||||
data = fileData;
|
||||
}
|
||||
else if([key isEqual: @"data.info"])
|
||||
{
|
||||
[document setInfoData: fileData];
|
||||
}
|
||||
else if([key isEqual: @"data.classes"])
|
||||
{
|
||||
classes = fileData;
|
||||
|
||||
// load the custom classes...
|
||||
if (![classManager loadCustomClassesWithData: classes])
|
||||
NSData *fileData = [fw regularFileContents];
|
||||
if([key isEqual: @"objects.gorm"])
|
||||
{
|
||||
NSRunAlertPanel(_(@"Problem Loading"),
|
||||
_(@"Could not open the associated classes file.\n"
|
||||
@"You won't be able to edit connections on custom classes"),
|
||||
_(@"OK"), nil, nil);
|
||||
data = fileData;
|
||||
}
|
||||
else if([key isEqual: @"data.info"])
|
||||
{
|
||||
[document setInfoData: fileData];
|
||||
}
|
||||
else if([key isEqual: @"data.classes"])
|
||||
{
|
||||
classes = fileData;
|
||||
|
||||
// load the custom classes...
|
||||
if (![classManager loadCustomClassesWithData: classes])
|
||||
{
|
||||
NSRunAlertPanel(_(@"Problem Loading"),
|
||||
_(@"Could not open the associated classes file.\n"
|
||||
@"You won't be able to edit connections on custom classes"),
|
||||
_(@"OK"), nil, nil);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if ([wrapper isRegularFile]) // if it's a file... here we need to handle legacy files.
|
||||
{
|
||||
NSString *classesFileName = [[[document documentPath] stringByDeletingPathExtension]
|
||||
stringByAppendingPathExtension: @"classes"];
|
||||
|
||||
// dump the contents to the data section...
|
||||
data = [wrapper regularFileContents];
|
||||
classes = [NSData dataWithContentsOfFile: classesFileName];
|
||||
|
||||
// load the custom classes...
|
||||
if (![classManager loadCustomClassesWithData: classes])
|
||||
{
|
||||
NSRunAlertPanel(_(@"Problem Loading"),
|
||||
_(@"Could not open the associated classes file.\n"
|
||||
@"You won't be able to edit connections on custom classes"),
|
||||
_(@"OK"), nil, nil);
|
||||
}
|
||||
}
|
||||
|
||||
// check the data...
|
||||
// NOTE: If info isn't present, then it's an older archive which
|
||||
// doesn't contain that file.
|
||||
if (data == nil || classes == nil)
|
||||
{
|
||||
return NO;
|
||||
result = NO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an unarchiver, and use it to unarchive the gorm file while
|
||||
* handling class replacement so that standard objects understood
|
||||
* by the gui library are converted to their Gorm internal equivalents.
|
||||
*/
|
||||
u = [[NSUnarchiver alloc] initForReadingWithData: data];
|
||||
|
||||
/*
|
||||
* Special internal classes
|
||||
*/
|
||||
[u decodeClassName: @"GSNibItem"
|
||||
asClassName: @"GormObjectProxy"];
|
||||
[u decodeClassName: @"GSCustomView"
|
||||
asClassName: @"GormCustomView"];
|
||||
|
||||
/*
|
||||
* Substitute any classes specified by the palettes...
|
||||
*/
|
||||
while((subClassName = [en nextObject]) != nil)
|
||||
else
|
||||
{
|
||||
NSString *realClassName = [substituteClasses objectForKey: subClassName];
|
||||
[u decodeClassName: realClassName
|
||||
asClassName: subClassName];
|
||||
}
|
||||
|
||||
// turn off custom classes.
|
||||
[GSClassSwapper setIsInInterfaceBuilder: YES];
|
||||
container = [u decodeObject];
|
||||
if (container == nil || [container isKindOfClass: [GSNibContainer class]] == NO)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
// turn on custom classes.
|
||||
[GSClassSwapper setIsInInterfaceBuilder: NO];
|
||||
|
||||
/*
|
||||
* Retrieve the custom class data and refresh the classes view...
|
||||
*/
|
||||
[classManager setCustomClassMap:
|
||||
[NSMutableDictionary dictionaryWithDictionary:
|
||||
[container customClasses]]];
|
||||
|
||||
//
|
||||
// Get all of the visible objects...
|
||||
//
|
||||
visible = [container visibleWindows];
|
||||
visObj = nil;
|
||||
enumerator = [visible objectEnumerator];
|
||||
while((visObj = [enumerator nextObject]) != nil)
|
||||
{
|
||||
[document setObject: visObj isVisibleAtLaunch: YES];
|
||||
}
|
||||
|
||||
//
|
||||
// Get all of the deferred objects...
|
||||
//
|
||||
deferred = [container deferredWindows];
|
||||
defObj = nil;
|
||||
enumerator = [deferred objectEnumerator];
|
||||
while((defObj = [enumerator nextObject]) != nil)
|
||||
{
|
||||
[document setObject: defObj isDeferred: YES];
|
||||
}
|
||||
|
||||
/*
|
||||
* In the newly loaded nib container, we change all the connectors
|
||||
* to hold the objects rather than their names (using our own dummy
|
||||
* object as the 'NSOwner'.
|
||||
*/
|
||||
filesOwner = [document filesOwner];
|
||||
firstResponder = [document firstResponder];
|
||||
ownerClass = [[container nameTable] objectForKey: @"NSOwner"];
|
||||
if (ownerClass)
|
||||
{
|
||||
[filesOwner setClassName: ownerClass];
|
||||
}
|
||||
// [[container nameTable] removeObjectForKey: @"NSOwner"];
|
||||
// [[container nameTable] removeObjectForKey: @"NSFirst"];
|
||||
[[container nameTable] setObject: filesOwner forKey: @"NSOwner"];
|
||||
[[container nameTable] setObject: firstResponder forKey: @"NSFirst"];
|
||||
|
||||
//
|
||||
// Add entries...
|
||||
//
|
||||
[[document nameTable] addEntriesFromDictionary: [container nameTable]];
|
||||
|
||||
//
|
||||
// Add top level items...
|
||||
//
|
||||
objs = [[container topLevelObjects] allObjects];
|
||||
[[document topLevelObjects] addObjectsFromArray: objs];
|
||||
|
||||
//
|
||||
// Add connections
|
||||
//
|
||||
connections = [document connections];
|
||||
[connections addObjectsFromArray: [container connections]];
|
||||
|
||||
/* Iterate over the contents of nameTable and create the connections */
|
||||
nt = [document nameTable];
|
||||
enumerator = [connections objectEnumerator];
|
||||
while ((con = [enumerator nextObject]) != nil)
|
||||
{
|
||||
NSString *name;
|
||||
id obj;
|
||||
/*
|
||||
* Create an unarchiver, and use it to unarchive the gorm file while
|
||||
* handling class replacement so that standard objects understood
|
||||
* by the gui library are converted to their Gorm internal equivalents.
|
||||
*/
|
||||
u = [[NSUnarchiver alloc] initForReadingWithData: data];
|
||||
|
||||
name = (NSString*)[con source];
|
||||
obj = [nt objectForKey: name];
|
||||
[con setSource: obj];
|
||||
name = (NSString*)[con destination];
|
||||
obj = [nt objectForKey: name];
|
||||
[con setDestination: obj];
|
||||
}
|
||||
|
||||
/*
|
||||
* If the GSNibContainer version is 0, we need to add the top level objects
|
||||
* to the list so that they can be properly processed.
|
||||
*/
|
||||
version = [u versionForClassName: NSStringFromClass([GSNibContainer class])];
|
||||
if(version == 0)
|
||||
{
|
||||
id obj;
|
||||
NSEnumerator *en = [nt objectEnumerator];
|
||||
/*
|
||||
* Special internal classes
|
||||
*/
|
||||
[u decodeClassName: @"GSNibItem"
|
||||
asClassName: @"GormObjectProxy"];
|
||||
[u decodeClassName: @"GSCustomView"
|
||||
asClassName: @"GormCustomView"];
|
||||
|
||||
// get all of the GSNibItem subclasses which could be top level objects
|
||||
while((obj = [en nextObject]) != nil)
|
||||
/*
|
||||
* Substitute any classes specified by the palettes...
|
||||
*/
|
||||
while((subClassName = [en nextObject]) != nil)
|
||||
{
|
||||
if([obj isKindOfClass: [GSNibItem class]] &&
|
||||
[obj isKindOfClass: [GSCustomView class]] == NO)
|
||||
NSString *realClassName = [substituteClasses objectForKey: subClassName];
|
||||
[u decodeClassName: realClassName
|
||||
asClassName: subClassName];
|
||||
}
|
||||
|
||||
// turn off custom classes.
|
||||
[GSClassSwapper setIsInInterfaceBuilder: YES];
|
||||
container = [u decodeObject];
|
||||
if (container == nil || [container isKindOfClass: [GSNibContainer class]] == NO)
|
||||
{
|
||||
result = NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
// turn on custom classes.
|
||||
[GSClassSwapper setIsInInterfaceBuilder: NO];
|
||||
|
||||
//
|
||||
// Retrieve the custom class data and refresh the classes view...
|
||||
//
|
||||
[classManager setCustomClassMap:
|
||||
[NSMutableDictionary dictionaryWithDictionary:
|
||||
[container customClasses]]];
|
||||
|
||||
//
|
||||
// Get all of the visible objects...
|
||||
//
|
||||
visible = [container visibleWindows];
|
||||
visObj = nil;
|
||||
enumerator = [visible objectEnumerator];
|
||||
while((visObj = [enumerator nextObject]) != nil)
|
||||
{
|
||||
[[container topLevelObjects] addObject: obj];
|
||||
[document setObject: visObj isVisibleAtLaunch: YES];
|
||||
}
|
||||
}
|
||||
[document setOlderArchive: YES];
|
||||
}
|
||||
else if(version == 1)
|
||||
{
|
||||
// nothing else, just mark it as older...
|
||||
[document setOlderArchive: YES];
|
||||
}
|
||||
|
||||
/*
|
||||
* If the GSWindowTemplate version is 0, we need to let Gorm know that this is
|
||||
* an older archive. Also, if the window template is not in the archive we know
|
||||
* it was made by an older version of Gorm.
|
||||
*/
|
||||
version = [u versionForClassName: NSStringFromClass([GSWindowTemplate class])];
|
||||
if(version == NSNotFound && [self _containsKindOfClass: [NSWindow class]])
|
||||
{
|
||||
[document setOlderArchive: YES];
|
||||
}
|
||||
|
||||
/*
|
||||
* Rebuild the mapping from object to name for the nameTable...
|
||||
*/
|
||||
[document rebuildObjToNameMapping];
|
||||
|
||||
/*
|
||||
* Repair the .gorm file, if needed.
|
||||
*/
|
||||
if(repairFile)
|
||||
{
|
||||
[self _repairFile];
|
||||
}
|
||||
|
||||
NSDebugLog(@"nameTable = %@",[container nameTable]);
|
||||
|
||||
// awaken all elements after the load is completed.
|
||||
enumerator = [nt keyEnumerator];
|
||||
while ((key = [enumerator nextObject]) != nil)
|
||||
{
|
||||
id o = [nt objectForKey: key];
|
||||
if ([o respondsToSelector: @selector(awakeFromDocument:)])
|
||||
{
|
||||
[o awakeFromDocument: document];
|
||||
|
||||
//
|
||||
// Get all of the deferred objects...
|
||||
//
|
||||
deferred = [container deferredWindows];
|
||||
defObj = nil;
|
||||
enumerator = [deferred objectEnumerator];
|
||||
while((defObj = [enumerator nextObject]) != nil)
|
||||
{
|
||||
[document setObject: defObj isDeferred: YES];
|
||||
}
|
||||
|
||||
//
|
||||
// In the newly loaded nib container, we change all the connectors
|
||||
// to hold the objects rather than their names (using our own dummy
|
||||
// object as the 'NSOwner'.
|
||||
//
|
||||
filesOwner = [document filesOwner];
|
||||
firstResponder = [document firstResponder];
|
||||
ownerClass = [[container nameTable] objectForKey: @"NSOwner"];
|
||||
if (ownerClass)
|
||||
{
|
||||
[filesOwner setClassName: ownerClass];
|
||||
}
|
||||
[[container nameTable] setObject: filesOwner forKey: @"NSOwner"];
|
||||
[[container nameTable] setObject: firstResponder forKey: @"NSFirst"];
|
||||
|
||||
//
|
||||
// Add entries...
|
||||
//
|
||||
[[document nameTable] addEntriesFromDictionary: [container nameTable]];
|
||||
|
||||
//
|
||||
// Add top level items...
|
||||
//
|
||||
objs = [[container topLevelObjects] allObjects];
|
||||
[[document topLevelObjects] addObjectsFromArray: objs];
|
||||
|
||||
//
|
||||
// Add connections
|
||||
//
|
||||
connections = [document connections];
|
||||
[connections addObjectsFromArray: [container connections]];
|
||||
|
||||
/* Iterate over the contents of nameTable and create the connections */
|
||||
nt = [document nameTable];
|
||||
enumerator = [connections objectEnumerator];
|
||||
while ((con = [enumerator nextObject]) != nil)
|
||||
{
|
||||
NSString *name;
|
||||
id obj;
|
||||
|
||||
name = (NSString*)[con source];
|
||||
obj = [nt objectForKey: name];
|
||||
[con setSource: obj];
|
||||
name = (NSString*)[con destination];
|
||||
obj = [nt objectForKey: name];
|
||||
[con setDestination: obj];
|
||||
}
|
||||
|
||||
/*
|
||||
* If the GSNibContainer version is 0, we need to add the top level objects
|
||||
* to the list so that they can be properly processed.
|
||||
*/
|
||||
version = [u versionForClassName: NSStringFromClass([GSNibContainer class])];
|
||||
if(version == 0)
|
||||
{
|
||||
id obj;
|
||||
NSEnumerator *en = [nt objectEnumerator];
|
||||
|
||||
// get all of the GSNibItem subclasses which could be top level objects
|
||||
while((obj = [en nextObject]) != nil)
|
||||
{
|
||||
if([obj isKindOfClass: [GSNibItem class]] &&
|
||||
[obj isKindOfClass: [GSCustomView class]] == NO)
|
||||
{
|
||||
[[container topLevelObjects] addObject: obj];
|
||||
}
|
||||
}
|
||||
[document setOlderArchive: YES];
|
||||
}
|
||||
else if(version == 1)
|
||||
{
|
||||
// nothing else, just mark it as older...
|
||||
[document setOlderArchive: YES];
|
||||
}
|
||||
|
||||
/*
|
||||
* If the GSWindowTemplate version is 0, we need to let Gorm know that this is
|
||||
* an older archive. Also, if the window template is not in the archive we know
|
||||
* it was made by an older version of Gorm.
|
||||
*/
|
||||
version = [u versionForClassName: NSStringFromClass([GSWindowTemplate class])];
|
||||
if(version == NSNotFound && [self _containsKindOfClass: [NSWindow class]])
|
||||
{
|
||||
[document setOlderArchive: YES];
|
||||
}
|
||||
|
||||
/*
|
||||
* Rebuild the mapping from object to name for the nameTable...
|
||||
*/
|
||||
[document rebuildObjToNameMapping];
|
||||
|
||||
/*
|
||||
* Repair the .gorm file, if needed.
|
||||
*/
|
||||
if(repairFile)
|
||||
{
|
||||
[self _repairFile];
|
||||
}
|
||||
|
||||
NSDebugLog(@"nameTable = %@",[container nameTable]);
|
||||
|
||||
// awaken all elements after the load is completed.
|
||||
enumerator = [nt keyEnumerator];
|
||||
while ((key = [enumerator nextObject]) != nil)
|
||||
{
|
||||
id o = [nt objectForKey: key];
|
||||
if ([o respondsToSelector: @selector(awakeFromDocument:)])
|
||||
{
|
||||
[o awakeFromDocument: document];
|
||||
}
|
||||
}
|
||||
|
||||
// document opened...
|
||||
[document setDocumentOpen: YES];
|
||||
|
||||
// release the unarchiver..
|
||||
RELEASE(u);
|
||||
|
||||
// done...
|
||||
result = YES;
|
||||
}
|
||||
}
|
||||
|
||||
// document opened...
|
||||
[document setDocumentOpen: YES];
|
||||
|
||||
// release the unarchiver..
|
||||
RELEASE(u);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
NS_HANDLER
|
||||
|
@ -596,11 +619,11 @@
|
|||
NSRunAlertPanel(_(@"Problem Loading"),
|
||||
[NSString stringWithFormat: @"Failed to load file. Exception: %@",[localException reason]],
|
||||
_(@"OK"), nil, nil);
|
||||
return NO;
|
||||
result = NO;
|
||||
}
|
||||
NS_ENDHANDLER;
|
||||
|
||||
// if we made it here, then it was a success....
|
||||
return YES;
|
||||
return result;
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -82,7 +82,8 @@
|
|||
NSString *subClassName = nil;
|
||||
NSDictionary *fileWrappers = nil;
|
||||
|
||||
if ([super loadFileWrapper: wrapper withDocument: doc])
|
||||
if ([super loadFileWrapper: wrapper withDocument: doc] &&
|
||||
[wrapper isDirectory])
|
||||
{
|
||||
GormClassManager *classManager = [document classManager];
|
||||
id docFilesOwner;
|
||||
|
|
Loading…
Reference in a new issue