Some preliminary work on loading gmodels (not working yet).

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/apps/gorm/trunk@14987 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Adam Fedor 2002-11-13 16:10:22 +00:00
parent 95f4f0bb78
commit d3a55312fb
6 changed files with 367 additions and 139 deletions

View file

@ -1,3 +1,11 @@
2002-11-13 Adam Fedor <fedor@gnu.org>
* Some preliminary work on loading gmodels (not working yet).
* GormDocument.m ([GormDocument -rebuildObjToNameMapping]): New.
(loadDocument:): Use it.
* GModelDecoder.m: New file for translating gmodel files.
(openGModel:): Moved from GormDocument.
2002-11-12 Adam Fedor <fedor@gnu.org>
* ClassInformation.plist (NSDocument): Add _window outlet.

309
GModelDecoder.m Normal file
View file

@ -0,0 +1,309 @@
/* GModelDecoder
*
* Copyright (C) 2002 Free Software Foundation, Inc.
*
* Author: Adam Fedor <fedor@gnu.org>
* Date: 2002
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <AppKit/GMArchiver.h>
#include <AppKit/IMLoading.h>
#include <AppKit/IMCustomObject.h>
#include <AppKit/NSWindow.h>
#include <AppKit/GSDisplayServer.h>
#include "GormPrivate.h"
#include "GormCustomView.h"
static Class gmodel_class(NSString *className);
static id gormNibOwner;
static id gormRealObject;
static BOOL gormFileOwnerDecoded;
@interface GModelApplication : NSObject
{
id mainMenu;
id windowMenu;
id delegate;
NSArray *windows;
}
+ (id)createObjectForModelUnarchiver:(GMUnarchiver*)unarchiver;
- (id)initWithModelUnarchiver:(GMUnarchiver*)unarchiver;
- mainMenu;
- windowMenu;
- delegate;
- (NSArray *) windows;
@end
@interface NSWindow (GormPrivate)
- (void) gmSetStyleMask: (unsigned int)mask;
@end
@implementation NSWindow (GormPrivate)
// private method to change the Window style mask on the fly
- (void) gmSetStyleMask: (unsigned int)mask
{
_styleMask = mask;
[GSServerForWindow(self) stylewindow: mask : [self windowNumber]];
}
@end
@implementation GModelApplication
- (id)initWithModelUnarchiver:(GMUnarchiver*)unarchiver
{
NSEnumerator *enumerator;
NSWindow *win;
mainMenu = [unarchiver decodeObjectWithName:@"mainMenu"];
windows = [unarchiver decodeObjectWithName:@"windows"];
enumerator = [windows objectEnumerator];
while ((win = [enumerator nextObject]) != nil)
{
/* If we did not retain the windows here, they would all get
released at the end of the event loop. */
//RETAIN (win);
/* Fix up window frames */
NSLog(@"Updating window class %@", win);
if ([win styleMask] == NSBorderlessWindowMask)
{
[win gmSetStyleMask: NSTitledWindowMask];
}
}
delegate = [unarchiver decodeObjectWithName:@"delegate"];
return self;
}
- (NSArray *) windows
{
return windows;
}
- mainMenu
{
return mainMenu;
}
- windowMenu
{
return windowMenu;
}
- delegate
{
return delegate;
}
+ (id)createObjectForModelUnarchiver:(GMUnarchiver*)unarchiver
{
return AUTORELEASE([[GModelApplication alloc] init]);
}
@end
@implementation GormObjectProxy (GModel)
+ (id)createObjectForModelUnarchiver:(GMUnarchiver*)unarchiver
{
return AUTORELEASE([[self alloc] init]);
}
- (id)initWithModelUnarchiver: (GMUnarchiver*)unarchiver
{
id extension;
id realObject;
id label;
theClass = [unarchiver decodeStringWithName: @"className"];
extension = [unarchiver decodeObjectWithName: @"extension"];
realObject = [unarchiver decodeObjectWithName: @"realObject"];
//real = [unarchiver representationForName: @"realObject" isLabeled: &label];
if (!gormFileOwnerDecoded)
{
gormFileOwnerDecoded = YES;
gormNibOwner = self;
gormRealObject = realObject;
}
return self;
}
@end
@implementation GormCustomView (GModel)
+ (id)createObjectForModelUnarchiver:(GMUnarchiver*)unarchiver
{
return AUTORELEASE([[self alloc] initWithFrame: NSMakeRect(0,0,10,10)]);
}
- (id)initWithModelUnarchiver:(GMUnarchiver*)unarchiver
{
NSString *className;
id realObject;
id extension;
className = [unarchiver decodeStringWithName: @"className"];
extension = [unarchiver decodeObjectWithName: @"extension"];
realObject = [unarchiver decodeObjectWithName: @"realObject"];
[self setFrame: [unarchiver decodeRectWithName: @"frame"]];
if (!gormFileOwnerDecoded)
{
gormFileOwnerDecoded = YES;
gormNibOwner = self;
gormRealObject = realObject;
}
return self;
}
@end
@implementation GormDocument (GModel)
/* importing of legacy gmodel files.*/
- (id) openGModel: (NSString *)path
{
id obj, con;
id unarchiver;
id decoded;
NSEnumerator *enumerator;
NSArray *gmobjects;
NSArray *gmconnections;
Class u = gmodel_class(@"GMUnarchiver");
NSLog (@"Loading gmodel file %@...", path);
/* GModel classes */
[u decodeClassName: @"NSApplication" asClassName: @"GModelApplication"];
[u decodeClassName: @"IMCustomView" asClassName: @"GormCustomView"];
[u decodeClassName: @"IMCustomObject" asClassName: @"GormObjectProxy"];
/* Gorm classes */
[u decodeClassName: @"NSMenu" asClassName: @"GormNSMenu"];
[u decodeClassName: @"NSWindow" asClassName: @"GormNSWindow"];
[u decodeClassName: @"NSBrowser" asClassName: @"GormNSBrowser"];
[u decodeClassName: @"NSTableView" asClassName: @"GormNSTableView"];
[u decodeClassName: @"NSOutlineView" asClassName: @"GormNSOutlineView"];
[u decodeClassName: @"NSPopUpButton" asClassName: @"GormNSPopUpButton"];
[u decodeClassName: @"NSPopUpButtonCell"
asClassName: @"GormNSPopUpButtonCell"];
unarchiver = [u unarchiverWithContentsOfFile: path];
if (!unarchiver)
{
NSLog(@"Failed to load gmodel file %@!!",path);
return nil;
}
NSLog(@"----------------- GModel testing -----------------");
decoded = [unarchiver decodeObjectWithName:@"RootObject"];
gmobjects = [decoded performSelector: @selector(objects)];
gmconnections = [decoded performSelector: @selector(connections)];
NSLog(@"Gmodel objects = %@", gmobjects);
NSLog(@" Nib Owner %@ class name is %@",
gormNibOwner, [gormNibOwner className]);
/* FIXME: Need to addClass:... if it isn't known */yy
if (gormNibOwner)
[filesOwner setClassName: [gormNibOwner className]];
enumerator = [gmconnections objectEnumerator];
while ((con = [enumerator nextObject]) != nil)
{
NSNibConnector *newcon;
newcon = AUTORELEASE([[NSNibConnector alloc] init]);
[newcon setSource: [con source]];
[newcon setDestination: [con destination]];
[newcon setLabel: [con label]];
[connections addObject: newcon];
}
/*
* Now we merge the objects from the gmodel into our own data
* structures.
*/
enumerator = [gmobjects objectEnumerator];
while ((obj = [enumerator nextObject]))
{
if (obj != gormNibOwner)
[self setName: nil forObject: obj];
}
if ([gormRealObject isKindOfClass: [GModelApplication class]])
{
enumerator = [[gormRealObject windows] objectEnumerator];
while ((obj = [enumerator nextObject]))
{
[self setName: nil forObject: obj];
}
if ([gormRealObject mainMenu])
[self setName: nil forObject: [gormRealObject mainMenu]];
}
else
{
/* Here we need to addClass:... (outlets, actions). */
NSLog(@"Don't understand real object %@", gormRealObject);
}
[self rebuildObjToNameMapping];
return self;
}
@end
static
Class gmodel_class(NSString *className)
{
static Class gmclass = Nil;
if (gmclass == Nil)
{
NSBundle *theBundle;
NSEnumerator *benum;
NSString *path;
/* Find the bundle */
benum = [NSStandardLibraryPaths() objectEnumerator];
while ((path = [benum nextObject]))
{
path = [path stringByAppendingPathComponent: @"Bundles"];
path = [path stringByAppendingPathComponent: @"libgmodel.bundle"];
if ([[NSFileManager defaultManager] fileExistsAtPath: path])
break;
path = nil;
}
NSCAssert(path != nil, @"Unable to load gmodel bundle");
NSDebugLog(@"Loading gmodel from %@", path);
theBundle = [NSBundle bundleWithPath: path];
NSCAssert(theBundle != nil, @"Can't init gmodel bundle");
gmclass = [theBundle classNamed: className];
NSCAssert(gmclass, @"Can't load gmodel bundle");
}
return gmclass;
}

