From d3a55312fb062d934a60d3da1d6e149f1cdf862a Mon Sep 17 00:00:00 2001 From: Adam Fedor Date: Wed, 13 Nov 2002 16:10:22 +0000 Subject: [PATCH] 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 --- ChangeLog | 8 + GModelDecoder.m | 309 +++++++++++++++++++++++++++++++++++++++ GNUmakefile | 1 + GormDocument.h | 4 +- GormDocument.m | 168 ++++++--------------- Palettes/1Windows/main.m | 16 +- 6 files changed, 367 insertions(+), 139 deletions(-) create mode 100644 GModelDecoder.m diff --git a/ChangeLog b/ChangeLog index cf6718a3..481b8755 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2002-11-13 Adam Fedor + + * 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 * ClassInformation.plist (NSDocument): Add _window outlet. diff --git a/GModelDecoder.m b/GModelDecoder.m new file mode 100644 index 00000000..09bd8155 --- /dev/null +++ b/GModelDecoder.m @@ -0,0 +1,309 @@ +/* GModelDecoder + * + * Copyright (C) 2002 Free Software Foundation, Inc. + * + * Author: Adam Fedor + * 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 +#include +#include +#include +#include +#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; +} + diff --git a/GNUmakefile b/GNUmakefile index 8f2b5422..6ad0f048 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -140,6 +140,7 @@ Gorm_OBJC_FILES = \ GormDocument.m \ IBInspector.m \ IBPalette.m \ + GModelDecoder.m \ GormCustomView.m \ GormViewKnobs.m \ GormFilesOwner.m \ diff --git a/GormDocument.h b/GormDocument.h index 57e6815f..2e5e0429 100644 --- a/GormDocument.h +++ b/GormDocument.h @@ -107,8 +107,8 @@ // sound support - (id) openSound: (id)sender; -// import gmodel -- (id) openGModel: (id)sender; +// Internals support +- (void) rebuildObjToNameMapping; @end #endif diff --git a/GormDocument.m b/GormDocument.m index 5fc46f33..f2a71fa7 100644 --- a/GormDocument.m +++ b/GormDocument.m @@ -28,39 +28,15 @@ #include "GormOutlineView.h" #include -// gmodel compatibility headers... -#include -#include -#include - -// 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 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; -} - diff --git a/Palettes/1Windows/main.m b/Palettes/1Windows/main.m index 20ac67b2..9698db8c 100644 --- a/Palettes/1Windows/main.m +++ b/Palettes/1Windows/main.m @@ -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 {