Nib changes.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/apps/gorm/trunk@23052 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Gregory John Casamento 2006-06-14 05:47:54 +00:00
parent cd5032d192
commit 09fbac4ce3
12 changed files with 480 additions and 41 deletions

View file

@ -1,3 +1,23 @@
2006-06-14 01:42 Gregory John Casamento <greg_casamento@yahoo.com>
* GormCore/GNUmakefile: Addition of GormNibWrapperLoader to the
makefile.
* GormCore/GormClassManager.[hm]: Correction for nib classes loading.
* GormCore/GormDocument.h: Added include for GSNibContainer
* GormCore/GormDocument.m: In NSNibConnector category which
implements "isEqual" check if it's the same "kind of class". If
not return NO.
* GormCore/GormGormWrapperBuilder.m: Corrections for connection
persistence issues.
* GormCore/GormGormWrapperLoader.m: Corrections for connection
persistence issues.
* GormCore/GormNibWrapperLoader.m: Initial cut at class to build the
nib wrapper.
* GormCore/GormPrivate.[hm]: Added encoding changes to
GormObjectProxy and GormCustomView to allow them to handle
NSCustomObject and NSCustomView respectively
* Gorm.m: In testing, don't substitute the browser either.
2006-06-10 21:04 Gregory John Casamento <greg_casamento@yahoo.com>
* GormCore/GormGormWrapperLoader.m: removed uneeded sound/image

3
Gorm.m
View file

@ -440,7 +440,8 @@
NSString *realClassName = [substituteClasses objectForKey: subClassName];
if([realClassName isEqualToString: @"NSTableView"] ||
[realClassName isEqualToString: @"NSOutlineView"])
[realClassName isEqualToString: @"NSOutlineView"] ||
[realClassName isEqualToString: @"NSBrowser"])
{
continue;
}

View file

@ -117,6 +117,7 @@ GormCore_OBJC_FILES = \
GormInspectorsManager.m \
GormInternalViewEditor.m \
GormMatrixEditor.m \
GormNibWrapperLoader.m \
GormNSSplitViewInspector.m \
GormObjectEditor.m \
GormObjectInspector.m \

View file

@ -107,8 +107,8 @@
- (NSString *) customClassForObject: (id)object;
- (NSString *) customClassForName: (NSString *)name;
- (void) setCustomClass: (NSString *)className
forName: (NSString *)object;
- (void) removeCustomClassForName: (NSString *) object;
forName: (NSString *)name;
- (void) removeCustomClassForName: (NSString *)name;
- (NSMutableDictionary *) customClassMap;
- (void) setCustomClassMap: (NSMutableDictionary *)dict;
- (BOOL) isCustomClassMapEmpty;

View file

@ -1517,7 +1517,7 @@
{
NSString *dictString = AUTORELEASE([[NSString alloc] initWithData: data encoding: NSASCIIStringEncoding]);
NSDictionary *dict = [dictString propertyList];
return [self loadCustomClassesWithDict: dict];
return [self loadNibFormatCustomClassesWithDict: dict];
}
// this method will load the custom classes and merge them with the
@ -1972,14 +1972,14 @@
}
- (void) setCustomClass: (NSString *)className
forName: (NSString *)object
forName: (NSString *)name
{
[customClassMap setObject: className forKey: object];
[customClassMap setObject: className forKey: name];
}
- (void) removeCustomClassForName: (NSString *)object
- (void) removeCustomClassForName: (NSString *)name
{
[customClassMap removeObjectForKey: object];
[customClassMap removeObjectForKey: name];
}
- (NSMutableDictionary *) customClassMap

View file

@ -28,7 +28,7 @@
#include <AppKit/AppKit.h>
#include <Foundation/Foundation.h>
#include <GNUstepGUI/GSNibTemplates.h>
#include <GNUstepGUI/GSNibContainer.h>
#include <InterfaceBuilder/InterfaceBuilder.h>
@class GormClassManager, GormClassEditor, GormObjectProxy, GormFilesOwner, GormFilePrefsManager;

View file