View file

@ -140,6 +140,7 @@ Gorm_OBJC_FILES = \
GormDocument.m \
IBInspector.m \
IBPalette.m \
GModelDecoder.m \
GormCustomView.m \
GormViewKnobs.m \
GormFilesOwner.m \

View file

@ -107,8 +107,8 @@
// sound support
- (id) openSound: (id)sender;
// import gmodel
- (id) openGModel: (id)sender;
// Internals support
- (void) rebuildObjToNameMapping;
@end
#endif

View file

@ -28,39 +28,15 @@
#include "GormOutlineView.h"
#include <AppKit/NSSound.h>
// gmodel compatibility headers...
#include <AppKit/GMArchiver.h>
#include <AppKit/IMLoading.h>
#include <AppKit/IMCustomObject.h>
// forward declaration...
static Class gmodel_class(NSString *className);
NSString *IBDidOpenDocumentNotification = @"IBDidOpenDocumentNotification";
NSString *IBWillSaveDocumentNotification = @"IBWillSaveDocumentNotification";
NSString *IBDidSaveDocumentNotification = @"IBDidSaveDocumentNotification";
NSString *IBWillCloseDocumentNotification = @"IBWillCloseDocumentNotification";
// category to allow extraction of information from a gmodel file..
/*
@interface GMModel (GormAdditions)
- (NSArray *) objects;
- (NSArray *) connections;
@interface GormDocument (GModel)
- (id) openGModel: (NSString *)path;
@end
@implementation GMModel (GormAdditions)
- (NSArray *) objects
{
return objects;
}
- (NSArray *) connections
{
return connections;
}
@end
*/
@implementation GormFirstResponder
- (NSImage*) imageForViewer
{
@ -1638,7 +1614,6 @@ static NSImage *classesImage = nil;
GSNibContainer *c;
NSEnumerator *enumerator;
id <IBConnectors> con;
NSString *name;
NSString *ownerClass;
NSFileManager *mgr = [NSFileManager defaultManager];
BOOL isDir = NO;
@ -1769,43 +1744,8 @@ static NSImage *classesImage = nil;
[connections addObjectsFromArray: [c connections]];
[nameTable addEntriesFromDictionary: nt];
/*
* Now we build our reverse mapping information and other initialisation
*/
NSResetMapTable(objToName);
NSMapInsert(objToName, (void*)filesOwner, (void*)@"NSOwner");
NSMapInsert(objToName, (void*)firstResponder, (void*)@"NSFirst");
enumerator = [nameTable keyEnumerator];
while ((name = [enumerator nextObject]) != nil)
{
id obj = [nameTable objectForKey: name];
[self rebuildObjToNameMapping];
NSMapInsert(objToName, (void*)obj, (void*)name);
if ([obj isKindOfClass: [NSMenu class]] == YES)
{
if ([name isEqual: @"NSMenu"] == YES)
{
NSRect frame = [[NSScreen mainScreen] frame];
[[obj window] setFrameTopLeftPoint:
NSMakePoint(1, frame.size.height-200)];
[[self openEditorForObject: obj] activate];
[objectsView addObject: obj];
}
}
else if ([obj isKindOfClass: [NSWindow class]] == YES)
{
[objectsView addObject: obj];
[[self openEditorForObject: obj] activate];
}
else if ([obj isKindOfClass: [GSNibItem class]] == YES
&& [obj isKindOfClass: [GormCustomView class]] == NO)
{
[objectsView addObject: obj];
//[[self openEditorForObject: obj] activate];
}
}
/*
* set our new file name
*/
@ -1844,6 +1784,49 @@ static NSImage *classesImage = nil;
return self;
}
/*
* Build our reverse mapping information and other initialisation
*/
- (void) rebuildObjToNameMapping
{
NSEnumerator *enumerator;
NSString *name;
NSResetMapTable(objToName);
NSMapInsert(objToName, (void*)filesOwner, (void*)@"NSOwner");
NSMapInsert(objToName, (void*)firstResponder, (void*)@"NSFirst");
enumerator = [nameTable keyEnumerator];
while ((name = [enumerator nextObject]) != nil)
{
id obj = [nameTable objectForKey: name];
NSMapInsert(objToName, (void*)obj, (void*)name);
if ([obj isKindOfClass: [NSMenu class]] == YES)
{
if ([name isEqual: @"NSMenu"] == YES)
{
NSRect frame = [[NSScreen mainScreen] frame];
[[obj window] setFrameTopLeftPoint:
NSMakePoint(1, frame.size.height-200)];
[[self openEditorForObject: obj] activate];
[objectsView addObject: obj];
}
}
else if ([obj isKindOfClass: [NSWindow class]] == YES)
{
[objectsView addObject: obj];
[[self openEditorForObject: obj] activate];
}
else if ([obj isKindOfClass: [GSNibItem class]] == YES
&& [obj isKindOfClass: [GormCustomView class]] == NO)
{
[objectsView addObject: obj];
//[[self openEditorForObject: obj] activate];
}
}
}
/*
* NB. This assumes we have an empty document to start with - the loaded
* document is merged in to it.
@ -2954,63 +2937,4 @@ shouldEditTableColumn: (NSTableColumn *)tableColumn
return nil;
}
// importing of legacy gmodel files.
- (id) openGModel: (NSString *)path
{
id unarchiver = nil;
id decoded = nil;
Class unarchiverClass = gmodel_class(@"GMUnarchiver");
NSLog (@"loading gmodel file %@...", path);
unarchiver = [unarchiverClass unarchiverWithContentsOfFile: path];
[unarchiver decodeClassName: @"IMCustomView" asClassName: @"GormCustomView"];
[unarchiver decodeClassName: @"IMCustomObject" asClassName: @"GormProxyObject"];
if (!unarchiver)
{
NSLog(@"Failed to load gmodel file %@!!",path);
return nil;
}
decoded = [unarchiver decodeObjectWithName:@"RootObject"];
[decoded _makeConnections];
NSLog(@"testing...");
//NSLog(@"objects = %@, connections = %@",[decoded objects], [decoded connections]);
return self;
}
@end
static
Class gmodel_class(NSString *className)
{
static Class gmclass = Nil;
if (gmclass == Nil)
{
NSBundle *theBundle;
NSEnumerator *benum;
NSString *path;
/* Find the bundle */
benum = [NSStandardLibraryPaths() objectEnumerator];
while ((path = [benum nextObject]))
{
path = [path stringByAppendingPathComponent: @"Bundles"];
path = [path stringByAppendingPathComponent: @"libgmodel.bundle"];
if ([[NSFileManager defaultManager] fileExistsAtPath: path])
break;
path = nil;
}
NSCAssert(path != nil, @"Unable to load gmodel bundle");
NSDebugLog(@"Loading gmodel from %@", path);
theBundle = [NSBundle bundleWithPath: path];
NSCAssert(theBundle != nil, @"Can't init gmodel bundle");
gmclass = [theBundle classNamed: className];
NSCAssert(gmclass, @"Can't load gmodel bundle");
}
return gmclass;
}

View file

@ -138,21 +138,7 @@ NSwindow inspector
return [GormNSWindow alloc];
}
@end
/*
@interface NSWindow (GormPrivate)
- (void) _setStyleMask: (unsigned int)mask;
@end
*/
/*
@implementation GormWindow (GormPrivate)
// private method to change the Window style mask on the fly
- (void) _setStyleMask: (unsigned int)mask
{
_styleMask = mask;
DPSstylewindow(GSCurrentContext(), mask, [self windowNumber]);
}
@end
*/
@implementation GormNSWindow (IBInspectorClassNames)
- (NSString*) inspectorClassName
{