mirror of
https://github.com/gnustep/apps-gorm.git
synced 2025-02-23 19:51:00 +00:00
Nib support changes.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/apps/gorm/trunk@23043 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
5fa3ae3247
commit
145a8afd69
16 changed files with 1507 additions and 699 deletions
19
ChangeLog
19
ChangeLog
|
@ -1,3 +1,22 @@
|
|||
2006-06-10 09:24 Gregory John Casamento <greg_casamento@yahoo.com>
|
||||
|
||||
* GormCore/GModelDecoder.m: Changes to make this compile with
|
||||
new modifications.
|
||||
* GormCore/GNUmakefile: Addition of new files.
|
||||
* GormCore/GormCustomView.m:Encoding changes for NSCustomView.
|
||||
* GormCore/GormDocumentController.m: Removed touch, so that it
|
||||
is possible to quit when first creating a new document, this is the
|
||||
way other document oriented apps behave.
|
||||
* GormCore/GormDocument.[hm]: Added container methods and
|
||||
coding methods.
|
||||
* GormCore/GormGormWrapperBuilder.m: Class whic writes gorm files.
|
||||
* GormCore/GormGormWrapperLoader.m: Class which loads gorm files
|
||||
* GormCore/GormPrivate.[hm]: Simplification of init call to
|
||||
GormObjectProxy.
|
||||
* GormCore/GormWrapperBuilder.[hm]: Wrapper builder
|
||||
* GormCore/GormWrapperLoader.[hm]: Wrapper loader
|
||||
* Gorm.m: Change testInterface to encode the doc.
|
||||
|
||||
2006-06-05 21:20 Gregory John Casamento <greg_casamento@yahoo.com>
|
||||
|
||||
* GormCore/GormDocumentController.m: touches the initial document
|
||||
|
|
9
Gorm.m
9
Gorm.m
|
@ -42,7 +42,7 @@
|
|||
NSMutableArray *documents;
|
||||
BOOL isConnecting;
|
||||
BOOL isTesting;
|
||||
id testContainer;
|
||||
id testContainer;
|
||||
id gormMenu;
|
||||
NSMenu *mainMenu; // saves the main menu...
|
||||
NSMenu *servicesMenu; // saves the services menu...
|
||||
|
@ -451,7 +451,7 @@
|
|||
|
||||
// do not allow custom classes during testing.
|
||||
[GSClassSwapper setIsInInterfaceBuilder: YES];
|
||||
[archiver encodeRootObject: [activeDoc container]];
|
||||
[archiver encodeRootObject: activeDoc];
|
||||
data = RETAIN([archiver archiverData]); // Released below...
|
||||
[activeDoc endArchiving];
|
||||
RELEASE(archiver);
|
||||
|
@ -478,6 +478,7 @@
|
|||
NSMutableDictionary *nameTable = [testContainer nameTable];
|
||||
|
||||
// initialize the context.
|
||||
RETAIN(testContainer);
|
||||
topObjects = [[NSMutableArray alloc] init];
|
||||
context = [NSDictionary dictionaryWithObjectsAndKeys: topObjects,
|
||||
@"NSTopLevelObjects", self, @"NSOwner", nil];
|
||||
|
@ -859,8 +860,8 @@
|
|||
|
||||
DESTROY(testingWindows);
|
||||
|
||||
// deallocate top level objects
|
||||
RELEASE(topObjects);
|
||||
// deallocate
|
||||
RELEASE(testContainer);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
|
|
@ -563,11 +563,11 @@ static BOOL gormFileOwnerDecoded;
|
|||
[newcon setSource: source];
|
||||
[newcon setDestination: (dest != nil)?dest:[self firstResponder]];
|
||||
[newcon setLabel: [con label]];
|
||||
[[container connections] addObject: newcon];
|
||||
[[self connections] addObject: newcon];
|
||||
}
|
||||
|
||||
// make sure that all of the actions on the application's delegate object are also added to FirstResponder.
|
||||
enumerator = [[container connections] objectEnumerator];
|
||||
enumerator = [connections objectEnumerator];
|
||||
while ((con = [enumerator nextObject]) != nil)
|
||||
{
|
||||
if([con isKindOfClass: [NSNibControlConnector class]])
|
||||
|
|
|
@ -86,6 +86,8 @@ GormCore_HEADER_FILES = \
|
|||
GormViewWithContentViewEditor.h \
|
||||
GormViewWithSubviewsEditor.h \
|
||||
GormWindowEditor.h \
|
||||
GormWrapperBuilder.h \
|
||||
GormWrapperLoader.h \
|
||||
NSCell+GormAdditions.h \
|
||||
NSColorWell+GormExtensions.h \
|
||||
NSFontManager+GormExtensions.h \
|
||||
|
@ -139,6 +141,10 @@ GormCore_OBJC_FILES = \
|
|||
GormViewWithContentViewEditor.m \
|
||||
GormViewWithSubviewsEditor.m \
|
||||
GormWindowEditor.m \
|
||||
GormWrapperBuilder.m \
|
||||
GormWrapperLoader.m \
|
||||
GormGormWrapperBuilder.m \
|
||||
GormGormWrapperLoader.m \
|
||||
NSCell+GormAdditions.m \
|
||||
NSColorWell+GormExtensions.m \
|
||||
NSFontManager+GormExtensions.m \
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <AppKit/NSNibLoading.h>
|
||||
|
||||
#include <GNUstepGUI/GSNibTemplates.h>
|
||||
#include <GNUstepGUI/GSNibCompatibility.h>
|
||||
|
||||
@class GSCustomView;
|
||||
|
||||
|
@ -87,38 +88,50 @@
|
|||
|
||||
- (id) initWithCoder: (NSCoder*)aCoder
|
||||
{
|
||||
int version = [aCoder versionForClassName:
|
||||
NSStringFromClass([GSCustomView class])];
|
||||
|
||||
if (version == 1)
|
||||
if([aCoder allowsKeyedCoding])
|
||||
{
|
||||
NSString *string;
|
||||
// do not decode super. We need to maintain mapping to NibItems
|
||||
string = [aCoder decodeObject];
|
||||
_frame = [aCoder decodeRect];
|
||||
[self initWithFrame: _frame];
|
||||
[aCoder decodeValueOfObjCType: @encode(unsigned int)
|
||||
at: &_autoresizingMask];
|
||||
[self setClassName: string];
|
||||
return self;
|
||||
}
|
||||
else if (version == 0)
|
||||
{
|
||||
NSString *string;
|
||||
// do not decode super. We need to maintain mapping to NibItems
|
||||
string = [aCoder decodeObject];
|
||||
_frame = [aCoder decodeRect];
|
||||
|
||||
[self initWithFrame: _frame];
|
||||
[self setClassName: string];
|
||||
return self;
|
||||
NSCustomView *customView = [[NSCustomView alloc] initWithCoder: aCoder];
|
||||
[self initWithFrame: [customView frame]];
|
||||
[self setClassName: [customView className]];
|
||||
_autoresizingMask = [customView autoresizingMask];
|
||||
RELEASE(customView);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"no initWithCoder for version");
|
||||
RELEASE(self);
|
||||
return nil;
|
||||
int version = [aCoder versionForClassName:
|
||||
NSStringFromClass([GSCustomView class])];
|
||||
|
||||
if (version == 1)
|
||||
{
|
||||
NSString *string;
|
||||
// do not decode super. We need to maintain mapping to NibItems
|
||||
string = [aCoder decodeObject];
|
||||
_frame = [aCoder decodeRect];
|
||||
[self initWithFrame: _frame];
|
||||
[aCoder decodeValueOfObjCType: @encode(unsigned int)
|
||||
at: &_autoresizingMask];
|
||||
[self setClassName: string];
|
||||
return self;
|
||||
}
|
||||
else if (version == 0)
|
||||
{
|
||||
NSString *string;
|
||||
// do not decode super. We need to maintain mapping to NibItems
|
||||
string = [aCoder decodeObject];
|
||||
_frame = [aCoder decodeRect];
|
||||
|
||||
[self initWithFrame: _frame];
|
||||
[self setClassName: string];
|
||||
return self;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"no initWithCoder for version");
|
||||
RELEASE(self);
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
@end
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include <GNUstepGUI/GSNibTemplates.h>
|
||||
#include <InterfaceBuilder/InterfaceBuilder.h>
|
||||
|
||||
@class GormClassManager, GormClassEditor, GormObjectProxy, GormFilesOwner;
|
||||
@class GormClassManager, GormClassEditor, GormObjectProxy, GormFilesOwner, GormFilePrefsManager;
|
||||
|
||||
/*
|
||||
* Each document has a GormFirstResponder object that is used as a placeholder
|
||||
|
@ -42,7 +42,7 @@
|
|||
}
|
||||
@end
|
||||
|
||||
@interface GormDocument : NSDocument <IBDocuments>
|
||||
@interface GormDocument : NSDocument <IBDocuments, GSNibContainer, NSCoding>
|
||||
{
|
||||
GormClassManager *classManager;
|
||||
GormFilesOwner *filesOwner;
|
||||
|
@ -70,14 +70,20 @@
|
|||
id lastEditor;
|
||||
BOOL isOlderArchive;
|
||||
id filePrefsView;
|
||||
id filePrefsManager;
|
||||
GormFilePrefsManager *filePrefsManager;
|
||||
NSWindow *filePrefsWindow;
|
||||
NSMutableArray *resourceManagers;
|
||||
NSData *infoData; /* data.info contents */
|
||||
NSMutableArray *images; /* temporary storage for images. */
|
||||
NSMutableArray *sounds; /* temporary storage for sounds. */
|
||||
NSFileWrapper *scmDirWrapper;
|
||||
id<GSNibContainer, NSObject> container;
|
||||
NSFileWrapper *scmWrapper;
|
||||
|
||||
// container data structures
|
||||
NSMutableDictionary *nameTable;
|
||||
NSMutableArray *connections;
|
||||
NSMutableSet *topLevelObjects;
|
||||
NSMutableSet *visibleWindows;
|
||||
NSMutableSet *deferredWindows;
|
||||
}
|
||||
|
||||
/* Archiving objects */
|
||||
|
@ -146,11 +152,6 @@
|
|||
*/
|
||||
- (NSWindow*) window;
|
||||
|
||||
/**
|
||||
* Return the container object associated with this document.
|
||||
*/
|
||||
- (id<GSNibContainer>) container;
|
||||
|
||||
/**
|
||||
* Returns YES, if obj is a top level object.
|
||||
*/
|
||||
|
@ -311,9 +312,66 @@
|
|||
- (NSWindow*) windowAndRect: (NSRect*)r forObject: (id)object;
|
||||
|
||||
/**
|
||||
* The container class to use in editing....
|
||||
* Save the SCM directory.
|
||||
*/
|
||||
- (Class) containerClass;
|
||||
- (void) setSCMWrapper: (NSFileWrapper *) wrapper;
|
||||
|
||||
/**
|
||||
* Save the SCM directory.
|
||||
*/
|
||||
- (NSFileWrapper *) scmWrapper;
|
||||
|
||||
/**
|
||||
* Images
|
||||
*/
|
||||
- (NSArray *) images;
|
||||
|
||||
/**
|
||||
* Sounds
|
||||
*/
|
||||
- (NSArray *) sounds;
|
||||
|
||||
/**
|
||||
* Images
|
||||
*/
|
||||
- (void) setImages: (NSArray *) imgs;
|
||||
|
||||
/**
|
||||
* Sounds
|
||||
*/
|
||||
- (void) setSounds: (NSArray *) snds;
|
||||
|
||||
/**
|
||||
* File's Owner
|
||||
*/
|
||||
- (GormFilesOwner *) filesOwner;
|
||||
|
||||
/**
|
||||
* File preferences.
|
||||
*/
|
||||
- (GormFilePrefsManager *) filePrefsManager;
|
||||
|
||||
/**
|
||||
* Windows visible at launch...
|
||||
*/
|
||||
- (NSSet *) visibleWindows;
|
||||
|
||||
/**
|
||||
* Windows deferred.
|
||||
*/
|
||||
- (NSSet *) deferredWindows;
|
||||
|
||||
- (void) setDocumentOpen: (BOOL) flag;
|
||||
|
||||
- (BOOL) isDocumentOpen;
|
||||
|
||||
- (void) setInfoData: (NSData *)data;
|
||||
|
||||
- (NSData *) infoData;
|
||||
|
||||
- (void) setOlderArchive: (BOOL)flag;
|
||||
|
||||
- (BOOL) isOlderArchive;
|
||||
@end
|
||||
|
||||
@interface GormDocument (MenuValidation)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -188,7 +188,6 @@
|
|||
|
||||
// set the filetype and touch the document.
|
||||
[doc setFileType: @"GSGormFileType"];
|
||||
[doc touch];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
195
GormCore/GormGormWrapperBuilder.m
Normal file
195
GormCore/GormGormWrapperBuilder.m
Normal file
|
@ -0,0 +1,195 @@
|
|||
/* GormWrapperBuilder
|
||||
*
|
||||
* This class is a subclass of the NSDocumentController
|
||||
*
|
||||
* Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* Author: Gregory John Casamento <greg_casamento@yahoo.com>
|
||||
* Date: 2006
|
||||
*
|
||||
* This file is part of GNUstep.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
|
||||
*/
|
||||
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <GNUstepGUI/GSNibTemplates.h>
|
||||
#include <GormCore/GormWrapperBuilder.h>
|
||||
#include <GormCore/GormClassManager.h>
|
||||
#include <GormCore/GormFilePrefsManager.h>
|
||||
#include <GormCore/GormDocument.h>
|
||||
#include <GormCore/GormProtocol.h>
|
||||
#include <GormCore/GormPalettesManager.h>
|
||||
|
||||
@interface GSNibContainer (BuilderAdditions)
|
||||
- (id) initWithDocument: (GormDocument *)document;
|
||||
@end;
|
||||
|
||||
@implementation GSNibContainer (BuilderAdditions)
|
||||
- (id) initWithDocument: (GormDocument *)document
|
||||
{
|
||||
if((self = [self init]) != nil)
|
||||
{
|
||||
NSMutableArray *visible = [nameTable objectForKey: @"NSVisible"];
|
||||
NSMutableArray *deferred = [nameTable objectForKey: @"NSDeferred"];
|
||||
|
||||
// Create the container for the .gorm file...
|
||||
[nameTable addEntriesFromDictionary: [document nameTable]];
|
||||
[topLevelObjects addObjectsFromArray: [[document topLevelObjects] allObjects]];
|
||||
[visible addObjectsFromArray: [[document visibleWindows] allObjects]];
|
||||
[deferred addObjectsFromArray: [[document deferredWindows] allObjects]];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
|
||||
@interface GormGormWrapperBuilder : GormWrapperBuilder
|
||||
@end
|
||||
|
||||
@implementation GormGormWrapperBuilder
|
||||
+ (NSString *) type
|
||||
{
|
||||
return @"GSGormFileType";
|
||||
}
|
||||
|
||||
/**
|
||||
* Private method which iterates through the list of custom classes and instructs
|
||||
* the archiver to replace the actual object with template during the archiving
|
||||
* process.
|
||||
*/
|
||||
- (void) _replaceObjectsWithTemplates: (NSArchiver *)archiver
|
||||
{
|
||||
NSEnumerator *en = [[document nameTable] keyEnumerator];
|
||||
GormClassManager *classManager = [document classManager];
|
||||
GormFilePrefsManager *filePrefsManager = [document filePrefsManager];
|
||||
id key = nil;
|
||||
|
||||
// loop through all custom objects and windows
|
||||
while((key = [en nextObject]) != nil)
|
||||
{
|
||||
id customClass = [classManager customClassForName: key];
|
||||
id object = [document objectForName: key];
|
||||
id template = nil;
|
||||
if(customClass != nil)
|
||||
{
|
||||
NSString *superClass = [classManager nonCustomSuperClassOf: customClass];
|
||||
template = [GSTemplateFactory templateForObject: object
|
||||
withClassName: customClass
|
||||
withSuperClassName: superClass];
|
||||
}
|
||||
else if([object isKindOfClass: [NSWindow class]]
|
||||
&& [filePrefsManager versionOfClass: @"GSWindowTemplate"] > 0)
|
||||
{
|
||||
template = [GSTemplateFactory templateForObject: object
|
||||
withClassName: [object className]
|
||||
withSuperClassName: [object className]];
|
||||
|
||||
}
|
||||
|
||||
// if the template has been created, replace the object with it.
|
||||
if(template != nil)
|
||||
{
|
||||
// if the object is deferrable, then set the flag appropriately.
|
||||
if([template respondsToSelector: @selector(setDeferFlag:)])
|
||||
{
|
||||
[template setDeferFlag: [document objectIsDeferred: object]];
|
||||
}
|
||||
|
||||
// if the object can accept autoposition information
|
||||
if([object respondsToSelector: @selector(autoPositionMask)])
|
||||
{
|
||||
int mask = [object autoPositionMask];
|
||||
if([template respondsToSelector: @selector(setAutoPositionMask:)])
|
||||
{
|
||||
[template setAutoPositionMask: mask];
|
||||
}
|
||||
}
|
||||
|
||||
// replace the object with the template.
|
||||
[archiver replaceObject: object withObject: template];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *)buildFileWrapperDictionaryWithDocument: (GormDocument *)doc
|
||||
{
|
||||
NSArchiver *archiver = nil;
|
||||
NSMutableData *archiverData = nil;
|
||||
NSString *gormPath = @"objects.gorm";
|
||||
NSString *classesPath = @"data.classes";
|
||||
NSString *infoPath = @"data.info";
|
||||
GormPalettesManager *palettesManager = [(id<Gorm>)NSApp palettesManager];
|
||||
NSDictionary *substituteClasses = [palettesManager substituteClasses];
|
||||
NSEnumerator *en = [substituteClasses keyEnumerator];
|
||||
NSString *subClassName = nil;
|
||||
NSFileWrapper *fileWrapper = nil;
|
||||
NSMutableDictionary *fileWrappers = [super buildFileWrapperDictionaryWithDocument: doc];
|
||||
|
||||
if(fileWrappers)
|
||||
{
|
||||
GormClassManager *classManager = [document classManager];
|
||||
GormFilePrefsManager *filePrefsManager = [document filePrefsManager];
|
||||
GSNibContainer *container = [[GSNibContainer alloc] initWithDocument: document];
|
||||
|
||||
/*
|
||||
* Set up archiving...
|
||||
*/
|
||||
archiverData = [NSMutableData dataWithCapacity: 0];
|
||||
archiver = [[NSArchiver alloc] initForWritingWithMutableData: archiverData];
|
||||
|
||||
/*
|
||||
* Special gorm classes to their archive equivalents.
|
||||
*/
|
||||
[archiver encodeClassName: @"GormObjectProxy"
|
||||
intoClassName: @"GSNibItem"];
|
||||
[archiver encodeClassName: @"GormCustomView"
|
||||
intoClassName: @"GSCustomView"];
|
||||
|
||||
|
||||
while((subClassName = [en nextObject]) != nil)
|
||||
{
|
||||
NSString *realClassName = [substituteClasses objectForKey: subClassName];
|
||||
[archiver encodeClassName: subClassName
|
||||
intoClassName: realClassName];
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize templates
|
||||
*/
|
||||
[self _replaceObjectsWithTemplates: archiver];
|
||||
[archiver encodeRootObject: container];
|
||||
RELEASE(archiver); // We're done with the archiver here..
|
||||
|
||||
/*
|
||||
* Add the gorm, info and classes files to the package.
|
||||
*/
|
||||
fileWrapper = [[NSFileWrapper alloc] initRegularFileWithContents: archiverData];
|
||||
[fileWrappers setObject: fileWrapper forKey: gormPath];
|
||||
RELEASE(fileWrapper);
|
||||
fileWrapper = [[NSFileWrapper alloc] initRegularFileWithContents: [classManager data]];
|
||||
[fileWrappers setObject: fileWrapper forKey: classesPath];
|
||||
RELEASE(fileWrapper);
|
||||
fileWrapper = [[NSFileWrapper alloc] initRegularFileWithContents: [filePrefsManager data]];
|
||||
[fileWrappers setObject: fileWrapper forKey: infoPath];
|
||||
RELEASE(fileWrapper);
|
||||
|
||||
// release the container...
|
||||
RELEASE(container);
|
||||
}
|
||||
|
||||
return fileWrappers;
|
||||
}
|
||||
@end
|
410
GormCore/GormGormWrapperLoader.m
Normal file
410
GormCore/GormGormWrapperLoader.m
Normal file
|
@ -0,0 +1,410 @@
|
|||
/* GormDocumentController.m
|
||||
*
|
||||
* This class is a subclass of the NSDocumentController
|
||||
*
|
||||
* Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* Author: Gregory John Casamento <greg_casamento@yahoo.com>
|
||||
* Date: 2006
|
||||
*
|
||||
* This file is part of GNUstep.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
|
||||
*/
|
||||
|
||||
#include <GormCore/GormWrapperLoader.h>
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <GormCore/GormPalettesManager.h>
|
||||
#include <GormCore/GormClassManager.h>
|
||||
#include <GormCore/GormImage.h>
|
||||
#include <GormCore/GormSound.h>
|
||||
#include <GormCore/GormPrivate.h>
|
||||
#include <GormCore/NSView+GormExtensions.h>
|
||||
#include <GormCore/GormFunctions.h>
|
||||
|
||||
@interface GormGormWrapperLoader : GormWrapperLoader
|
||||
@end
|
||||
|
||||
@implementation GormGormWrapperLoader
|
||||
+ (NSString *) type
|
||||
{
|
||||
return @"GSGormFileType";
|
||||
}
|
||||
|
||||
/**
|
||||
* The sole purpose of this method is to clean up .gorm files from older
|
||||
* versions of Gorm which might have some dangling references. This method
|
||||
* may be added to as time goes on to make sure that it's possible
|
||||
* to repair old .gorm files.
|
||||
*/
|
||||
- (void) _repairFile
|
||||
{
|
||||
NSEnumerator *en = [[[document nameTable] allKeys] objectEnumerator];
|
||||
NSString *key = nil;
|
||||
|
||||
NSRunAlertPanel(_(@"Warning"),
|
||||
_(@"You are running with 'GormRepairFileOnLoad' set to YES."),
|
||||
nil, nil, nil);
|
||||
|
||||
while((key = [en nextObject]) != nil)
|
||||
{
|
||||
id obj = [[document nameTable] objectForKey: key];
|
||||
if([obj isKindOfClass: [NSMenu class]] && ![key isEqual: @"NSMenu"])
|
||||
{
|
||||
id sm = [obj supermenu];
|
||||
if(sm == nil)
|
||||
{
|
||||
NSArray *menus = findAll(obj);
|
||||
NSLog(@"Found and removed a dangling menu %@, %@.",obj,[document nameForObject: obj]);
|
||||
[document detachObjects: menus];
|
||||
[document detachObject: obj];
|
||||
|
||||
// Since the menu is a top level object, it is not retained by
|
||||
// anything else. When it was unarchived it was autoreleased, and
|
||||
// the detach also does a release. Unfortunately, this causes a
|
||||
// crash, so this extra retain is only here to stave off the
|
||||
// release, so the autorelease can release the menu when it should.
|
||||
RETAIN(obj); // extra retain to stave off autorelease...
|
||||
}
|
||||
}
|
||||
|
||||
if([obj isKindOfClass: [NSMenuItem class]])
|
||||
{
|
||||
id m = [obj menu];
|
||||
if(m == nil)
|
||||
{
|
||||
id sm = [obj submenu];
|
||||
|
||||
NSLog(@"Found and removed a dangling menu item %@, %@.",obj,[document nameForObject: obj]);
|
||||
[document detachObject: obj];
|
||||
|
||||
// if there are any submenus, detach those as well.
|
||||
if(sm != nil)
|
||||
{
|
||||
NSArray *menus = findAll(sm);
|
||||
[document detachObjects: menus];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If it's a view and it does't have a window *AND* it's not a top level object
|
||||
* then it's not a standalone view, it's an orphan. Delete it.
|
||||
*/
|
||||
if([obj isKindOfClass: [NSView class]])
|
||||
{
|
||||
if([obj window] == nil &&
|
||||
[[document topLevelObjects] containsObject: obj] == NO &&
|
||||
[obj hasSuperviewKindOfClass: [NSTabView class]] == NO)
|
||||
{
|
||||
NSLog(@"Found and removed an orphan view %@, %@",obj,[document nameForObject: obj]);
|
||||
[document detachObject: obj];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Private method. Determines if the document contains an instance of a given
|
||||
* class or one of it's subclasses.
|
||||
*/
|
||||
- (BOOL) _containsKindOfClass: (Class)cls
|
||||
{
|
||||
NSEnumerator *en = [[document nameTable] objectEnumerator];
|
||||
id obj = nil;
|
||||
while((obj = [en nextObject]) != nil)
|
||||
{
|
||||
if([obj isKindOfClass: cls])
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) loadFileWrapper: (NSFileWrapper *)wrapper withDocument: (GormDocument *) doc
|
||||
{
|
||||
NS_DURING
|
||||
{
|
||||
NSMutableDictionary *cc = nil;
|
||||
NSData *data = nil;
|
||||
NSData *classes = nil;
|
||||
NSUnarchiver *u = nil;
|
||||
NSEnumerator *enumerator = nil;
|
||||
id <IBConnectors> con = nil;
|
||||
NSString *ownerClass, *key = nil;
|
||||
BOOL repairFile = [[NSUserDefaults standardUserDefaults] boolForKey: @"GormRepairFileOnLoad"];
|
||||
GormPalettesManager *palettesManager = [(id<Gorm>)NSApp palettesManager];
|
||||
NSDictionary *substituteClasses = [palettesManager substituteClasses];
|
||||
NSEnumerator *en = [substituteClasses keyEnumerator];
|
||||
NSString *subClassName = nil;
|
||||
unsigned int version = NSNotFound;
|
||||
NSDictionary *fileWrappers = nil;
|
||||
|
||||
if ([super loadFileWrapper: wrapper withDocument: doc])
|
||||
{
|
||||
GormClassManager *classManager = [document classManager];
|
||||
NSArray *imageFileTypes = [NSImage imageFileTypes];
|
||||
NSArray *soundFileTypes = [NSSound soundUnfilteredFileTypes];
|
||||
NSMutableArray *images = [[NSMutableArray alloc] init];
|
||||
NSMutableArray *sounds = [[NSMutableArray alloc] init];
|
||||
|
||||
key = nil;
|
||||
fileWrappers = [wrapper fileWrappers];
|
||||
|
||||
// [ saveSCMDirectory: fileWrappers];
|
||||
|
||||
enumerator = [fileWrappers keyEnumerator];
|
||||
while((key = [enumerator nextObject]) != nil)
|
||||
{
|
||||
NSFileWrapper *fw = [fileWrappers objectForKey: key];
|
||||
if([fw isRegularFile])
|
||||
{
|
||||
NSData *fileData = [fw regularFileContents];
|
||||
if([key isEqual: @"objects.gorm"])
|
||||
{
|
||||
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 ([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]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check the data...
|
||||
if (data == nil || [document infoData] == nil || classes == nil)
|
||||
{
|
||||
return 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)
|
||||
{
|
||||
NSString *realClassName = [substituteClasses objectForKey: subClassName];
|
||||
[u decodeClassName: realClassName
|
||||
asClassName: subClassName];
|
||||
}
|
||||
|
||||
// turn off custom classes.
|
||||
[GSClassSwapper setIsInInterfaceBuilder: YES];
|
||||
GSNibContainer *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...
|
||||
*/
|
||||
NSMutableDictionary *nt = [container nameTable];
|
||||
|
||||
cc = [nt objectForKey: @"GSCustomClassMap"];
|
||||
if (cc == nil)
|
||||
{
|
||||
cc = [NSMutableDictionary dictionary]; // create an empty one.
|
||||
[nt setObject: cc forKey: @"GSCustomClassMap"];
|
||||
}
|
||||
[classManager setCustomClassMap: cc];
|
||||
[nt removeObjectForKey: @"GSCustomClassMap"];
|
||||
|
||||
//
|
||||
// Get all of the visible objects...
|
||||
//
|
||||
NSArray *visible = [nt objectForKey: @"NSVisible"];
|
||||
id visObj = nil;
|
||||
enumerator = [visible objectEnumerator];
|
||||
while((visObj = [enumerator nextObject]) != nil)
|
||||
{
|
||||
[document setObject: visObj isVisibleAtLaunch: YES];
|
||||
}
|
||||
[nt removeObjectForKey: @"NSVisible"];
|
||||
|
||||
//
|
||||
// Get all of the deferred objects...
|
||||
//
|
||||
NSArray *deferred = [nt objectForKey: @"NSDeferred"];
|
||||
id defObj = nil;
|
||||
enumerator = [deferred objectEnumerator];
|
||||
while((defObj = [enumerator nextObject]) != nil)
|
||||
{
|
||||
[document setObject: defObj isDeferred: YES];
|
||||
}
|
||||
[nt removeObjectForKey: @"NSDeferred"];
|
||||
|
||||
/*
|
||||
* 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'.
|
||||
*/
|
||||
ownerClass = [nt objectForKey: @"NSOwner"];
|
||||
if (ownerClass)
|
||||
{
|
||||
[[document filesOwner] setClassName: ownerClass];
|
||||
}
|
||||
[[container nameTable] removeObjectForKey: @"NSOwner"];
|
||||
[[container nameTable] removeObjectForKey: @"NSFirst"];
|
||||
|
||||
//
|
||||
// Add entries...
|
||||
//
|
||||
[[document nameTable] addEntriesFromDictionary: nt];
|
||||
|
||||
//
|
||||
// Add top level items...
|
||||
//
|
||||
NSArray *objs = [[container topLevelObjects] allObjects];
|
||||
[[document topLevelObjects] addObjectsFromArray: objs];
|
||||
|
||||
|
||||
/* Iterate over the contents of nameTable and create the connections */
|
||||
nt = [document nameTable];
|
||||
enumerator = [[container 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.
|
||||
*/
|
||||
if([u versionForClassName: NSStringFromClass([GSNibContainer class])] == 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];
|
||||
}
|
||||
|
||||
/*
|
||||
* 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];
|
||||
}
|
||||
|
||||
/*
|
||||
* repair the .gorm file, if needed.
|
||||
*/
|
||||
if(repairFile)
|
||||
{
|
||||
[self _repairFile];
|
||||
}
|
||||
|
||||
/*
|
||||
* Rebuild the mapping from object to name for the nameTable...
|
||||
*/
|
||||
[document rebuildObjToNameMapping];
|
||||
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
NSRunAlertPanel(_(@"Problem Loading"),
|
||||
[NSString stringWithFormat: @"Failed to load file. Exception: %@",[localException reason]],
|
||||
_(@"OK"), nil, nil);
|
||||
return NO;
|
||||
}
|
||||
NS_ENDHANDLER;
|
||||
|
||||
// if we made it here, then it was a success....
|
||||
return YES;
|
||||
}
|
||||
@end
|
|
@ -51,7 +51,8 @@ extern NSString *GormResizeCellNotification;
|
|||
|
||||
// templates
|
||||
@interface GSNibItem (GormAdditions)
|
||||
- initWithClassName: (NSString*)className frame: (NSRect)frame;
|
||||
- (id) initWithClassName: (NSString*)className;
|
||||
- (id) initWithClassName: (NSString*)className frame: (NSRect)frame;
|
||||
- (NSString*) className;
|
||||
@end
|
||||
|
||||
|
|
|
@ -49,15 +49,23 @@ static BOOL _isInInterfaceBuilder = NO;
|
|||
#include "GormViewWithContentViewEditor.h"
|
||||
|
||||
@implementation GSNibItem (GormAdditions)
|
||||
- initWithClassName: (NSString*)className frame: (NSRect)frame
|
||||
- (id) initWithClassName: (NSString*)className frame: (NSRect)frame
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
theClass = [className copy];
|
||||
theFrame = frame;
|
||||
|
||||
if((self = [super init]) != nil)
|
||||
{
|
||||
theClass = [className copy];
|
||||
theFrame = frame;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithClassName: (NSString*)className
|
||||
{
|
||||
return [self initWithClassName: className
|
||||
frame: NSMakeRect(0,0,0,0)];
|
||||
}
|
||||
|
||||
|
||||
- (NSString*) className
|
||||
{
|
||||
return theClass;
|
||||
|
@ -109,42 +117,50 @@ static BOOL _isInInterfaceBuilder = NO;
|
|||
*/
|
||||
- (id) initWithCoder: (NSCoder*)aCoder
|
||||
{
|
||||
int version = [aCoder versionForClassName:
|
||||
NSStringFromClass([GSNibItem class])];
|
||||
|
||||
if (version == NSNotFound)
|
||||
if([aCoder allowsKeyedCoding])
|
||||
{
|
||||
NSLog(@"no GSNibItem");
|
||||
version = [aCoder versionForClassName:
|
||||
NSStringFromClass([GormObjectProxy class])];
|
||||
}
|
||||
|
||||
if (version == 0)
|
||||
{
|
||||
// do not decode super (it would try to morph into theClass ! )
|
||||
[aCoder decodeValueOfObjCType: @encode(id) at: &theClass];
|
||||
theFrame = [aCoder decodeRect];
|
||||
RETAIN(theClass); // release in dealloc of GSNibItem...
|
||||
|
||||
return self;
|
||||
}
|
||||
else if (version == 1)
|
||||
{
|
||||
// do not decode super (it would try to morph into theClass ! )
|
||||
[aCoder decodeValueOfObjCType: @encode(id) at: &theClass];
|
||||
theFrame = [aCoder decodeRect];
|
||||
[aCoder decodeValueOfObjCType: @encode(unsigned int)
|
||||
at: &autoresizingMask];
|
||||
RETAIN(theClass); // release in dealloc of GSNibItem...
|
||||
|
||||
return self;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"no initWithCoder for version %d", version);
|
||||
RELEASE(self);
|
||||
return nil;
|
||||
int version = [aCoder versionForClassName:
|
||||
NSStringFromClass([GSNibItem class])];
|
||||
|
||||
if (version == NSNotFound)
|
||||
{
|
||||
NSLog(@"no GSNibItem");
|
||||
version = [aCoder versionForClassName:
|
||||
NSStringFromClass([GormObjectProxy class])];
|
||||
}
|
||||
|
||||
if (version == 0)
|
||||
{
|
||||
// do not decode super (it would try to morph into theClass ! )
|
||||
[aCoder decodeValueOfObjCType: @encode(id) at: &theClass];
|
||||
theFrame = [aCoder decodeRect];
|
||||
RETAIN(theClass); // release in dealloc of GSNibItem...
|
||||
|
||||
return self;
|
||||
}
|
||||
else if (version == 1)
|
||||
{
|
||||
// do not decode super (it would try to morph into theClass ! )
|
||||
[aCoder decodeValueOfObjCType: @encode(id) at: &theClass];
|
||||
theFrame = [aCoder decodeRect];
|
||||
[aCoder decodeValueOfObjCType: @encode(unsigned int)
|
||||
at: &autoresizingMask];
|
||||
RETAIN(theClass); // release in dealloc of GSNibItem...
|
||||
|
||||
return self;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"no initWithCoder for version %d", version);
|
||||
RELEASE(self);
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSString*) inspectorClassName
|
||||
|
|
51
GormCore/GormWrapperBuilder.h
Normal file
51
GormCore/GormWrapperBuilder.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/* GormWrapperBuilder
|
||||
*
|
||||
* This class is a subclass of the NSDocumentController
|
||||
*
|
||||
* Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* Author: Gregory John Casamento <greg_casamento@yahoo.com>
|
||||
* Date: 2006
|
||||
*
|
||||
* This file is part of GNUstep.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GormWrapperBuilder_h
|
||||
#define INCLUDED_GormWrapperBuilder_h
|
||||
|
||||
#include <Foundation/NSObject.h>
|
||||
|
||||
@class NSFileWrapper, GormDocument, NSString, NSMutableDictionary;
|
||||
|
||||
@protocol GormWrapperBuilder
|
||||
- (NSMutableDictionary *) buildFileWrapperDictionaryWithDocument: (GormDocument *)document;
|
||||
- (NSFileWrapper *) buildFileWrapperWithDocument: (GormDocument *)document;
|
||||
@end
|
||||
|
||||
@interface GormWrapperBuilder : NSObject <GormWrapperBuilder>
|
||||
{
|
||||
GormDocument *document;
|
||||
}
|
||||
@end
|
||||
|
||||
@interface GormWrapperBuilderFactory : NSObject
|
||||
+ (GormWrapperBuilderFactory *) sharedWrapperBuilderFactory;
|
||||
+ (void) registerWrapperBuilderClass: (Class) aClass;
|
||||
- (id<GormWrapperBuilder>) wrapperBuilderForType: (NSString *) type;
|
||||
@end
|
||||
|
||||
#endif
|
165
GormCore/GormWrapperBuilder.m
Normal file
165
GormCore/GormWrapperBuilder.m
Normal file
|
@ -0,0 +1,165 @@
|
|||
/* GormWrapperBuilder
|
||||
*
|
||||
* These classes handle loading different formats into the
|
||||
* document's data structures.
|
||||
*
|
||||
* Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* Author: Gregory John Casamento <greg_casamento@yahoo.com>
|
||||
* Date: 2006
|
||||
*
|
||||
* This file is part of GNUstep.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
|
||||
*/
|
||||
|
||||
#include <AppKit/NSFileWrapper.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSDictionary.h>
|
||||
#include <GormCore/GormWrapperBuilder.h>
|
||||
#include <GormCore/GormDocument.h>
|
||||
#include <GormCore/GormPrivate.h>
|
||||
#include <GormCore/GormSound.h>
|
||||
#include <GormCore/GormImage.h>
|
||||
|
||||
static NSMutableDictionary *_wrapperBuilderMap = nil;
|
||||
static GormWrapperBuilderFactory *_sharedWrapperBuilderFactory = nil;
|
||||
|
||||
@implementation GormWrapperBuilder
|
||||
+ (NSString *) type
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSFileWrapper *) buildFileWrapperWithDocument: (GormDocument *)doc
|
||||
{
|
||||
return [[NSFileWrapper alloc] initDirectoryWithFileWrappers:
|
||||
[self buildFileWrapperDictionaryWithDocument: doc]];
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *) buildFileWrapperDictionaryWithDocument: (GormDocument *)doc
|
||||
{
|
||||
NSMutableDictionary *fileWrappers = [NSMutableDictionary dictionary];
|
||||
NSFileWrapper *scmDirWrapper = nil;
|
||||
|
||||
// Assign document and don't retain...
|
||||
document = doc;
|
||||
|
||||
//
|
||||
// Add the SCM wrapper to the wrapper, if it's present.
|
||||
//
|
||||
scmDirWrapper = [document scmWrapper];
|
||||
if(scmDirWrapper != nil)
|
||||
{
|
||||
NSString *name = [[scmDirWrapper filename] lastPathComponent];
|
||||
[fileWrappers setObject: scmDirWrapper forKey: name];
|
||||
}
|
||||
|
||||
//
|
||||
// Copy resources into the new folder...
|
||||
// Gorm doesn't copy these into the folder right away since the folder may
|
||||
// not yet exist. This allows the user to add/delete resources as they see fit
|
||||
// but only those which they end up with will actually be put into the wrapper
|
||||
// when the model/document is saved.
|
||||
//
|
||||
NSArray *resources = [[document sounds] arrayByAddingObjectsFromArray:
|
||||
[document images]];
|
||||
id object = nil;
|
||||
NSEnumerator *en = [resources objectEnumerator];
|
||||
while ((object = [en nextObject]) != nil)
|
||||
{
|
||||
if([object isSystemResource] == NO)
|
||||
{
|
||||
NSString *path = [object path];
|
||||
NSString *resName = nil;
|
||||
NSData *resData = nil;
|
||||
NSFileWrapper *fileWrapper = nil;
|
||||
|
||||
if([object isInWrapper])
|
||||
{
|
||||
resName = [object filename];
|
||||
resData = [object data];
|
||||
}
|
||||
else
|
||||
{
|
||||
resName = [path lastPathComponent];
|
||||
resData = [NSData dataWithContentsOfFile: path];
|
||||
[object setData: resData];
|
||||
[object setInWrapper: YES];
|
||||
}
|
||||
|
||||
fileWrapper = [[NSFileWrapper alloc] initRegularFileWithContents: resData];
|
||||
[fileWrappers setObject: fileWrapper forKey: resName];
|
||||
RELEASE(fileWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
return fileWrappers;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation GormWrapperBuilderFactory
|
||||
+ (void) initialize
|
||||
{
|
||||
NSArray *classes = GSObjCAllSubclassesOfClass([GormWrapperBuilder class]);
|
||||
NSEnumerator *en = [classes objectEnumerator];
|
||||
Class cls = nil;
|
||||
|
||||
while((cls = [en nextObject]) != nil)
|
||||
{
|
||||
[self registerWrapperBuilderClass: cls];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void) registerWrapperBuilderClass: (Class)aClass
|
||||
{
|
||||
if(_wrapperBuilderMap == nil)
|
||||
{
|
||||
_wrapperBuilderMap = [[NSMutableDictionary alloc] initWithCapacity: 5];
|
||||
}
|
||||
|
||||
[_wrapperBuilderMap setObject: aClass forKey: (NSString *)[aClass type]];
|
||||
}
|
||||
|
||||
+ (GormWrapperBuilderFactory *) sharedWrapperBuilderFactory
|
||||
{
|
||||
if(_sharedWrapperBuilderFactory == nil)
|
||||
{
|
||||
_sharedWrapperBuilderFactory = [[self alloc] init];
|
||||
}
|
||||
return _sharedWrapperBuilderFactory;
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if((self = [super init]) != nil)
|
||||
{
|
||||
if(_sharedWrapperBuilderFactory == nil)
|
||||
{
|
||||
_sharedWrapperBuilderFactory = self;
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id<GormWrapperBuilder>) wrapperBuilderForType: (NSString *) type
|
||||
{
|
||||
Class cls = [_wrapperBuilderMap objectForKey: type];
|
||||
id<GormWrapperBuilder> obj = AUTORELEASE([[cls alloc] init]);
|
||||
return obj;
|
||||
}
|
||||
@end
|
||||
|
51
GormCore/GormWrapperLoader.h
Normal file
51
GormCore/GormWrapperLoader.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/* GormWrapperLoader
|
||||
*
|
||||
* This class is a subclass of the NSDocumentController
|
||||
*
|
||||
* Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* Author: Gregory John Casamento <greg_casamento@yahoo.com>
|
||||
* Date: 2006
|
||||
*
|
||||
* This file is part of GNUstep.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GormWrapperLoader_h
|
||||
#define INCLUDED_GormWrapperLoader_h
|
||||
|
||||
#include <Foundation/NSObject.h>
|
||||
|
||||
@class NSFileWrapper, GormDocument, NSString;
|
||||
|
||||
@protocol GormWrapperLoader
|
||||
- (BOOL) loadFileWrapper: (NSFileWrapper *)wrapper withDocument: (GormDocument *)document;
|
||||
@end
|
||||
|
||||
@interface GormWrapperLoader : NSObject <GormWrapperLoader>
|
||||
{
|
||||
GormDocument *document;
|
||||
}
|
||||
- (void) saveSCMDirectory: (NSDictionary *) fileWrappers;
|
||||
@end
|
||||
|
||||
@interface GormWrapperLoaderFactory : NSObject
|
||||
+ (GormWrapperLoaderFactory *) sharedWrapperLoaderFactory;
|
||||
+ (void) registerWrapperLoaderClass: (Class) aClass;
|
||||
- (id<GormWrapperLoader>) wrapperLoaderForType: (NSString *) type;
|
||||
@end
|
||||
|
||||
#endif
|
157
GormCore/GormWrapperLoader.m
Normal file
157
GormCore/GormWrapperLoader.m
Normal file
|
@ -0,0 +1,157 @@
|
|||
/* GormWrapperLoader
|
||||
*
|
||||
* These classes handle loading different formats into the
|
||||
* document's data structures.
|
||||
*
|
||||
* Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* Author: Gregory John Casamento <greg_casamento@yahoo.com>
|
||||
* Date: 2006
|
||||
*
|
||||
* This file is part of GNUstep.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
|
||||
*/
|
||||
|
||||
#include <AppKit/NSFileWrapper.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <GormCore/GormWrapperLoader.h>
|
||||
#include <GormCore/GormDocument.h>
|
||||
#include <GormCore/GormPrivate.h>
|
||||
#include <GormCore/GormSound.h>
|
||||
#include <GormCore/GormImage.h>
|
||||
|
||||
static NSMutableDictionary *_wrapperLoaderMap = nil;
|
||||
static GormWrapperLoaderFactory *_sharedWrapperLoaderFactory = nil;
|
||||
|
||||
@implementation GormWrapperLoader
|
||||
+ (NSString *) type
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void) saveSCMDirectory: (NSDictionary *) fileWrappers
|
||||
{
|
||||
[document setSCMWrapper: [fileWrappers objectForKey: @".svn"]];
|
||||
if([document scmWrapper] == nil)
|
||||
{
|
||||
[document setSCMWrapper: [fileWrappers objectForKey: @"CVS"]];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) loadFileWrapper: (NSFileWrapper *)wrapper withDocument: (GormDocument *)doc
|
||||
{
|
||||
if ([wrapper isDirectory])
|
||||
{
|
||||
NSDictionary *fileWrappers = nil;
|
||||
NSString *key = nil;
|
||||
NSArray *imageFileTypes = [NSImage imageFileTypes];
|
||||
NSArray *soundFileTypes = [NSSound soundUnfilteredFileTypes];
|
||||
NSMutableArray *images = [NSMutableArray array];
|
||||
NSMutableArray *sounds = [NSMutableArray array];
|
||||
NSData *fileData = nil;
|
||||
|
||||
document = doc; // don't retain...
|
||||
key = nil;
|
||||
fileWrappers = [wrapper fileWrappers];
|
||||
|
||||
[self saveSCMDirectory: fileWrappers];
|
||||
|
||||
NSEnumerator *enumerator = [fileWrappers keyEnumerator];
|
||||
while((key = [enumerator nextObject]) != nil)
|
||||
{
|
||||
NSFileWrapper *fw = [fileWrappers objectForKey: key];
|
||||
if([fw isRegularFile])
|
||||
{
|
||||
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]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[document setSounds: sounds];
|
||||
[document setImages: images];
|
||||
}
|
||||
else
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation GormWrapperLoaderFactory
|
||||
+ (void) initialize
|
||||
{
|
||||
NSArray *classes = GSObjCAllSubclassesOfClass([GormWrapperLoader class]);
|
||||
NSEnumerator *en = [classes objectEnumerator];
|
||||
Class cls = nil;
|
||||
|
||||
while((cls = [en nextObject]) != nil)
|
||||
{
|
||||
[self registerWrapperLoaderClass: cls];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void) registerWrapperLoaderClass: (Class)aClass
|
||||
{
|
||||
if(_wrapperLoaderMap == nil)
|
||||
{
|
||||
_wrapperLoaderMap = [[NSMutableDictionary alloc] initWithCapacity: 5];
|
||||
}
|
||||
|
||||
[_wrapperLoaderMap setObject: aClass forKey: (NSString *)[aClass type]];
|
||||
}
|
||||
|
||||
+ (GormWrapperLoaderFactory *) sharedWrapperLoaderFactory
|
||||
{
|
||||
if(_sharedWrapperLoaderFactory == nil)
|
||||
{
|
||||
_sharedWrapperLoaderFactory = [[self alloc] init];
|
||||
}
|
||||
return _sharedWrapperLoaderFactory;
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if((self = [super init]) != nil)
|
||||
{
|
||||
if(_sharedWrapperLoaderFactory == nil)
|
||||
{
|
||||
_sharedWrapperLoaderFactory = self;
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id<GormWrapperLoader>) wrapperLoaderForType: (NSString *) type
|
||||
{
|
||||
Class cls = [_wrapperLoaderMap objectForKey: type];
|
||||
id<GormWrapperLoader> obj = AUTORELEASE([[cls alloc] init]);
|
||||
return obj;
|
||||
}
|
||||
@end
|
||||
|
Loading…
Reference in a new issue