@ -72,14 +72,19 @@
{
BOOL result = NO;
if([object isKindOfClass: [NSNibConnector class]] == NO)
{
return NO;
}
if(self == object)
{
result = YES;
}
else if([[self source] isEqual: [object source]] &&
[[self destination] isEqual: [object destination]] &&
[[self label] isEqual: [object label]] &&
([self class] == [object class]))
[[self destination] isEqual: [object destination]] &&
[[self label] isEqual: [object label]] &&
([self class] == [object class]))
{
result = YES;
}
@ -715,7 +720,7 @@ static NSImage *fileImage = nil;
[[self openEditorForObject: menu] activate];
// If it's the main menu... locate it appropriately...
if(isMainMenu)
if(isMainMenu && [self isActive])
{
NSRect frame = [[self window] frame];
NSPoint origin = frame.origin;
@ -1155,7 +1160,7 @@ static NSImage *fileImage = nil;
// Get rid of the selection box.
[selectionBox removeFromSuperviewWithoutNeedingDisplay];
RELEASE(classManager);
RELEASE(filePrefsManager);
RELEASE(filePrefsView);
@ -1172,8 +1177,10 @@ static NSImage *fileImage = nil;
RELEASE(classesView);
RELEASE(soundsScrollView);
RELEASE(imagesScrollView);
RELEASE(filePrefsWindow);
RELEASE(filePrefsWindow); // FIXME: Causes NIB to crash...
RELEASE(resourceManagers);
RELEASE(nameTable);
RELEASE(connections);
RELEASE(topLevelObjects);
@ -1181,7 +1188,6 @@ static NSImage *fileImage = nil;
RELEASE(deferredWindows);
TEST_RELEASE(scmWrapper);
[super dealloc];
}
@ -1620,6 +1626,10 @@ static NSImage *fileImage = nil;
}
}
/**
* Start the process of archiving.
*/
/**
* Start the process of archiving.
*/
@ -1627,6 +1637,7 @@ static NSImage *fileImage = nil;
{
NSEnumerator *enumerator;
id<IBConnectors> con;
id obj;
/*
* Map all connector sources and destinations to their name strings.
@ -1645,6 +1656,16 @@ static NSImage *fileImage = nil;
{
[savedEditors addObject: con];
}
else
{
NSString *name;
obj = [con source];
name = [self nameForObject: obj];
[con setSource: name];
obj = [con destination];
name = [self nameForObject: obj];
[con setDestination: name];
}
}
[connections removeObjectsInArray: savedEditors];
@ -1674,6 +1695,7 @@ static NSImage *fileImage = nil;
{
NSEnumerator *enumerator;
id<IBConnectors> con;
id obj;
/*
* Restore class versions.
@ -1689,6 +1711,21 @@ static NSImage *fileImage = nil;
[nameTable setObject: firstResponder forKey: @"NSFirst"];
NSMapInsert(objToName, (void*)firstResponder, (void*)@"NSFirst");
/*
* Map all connector source and destination names to their objects.
*/
enumerator = [connections objectEnumerator];
while ((con = [enumerator nextObject]) != nil)
{
NSString *name;
name = (NSString*)[con source];
obj = [self objectForName: name];
[con setSource: obj];
name = (NSString*)[con destination];
obj = [self objectForName: name];
[con setDestination: obj];
}
/*
* Restore editor links and reactivate the editors.
*/
@ -3394,9 +3431,9 @@ static NSImage *fileImage = nil;
postNotificationName: IBWillSaveDocumentNotification
object: self];
[self beginArchiving];
// [self beginArchiving];
result = [builder buildFileWrapperWithDocument: self];
[self endArchiving];
// [self endArchiving];
if(result)
{

View file

@ -47,12 +47,17 @@
{
NSMutableArray *visible = [nameTable objectForKey: @"NSVisible"];
NSMutableArray *deferred = [nameTable objectForKey: @"NSDeferred"];
NSDictionary *customClasses = [[document classManager] customClassMap];
// Create the container for the .gorm file...
[nameTable addEntriesFromDictionary: [document nameTable]];
[topLevelObjects addObjectsFromArray: [[document topLevelObjects] allObjects]];
[topLevelObjects addObjectsFromArray: [[document topLevelObjects] allObjects]];
[connections addObjectsFromArray: [document connections]];
[visible addObjectsFromArray: [[document visibleWindows] allObjects]];
[deferred addObjectsFromArray: [[document deferredWindows] allObjects]];
// add the custom class mapping...
[nameTable setObject: customClasses forKey: @"GSCustomClassMap"];
}
return self;
}
@ -60,32 +65,36 @@
- (void) prepareConnectionsWithDocument: (GormDocument *)document
{
NSEnumerator *enumerator = [connections objectEnumerator];
id o = nil;
while ((o = [enumerator nextObject]) != nil)
id conn = nil;
while ((conn = [enumerator nextObject]) != nil)
{
NSString *name = nil;
id obj = nil;
obj = [o source];
obj = [conn source];
name = [document nameForObject: obj];
[o setSource: name];
obj = [o destination];
[conn setSource: name];
obj = [conn destination];
name = [document nameForObject: obj];
[o setDestination: name];
[conn setDestination: name];
}
}
- (void) resetConnectionsWithDocument: (GormDocument *)document
{
NSEnumerator *enumerator = [connections objectEnumerator];
id o = nil;
while ((o = [enumerator nextObject]) != nil)
id conn = nil;
while ((conn = [enumerator nextObject]) != nil)
{
id src = [document objectForName: [o source]];
id dst = [document objectForName: [o destination]];
[o setSource: src];
[o setDestination: dst];
[o establishConnection];
NSString *name = nil;
id obj = nil;
name = (NSString*)[conn source];
obj = [document objectForName: name];
[conn setSource: obj];
name = (NSString*)[conn destination];
obj = [document objectForName: name];
[conn setDestination: obj];
}
}
@end
@ -176,7 +185,10 @@
{
GormClassManager *classManager = [document classManager];
GormFilePrefsManager *filePrefsManager = [document filePrefsManager];
GSNibContainer *container = [[GSNibContainer alloc] initWithDocument: document];
GSNibContainer *container = nil;
[document beginArchiving];
container = [[GSNibContainer alloc] initWithDocument: document];
/*
* Set up archiving...
@ -204,9 +216,9 @@
* Initialize templates
*/
[self _replaceObjectsWithTemplates: archiver];
[container prepareConnectionsWithDocument: document];
// [container prepareConnectionsWithDocument: document];
[archiver encodeRootObject: container];
[container resetConnectionsWithDocument: document];
// [container resetConnectionsWithDocument: document];
RELEASE(archiver); // We're done with the archiver here..
/*
@ -224,6 +236,7 @@
// release the container...
RELEASE(container);
[document endArchiving];
}
return fileWrappers;

View file

@ -276,14 +276,18 @@
* to hold the objects rather than their names (using our own dummy
* object as the 'NSOwner'.
*/
GormFilesOwner *filesOwner = [document filesOwner];
GormFirstResponder *firstResponder = [document firstResponder];
ownerClass = [nt objectForKey: @"NSOwner"];
if (ownerClass)
{
[[document filesOwner] setClassName: ownerClass];
[filesOwner setClassName: ownerClass];
}
[[container nameTable] removeObjectForKey: @"NSOwner"];
[[container nameTable] removeObjectForKey: @"NSFirst"];
[nt setObject: filesOwner forKey: @"NSOwner"];
[nt setObject: firstResponder forKey: @"NSFirst"];
//
// Add entries...
//
@ -295,10 +299,15 @@
NSArray *objs = [[container topLevelObjects] allObjects];
[[document topLevelObjects] addObjectsFromArray: objs];
//
// Add connections
//
NSMutableArray *connections = [document connections];
[connections addObjectsFromArray: [container connections]];
/* Iterate over the contents of nameTable and create the connections */
nt = [document nameTable];
enumerator = [[container connections] objectEnumerator];
enumerator = [connections objectEnumerator];
while ((con = [enumerator nextObject]) != nil)
{
NSString *name;

View file

@ -0,0 +1,349 @@
/* GormNibWrapperLoader
*
* 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>
#include <GormCore/GormCustomView.h>
#include <GNUstepGUI/GSNibCompatibility.h>
@interface NSWindowTemplate (Private)
- (void) setBaseWindowClass: (Class) clz;
@end
@implementation NSWindowTemplate (Private)
- (void) setBaseWindowClass: (Class) clz
{
_baseWindowClass = clz;
}
@end
@interface GormNibWrapperLoader : GormWrapperLoader
{
NSIBObjectData *container;
NSMutableDictionary *swappedObjects;
}
@end
@implementation GormNibWrapperLoader
- (id) init
{
if((self = [super init]) != nil)
{
swappedObjects = [[NSMutableDictionary alloc] init];
}
return self;
}
- (void) dealloc
{
// RELEASE(swappedObjects);
[super dealloc];
}
+ (NSString *) type
{
return @"GSNibFileType";
}
- (BOOL) _isTopLevelObject: (id)obj
{
if([obj isKindOfClass: [NSWindow class]] ||
[obj isKindOfClass: [GormObjectProxy class]])
{
return YES;
}
else if([obj isKindOfClass: [NSMenu class]])
{
if([obj supermenu] == nil)
{
return YES;
}
}
return NO;
}
- (BOOL) loadFileWrapper: (NSFileWrapper *)wrapper withDocument: (GormDocument *) doc
{
NS_DURING
{
NSData *data = nil;
NSData *classes = nil;
NSKeyedUnarchiver *u = nil;
NSEnumerator *enumerator = nil;
NSString *key = nil;
GormPalettesManager *palettesManager = [(id<Gorm>)NSApp palettesManager];
NSDictionary *substituteClasses = [palettesManager substituteClasses];
NSEnumerator *en = [substituteClasses keyEnumerator];
NSString *subClassName = nil;
NSDictionary *fileWrappers = nil;
if ([super loadFileWrapper: wrapper withDocument: doc])
{
GormClassManager *classManager = [document classManager];
key = nil;
fileWrappers = [wrapper fileWrappers];
// turn off custom classes...
[NSClassSwapper setIsInInterfaceBuilder: YES];
enumerator = [fileWrappers keyEnumerator];
while((key = [enumerator nextObject]) != nil)
{
NSFileWrapper *fw = [fileWrappers objectForKey: key];
if([fw isRegularFile])
{
NSData *fileData = [fw regularFileContents];
if([key isEqual: @"keyedobjects.nib"])
{
data = fileData;
}
else if([key isEqual: @"classes.nib"])
{
classes = fileData;
// load the custom classes...
if (![classManager loadNibFormatCustomClassesWithData: 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...
if (data == 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 = [[NSKeyedUnarchiver alloc] initForReadingWithData: data];
[u setDelegate: self];
/*
* Special internal classes
*/
[u setClass: [GormObjectProxy class]
forClassName: @"NSCustomObject"];
[u setClass: [GormCustomView class]
forClassName: @"NSCustomView"];
/*
* Substitute any classes specified by the palettes...
*/
while((subClassName = [en nextObject]) != nil)
{
NSString *realClassName = [substituteClasses objectForKey: subClassName];
Class substituteClass = NSClassFromString(subClassName);
[u setClass: substituteClass
forClassName: realClassName];
}
//
// decode
//
container = [u decodeObjectForKey: @"IB.objectdata"];
if (container == nil || [container isKindOfClass: [NSIBObjectData class]] == NO)
{
return NO;
}
id nibFilesOwner = [container objectForName: @"File's Owner"];
id docFilesOwner = [document filesOwner];
NSMapTable objects = [container objects];
NSArray *objs = NSAllMapTableKeys(objects);
NSEnumerator *en = [objs objectEnumerator];
id o = nil;
//
// set the current class on the File's owner...
//
if([nibFilesOwner isKindOfClass: [GormObjectProxy class]])
{
[docFilesOwner setClassName: [nibFilesOwner className]];
}
//
// Add the main menu first...
//
id menu = [container objectForName: @"MainMenu"];
if(menu)
{
[document attachObject: menu toParent: nil];
}
//
// add objects...
//
while((o = [en nextObject]) != nil)
{
id obj = o;
NSString *customClassName = nil;
NSString *objName = nil;
// skip the file's owner, it is handled above...
if(o == nibFilesOwner)
continue;
//
// if it's a window template, then replace it with an actual window.
//
if([o isKindOfClass: [NSWindowTemplate class]])
{
NSString *className = [o className];
BOOL isDeferred = [o isDeferred];
BOOL isVisible = [[container visibleWindows] containsObject: o];
// make the object deferred/visible...
obj = [o nibInstantiate];
[document setObject: obj isDeferred: isDeferred];
[document setObject: obj isVisibleAtLaunch: isVisible];
// record the custom class...
if([classManager isCustomClass: className])
{
customClassName = className;
}
}
if([self _isTopLevelObject: obj])
{
[document attachObject: obj toParent: nil];
}
if(customClassName != nil)
{
objName = [document nameForObject: obj];
[classManager setCustomClass: customClassName forName: objName];
}
}
//
// add the swapped objects...
//
en = [swappedObjects keyEnumerator];
NSString *key = nil;
while((key = [en nextObject]) != nil)
{
NSArray *array = [swappedObjects objectForKey: key];
NSEnumerator *oen = [array objectEnumerator];
id actualObj = nil;
while((actualObj = [oen nextObject]) != nil)
{
NSString *name = [document nameForObject: actualObj];
[classManager setCustomClass: key forName: name];
}
}
//
// add connections...
//
en = [[container connections] objectEnumerator];
o = nil;
while((o = [en nextObject]) != nil)
{
[document addConnector: o];
}
// turn on custom classes.
[NSClassSwapper setIsInInterfaceBuilder: NO];
return YES;
}
}
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;
}
- (void) unarchiver: (NSKeyedUnarchiver *)unarchiver willReplaceObject: (id)obj withObject: (id)newObj
{
if([obj isKindOfClass: [NSClassSwapper class]])
{
NSString *className = [obj className];
NSMutableArray *objects = [swappedObjects objectForKey: className];
if(objects == nil)
{
objects = [NSMutableArray array];
[swappedObjects setObject: objects forKey: className];
}
[objects addObject: newObj];
}
}
- (id) unarchiver: (NSKeyedUnarchiver *)unarchiver didDecodeObject: (id)obj
{
if([obj isKindOfClass: [NSWindowTemplate class]])
{
GormClassManager *classManager = [document classManager];
NSString *className = [obj className];
if([classManager isCustomClass: className])
{
className = [classManager nonCustomSuperClassOf: className];
}
Class clz = [unarchiver classForClassName: className];
[obj setBaseWindowClass: clz];
}
else if([obj isKindOfClass: [NSNibOutletConnector class]] ||
[obj isKindOfClass: [NSNibControlConnector class]])
{
if([obj source] == nil)
{
[obj setSource: [document firstResponder]];
}
if([obj destination] == nil)
{
[obj setDestination: [document firstResponder]];
}
}
return obj;
}
@end

View file

@ -36,6 +36,8 @@
#include <GormCore/GormPalettesManager.h>
#include <GormCore/GormProtocol.h>
#include <GormCore/GormClassEditor.h>
#include <GNUstepGUI/GSNibTemplates.h>
#include <GNUstepGUI/GSNibCompatibility.h>
extern NSString *GormLinkPboardType;
extern NSString *GormToggleGuidelineNotification;
@ -61,6 +63,11 @@ extern NSString *GormResizeCellNotification;
- (BOOL) isInInterfaceBuilder;
@end
@interface NSClassSwapper (GormCustomClassAdditions)
+ (void) setIsInInterfaceBuilder: (BOOL)flag;
- (BOOL) isInInterfaceBuilder;
@end
@interface GormObjectProxy : GSNibItem
/*
* Use a GormObjectProxy in Gorm, but encode a GSNibItem in the archive.

View file

@ -119,7 +119,9 @@ static BOOL _isInInterfaceBuilder = NO;
{
if([aCoder allowsKeyedCoding])
{
ASSIGN(theClass, [aCoder decodeObjectForKey: @"NSClassName"]);
theFrame = NSZeroRect;
return self;
}
else
{