Gorm source

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/apps/gorm/trunk@5409 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 1999-12-08 15:04:57 +00:00
commit b24b1706c8
18 changed files with 3161 additions and 0 deletions

6
ChangeLog Normal file
View file

@ -0,0 +1,6 @@
Sat Nov 27 05:25:15 1999 Nicola Pero <n.pero@mi.flashnet.it>
* KeyboardInput-test/KeyboardInput-test.m ([inputTestView
-drawRect:]): Fixed bug.
* KeyboardInput-test/KeyboardInput-test.m ([KeyboardInputTest
-init]): Moved typing view to top.

82
GNUmakefile Normal file
View file

@ -0,0 +1,82 @@
# GNUmakefile: main makefile for GNUstep Object Relationship Modeller
#
# Copyright (C) 1999 Free Software Foundation, Inc.
#
# Author: Richard Frith-Macdonald <richard@brainstorm.co.uk>
# Date: 1999
#
# 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 $(GNUSTEP_MAKEFILES)/common.make
#
# Each palette is a subproject
#
SUBPROJECTS = \
Menu \
Text \
View \
Window
#
# MAIN APP
#
APP_NAME = Gorm
Gorm_APPLICATION_ICON=Gorm.tiff
Gorm_RESOURCE_FILES = \
Menu/Menu.palette \
Text/Text.palette \
View/View.palette \
Window/Window.palette \
Images/GormClass.tiff \
Images/GormFilesOwner.tiff \
Images/GormFirstResponder.tiff \
Images/GormFontManager.tiff \
Images/GormImage.tiff \
Images/GormWindow.tiff \
Images/GormMenu.tiff \
Images/GormObject.tiff \
Images/GormSound.tiff \
Images/Gorm.tiff \
Images/GormLinkImage.tiff
Gorm_HEADERS = \
Gorm.h \
GormPrivate.h
Gorm_OBJC_FILES = \
Gorm.m \
GormDocument.m \
GormEditors.m \
IBInspector.m \
IBPalette.m \
InfoPanel.m \
GormInspectorsManager.m \
GormPalettesManager.m \
GormResourcesManager.m
-include GNUmakefile.preamble
-include GNUmakefile.local
include $(GNUSTEP_MAKEFILES)/aggregate.make
include $(GNUSTEP_MAKEFILES)/application.make
include $(GNUSTEP_MAKEFILES)/bundle.make
-include GNUmakefile.postamble

205
Gorm.h Normal file
View file

@ -0,0 +1,205 @@
#ifndef GORM_H
#define GORM_H
#include <Foundation/Foundation.h>
#include <AppKit/AppKit.h>
#include <AppKit/NSNibConnector.h>
#include <AppKit/NSNibLoading.h>
/*
* Positions of handles for resizing items.
*/
enum IBKnowPosition {
IBBottomLeftKnobPosition,
IBMiddleLeftKnobPosition,
IBTopLeftKnobPosition,
IBTopMiddleKnobPosition,
IBTopRightKnobPosition,
IBMiddleRightKnobPosition,
IBBottomRightKnobPosition,
IBBottomMiddleKnobPosition
};
/*
* Pasteboard types used for DnD when views are dragged out of a palette
* window into another window in Gorm (or, in the case of IBWindowPboardType
* onto the desktop).
*/
extern NSString *IBCellPboardType;
extern NSString *IBMenuPboardType;
extern NSString *IBMenuCellPboardType;
extern NSString *IBObjectPboardType;
extern NSString *IBViewPboardType;
extern NSString *IBWindowPboardType;
/*
* Notification for editing and inspecting the objects etc.
*/
extern NSString *IBAttributesChangedNotification;
extern NSString *IBInspectorDidModifyObjectNotification;
extern NSString *IBSelectionChangedNotification;
extern NSString *IBWillBeginTestingInterfaceNotification;
extern NSString *IBDidBeginTestingInterfaceNotification;
extern NSString *IBWillEndTestingInterfaceNotification;
extern NSString *IBDidEndTestingInterfaceNotification;
/*
* Connector objects are used to record connections between nib objects.
*/
@protocol IBConnectors <NSObject>
- (id) destination;
- (void) establishConnection;
- (NSString*) label;
- (void) replaceObject: (id)anObject withObject: (id)anotherObject;
- (id) source;
- (void) setDestination: (id)anObject;
- (void) setLabel: (NSString*)label;
- (void) setSource: (id)anObject;
@end
@protocol IBDocuments <NSObject>
- (void) addConnector: (id<IBConnectors>)aConnector;
- (NSArray*) allConnectors;
- (void) attachObject: (id)anObject toParent: (id)aParent;
- (void) attachObjects: (NSArray*)anArray toParent: (id)aParent;
- (NSArray*) connectorsForDestination: (id)destination;
- (NSArray*) connectorsForDestination: (id)destination
ofClass: (Class)aConnectorClass;
- (NSArray*) connectorsForSource: (id)source;
- (NSArray*) connectorsForSource: (id)source
ofClass: (Class)aConnectorClass;
- (BOOL) containsObject: (id)anObject;
- (BOOL) containsObjectWithName: (NSString*)aName forParent: (id)parent;
- (BOOL) copyObject: (id)anObject
type: (NSString*)aType
toPasteboard: (NSPasteboard*)aPasteboard;
- (BOOL) copyObjects: (NSArray*)anArray
type: (NSString*)aType
toPasteboard: (NSPasteboard*)aPasteboard;
- (void) detachObject: (id)anObject;
- (void) detachObjects: (NSArray*)anArray;
- (NSString*) documentPath;
- (BOOL) documentShouldClose;
- (void) documentWillClose;
- (NSString*) nameForObject: (id)anObject;
- (NSArray*) objects;
- (id) parentOfObject: (id)anObject;
- (NSArray*) pasteType: (NSString*)aType
fromPasteboard: (NSPasteboard*)aPasteboard
parent: (id)parent;
- (void) removeConnector: (id<IBConnectors>)aConnector;
- (void) setName: (NSString*)aName forObject: (id)object;
- (void) touch; /* Mark document as having been changed. */
@end
@protocol IBSelectionOwners <NSObject>
- (unsigned) selectionCount;
- (NSArray*) selection;
- (void) drawSelection;
@end
@protocol IB <NSObject>
- (id<IBDocuments>) activeDocument;
- (BOOL) isTestingInterface;
- (id<IBSelectionOwners>) selectionOwner;
- (id) selectedObject;
@end
@interface IBPalette : NSObject
{
NSWindow *window;
NSImage *icon;
}
/*
* For internal use only - these class methods return the information
* associated with a particular view.
*/
+ (id) objectForView: (NSView*)aView;
+ (NSString*) typeForView: (NSView*)aView;
/*
* Associate a particular object and DnD type with a view - so that
* Gorm knows to initiate a DnD session with the specified object
* and type rather than an archived copy of the view itsself and
* the default type (IBViewPboardType).
*/
- (void) associateObject: (id)anObject
type: (NSString*)aType
with: (NSView*)aView;
/*
* Method called by Gorm when a new palette has been created and its nib
* (if any) has been loaded. Any palette initialisation should be done here.
*/
- (void) finishInstantiate;
/*
* Return the icon representing the palette.
*/
- (NSImage*) paletteIcon;
/*
* Return the window containing the views that may be dragged from the
* palette.
*/
- (NSWindow*) originalWindow;
@end
/*
* How to get the inspector for a particular object.
*/
@interface NSObject (IBInspectorClassNames)
- (NSString*) inspectorClassName;
- (NSString*) connectInspectorClassName;
- (NSString*) sizeInspectorClassName;
- (NSString*) helpInspectorClassName;
- (NSString*) classInspectorClassName;
@end
@interface IBInspector : NSObject
{
id object;
NSWindow *window;
NSButton *okButton;
NSButton *revertButton;
}
- (id) object;
- (void) ok: (id)sender;
- (NSButton*) okButton;
- (void) revert: (id)sender;
- (NSButton*) revertButton;
- (void) touch: (id)sender;
- (BOOL) wantsButtons;
- (NSWindow*) window;
@end
@interface NSObject (IBEditorSpecification)
- (NSString*) editorClassName;
@end
@protocol IBEditors <IBSelectionOwners>
- (BOOL) acceptsTypeFromArray: (NSArray*)types;
- (BOOL) activate;
- (id) initWithObject: (id)anObject inDocument: (id<IBDocuments>)aDocument;
- (void) close;
- (void) closeSubeditors;
- (void) copySelection;
- (void) deleteSelection;
- (id<IBDocuments>) document;
- (id) editedObject;
- (void) makeSelectionVisible: (BOOL)flag;
- (id<IBEditors>) openSubeditorForObject: (id)anObject;
- (void) orderFront;
- (void) pasteInSelection;
- (void) resetObject: (id)anObject;
- (void) selectObjects: (NSArray*)objects;
- (void) validateEditing;
- (BOOL) wantsSelection;
- (NSWindow*) window;
@end
#endif

324
Gorm.m Normal file
View file

@ -0,0 +1,324 @@
/* Gorm.m
*
* Copyright (C) 1999 Free Software Foundation, Inc.
*
* Author: Richard Frith-Macdonald <richard@brainstrom.co.uk>
* Date: 1999
*
* 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 "GormPrivate.h"
@class InfoPanel;
@implementation Gorm
- (id<IBDocuments>) activeDocument
{
return (id<IBDocuments>)[documents lastObject];
}
- (BOOL) applicationShouldTerminate: (NSApplication*)sender
{
NSEnumerator *enumerator = [documents objectEnumerator];
GormDocument *doc;
BOOL edited = NO;
while ((doc = [enumerator nextObject]) != nil)
{
if ([[[doc resourcesManager] window] isDocumentEdited] == YES)
{
edited = YES;
}
}
if (edited == YES)
{
int result;
result = NSRunAlertPanel(NULL, @"There are edited windows",
@"Review Unsaved", @"Cancel", @"Quit Anyway");
if (result == NSAlertAlternateReturn)
{
return NO;
}
else if (result != NSAlertOtherReturn)
{
enumerator = [documents objectEnumerator];
while ((doc = [enumerator nextObject]) != nil)
{
NSWindow *win = [[doc resourcesManager] window];
if ([win isDocumentEdited] == YES)
{
[win performClose: self];
}
}
}
}
return YES;
}
- (void) dealloc
{
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver: self];
RELEASE(infoPanel);
RELEASE(inspectorsManager);
RELEASE(palettesManager);
RELEASE(documents);
[super dealloc];
}
- (id) init
{
self = [super init];
if (self != nil)
{
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
documents = [NSMutableArray new];
[nc addObserver: self
selector: @selector(selectionChanged:)
name: IBSelectionChangedNotification
object: nil];
}
return self;
}
- (GormInspectorsManager*) inspectorsManager
{
if (inspectorsManager == nil)
{
inspectorsManager = [GormInspectorsManager new];
}
return inspectorsManager;
}
- (id) makeNewDocument: (id) sender
{
id doc = [GormDocument new];
[documents addObject: doc];
[doc setDocumentActive: YES];
RELEASE(doc);
return doc;
}
- (id) openDocument: (id) sender
{
GormDocument *doc = [GormDocument new];
[documents addObject: doc];
RELEASE(doc);
if ([doc openDocument: sender] == nil)
{
[documents removeObjectIdenticalTo: doc];
doc = nil;
}
else
{
[doc setDocumentActive: YES];
}
return doc;
}
- (id) openPalette: (id) sender
{
return [[self palettesManager] openPalette: sender];
}
- (GormPalettesManager*) palettesManager
{
if (palettesManager == nil)
{
palettesManager = [GormPalettesManager new];
}
return palettesManager;
}
- (id) runInfoPanel: (id) sender
{
if (infoPanel == nil)
{
infoPanel = [InfoPanel new];
}
[infoPanel orderFront: nil];
return self;
}
- (id) runGormInspectors: (id) sender
{
[[[self inspectorsManager] panel] orderFront: nil];
return self;
}
- (id) runGormPalettes: (id) sender
{
[[[self palettesManager] panel] orderFront: self];
return self;
}
- (id) saveAsDocument: (id)sender
{
return [[documents lastObject] saveAsDocument: sender];
}
- (id) saveDocument: (id)sender
{
return [[documents lastObject] saveDocument: sender];
}
- (void) selectionChanged: (NSNotification*)notification
{
selectionOwner = [notification object];
}
- (id<IBSelectionOwners>) selectionOwner
{
return selectionOwner;
}
- (id) selectedObject
{
return [[selectionOwner selection] lastObject];
}
@end
int
main(void)
{
NSAutoreleasePool *pool;
NSMenu *aMenu;
NSMenu *mainMenu;
NSMenu *windowsMenu;
NSMenuItem *menuItem;
pool = [NSAutoreleasePool new];
initialize_gnustep_backend ();
/*
* Install an instance of Gorm as the application so that the app
* can conform to the IB protocol
*/
NSApp = [Gorm new];
mainMenu = [[NSMenu alloc] initWithTitle: @"Gorm"];
/*
* Set up info menu.
*/
aMenu = [NSMenu new];
[aMenu addItemWithTitle: @"Info Panel..."
action: @selector(runInfoPanel:)
keyEquivalent: @""];
[aMenu addItemWithTitle: @"Help..."
action: NULL
keyEquivalent: @"?"];
menuItem = [mainMenu addItemWithTitle: @"Info"
action: NULL
keyEquivalent: @""];
[mainMenu setSubmenu: aMenu forItem: menuItem];
RELEASE(aMenu);
/*
* Set up document menu.
*/
aMenu = [NSMenu new];
[aMenu addItemWithTitle: @"Open..."
action: @selector(openDocument:)
keyEquivalent: @"o"];
[aMenu addItemWithTitle: @"New Application"
action: @selector(makeNewDocument:)
keyEquivalent: @"n"];
[aMenu addItemWithTitle: @"Save"
action: @selector(saveDocument:)
keyEquivalent: @"s"];
[aMenu addItemWithTitle: @"Save As..."
action: @selector(saveAsDocument:)
keyEquivalent: @"S"];
menuItem = [mainMenu addItemWithTitle: @"Document"
action: NULL
keyEquivalent: @""];
[mainMenu setSubmenu: aMenu forItem: menuItem];
RELEASE(aMenu);
/*
* Set up tools menu.
*/
aMenu = [NSMenu new];
[aMenu addItemWithTitle: @"Inspector..."
action: @selector(runGormInspectors:)
keyEquivalent: @""];
[aMenu addItemWithTitle: @"Palettes..."
action: @selector(runGormPalettes:)
keyEquivalent: @""];
[aMenu addItemWithTitle: @"Load Palette..."
action: @selector(openPalette:)
keyEquivalent: @""];
menuItem = [mainMenu addItemWithTitle: @"Tools"
action: NULL
keyEquivalent: @""];
[mainMenu setSubmenu: aMenu forItem: menuItem];
RELEASE(aMenu);
/*
* Set up Windows menu
*/
windowsMenu = [NSMenu new];
[windowsMenu addItemWithTitle: @"Arrange"
action: @selector(arrangeInFront:)
keyEquivalent: @""];
[windowsMenu addItemWithTitle: @"Miniaturize"
action: @selector(performMiniaturize:)
keyEquivalent: @"m"];
[windowsMenu addItemWithTitle: @"Close"
action: @selector(performClose:)
keyEquivalent: @"w"];
menuItem = [mainMenu addItemWithTitle: @"Windows"
action: NULL
keyEquivalent: @""];
[mainMenu setSubmenu: windowsMenu forItem: menuItem];
RELEASE(windowsMenu);
[mainMenu addItemWithTitle: @"Quit"
action: @selector(terminate:)
keyEquivalent: @"q"];
[NSApp setMainMenu: mainMenu];
[NSApp setWindowsMenu: windowsMenu];
[mainMenu display];
{
extern BOOL NSImageDoesCaching;
extern BOOL NSImageForceCaching;
NSImageDoesCaching = YES;
//[NSObject enableDoubleReleaseCheck: YES];
}
/*
* Set Gorm up as its own delegate
*/
[NSApp setDelegate: NSApp];
[NSApp run];
[pool release];
return 0;
}

51
GormDocument.h Normal file
View file

@ -0,0 +1,51 @@
#ifndef GORMDOCUMENT_H
#define GORMDOCUMENT_H
@interface GormDocument : GSNibContainer <IBDocuments>
{
GormResourcesManager *resourcesManager;
NSString *documentPath;
NSMapTable *objToName;
id owner; /* Dummy object */
}
- (void) addConnector: (id<IBConnectors>)aConnector;
- (NSArray*) allConnectors;
- (void) attachObject: (id)anObject toParent: (id)aParent;
- (void) attachObjects: (NSArray*)anArray toParent: (id)aParent;
- (NSArray*) connectorsForDestination: (id)destination;
- (NSArray*) connectorsForDestination: (id)destination
ofClass: (Class)aConnectorClass;
- (NSArray*) connectorsForSource: (id)source;
- (NSArray*) connectorsForSource: (id)source
ofClass: (Class)aConnectorClass;
- (BOOL) containsObject: (id)anObject;
- (BOOL) containsObjectWithName: (NSString*)aName forParent: (id)parent;
- (BOOL) copyObject: (id)anObject
type: (NSString*)aType
toPasteboard: (NSPasteboard*)aPasteboard;
- (BOOL) copyObjects: (NSArray*)anArray
type: (NSString*)aType
toPasteboard: (NSPasteboard*)aPasteboard;
- (void) detachObject: (id)anObject;
- (void) detachObjects: (NSArray*)anArray;
- (NSString*) documentPath;
- (BOOL) documentShouldClose;
- (void) documentWillClose;
- (NSString*) nameForObject: (id)anObject;
- (id) objectForName: (NSString*)aString;
- (NSArray*) objects;
- (id) openDocument: (id)sender;
- (id) parentOfObject: (id)anObject;
- (NSArray*) pasteType: (NSString*)aType
fromPasteboard: (NSPasteboard*)aPasteboard
parent: (id)parent;
- (GormResourcesManager*) resourcesManager;
- (void) removeConnector: (id<IBConnectors>)aConnector;
- (id) saveAsDocument: (id)sender;
- (id) saveDocument: (id)sender;
- (void) setDocumentActive: (BOOL)flag;
- (void) setName: (NSString*)aName forObject: (id)object;
- (void) touch; /* Mark document as having been changed. */
@end
#endif

722
GormDocument.m Normal file
View file

@ -0,0 +1,722 @@
/* GormDocument.m
*
* Copyright (C) 1999 Free Software Foundation, Inc.
*
* Author: Richard Frith-Macdonald <richard@brainstrom.co.uk>
* Date: 1999
*
* 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 "GormPrivate.h"
/*
* A private connector for child->parent relationships.
*/
@interface GormConnector : NSNibConnector
@end
@implementation GormConnector
@end
@implementation GormDocument
- (void) addConnector: (id<IBConnectors>)aConnector
{
if ([connections indexOfObjectIdenticalTo: aConnector] == NSNotFound)
{
[connections addObject: aConnector];
}
}
- (NSArray*) allConnectors
{
return AUTORELEASE([connections copy]);
}
- (void) attachObject: (id)anObject toParent: (id)aParent
{
NSArray *old;
/*
* Create a connector that links this object to its parent.
* A nil parent is the root of the hierarchy so we use a dummy object for it.
*/
if (aParent == nil)
{
aParent = owner;
}
old = [self connectorsForSource: anObject ofClass: [GormConnector class]];
if ([old count] > 0)
{
[[old objectAtIndex: 0] setDestination: aParent];
}
else
{
GormConnector *con = [GormConnector new];
[con setSource: anObject];
[con setDestination: aParent];
[self addConnector: (id<IBConnectors>)con];
RELEASE(con);
}
[self setName: nil forObject: anObject];
if ([anObject isKindOfClass: [NSWindow class]] == YES)
{
[resourcesManager addObject: anObject];
}
else if ([anObject isKindOfClass: [NSMenu class]] == YES)
{
[resourcesManager addObject: anObject];
}
}
- (void) attachObjects: (NSArray*)anArray toParent: (id)aParent
{
NSEnumerator *enumerator = [anArray objectEnumerator];
NSObject *obj;
while ((obj = [enumerator nextObject]) != nil)
{
[self attachObject: obj toParent: aParent];
}
}
- (NSArray*) connectorsForDestination: (id)destination
{
return [self connectorsForDestination: destination ofClass: 0];
}
- (NSArray*) connectorsForDestination: (id)destination
ofClass: (Class)aConnectorClass
{
NSMutableArray *array = [NSMutableArray arrayWithCapacity: 16];
NSEnumerator *enumerator = [connections objectEnumerator];
id<IBConnectors> c;
while ((c = [enumerator nextObject]) != nil)
{
if ([c destination] == destination
&& (aConnectorClass == 0 || aConnectorClass == [c class]))
{
[array addObject: c];
}
}
return array;
}
- (NSArray*) connectorsForSource: (id)source
{
return [self connectorsForSource: source ofClass: 0];
}
- (NSArray*) connectorsForSource: (id)source
ofClass: (Class)aConnectorClass
{
NSMutableArray *array = [NSMutableArray arrayWithCapacity: 16];
NSEnumerator *enumerator = [connections objectEnumerator];
id<IBConnectors> c;
while ((c = [enumerator nextObject]) != nil)
{
if ([c source] == source
&& (aConnectorClass == 0 || aConnectorClass == [c class]))
{
[array addObject: c];
}
}
return array;
}
- (BOOL) containsObject: (id)anObject
{
if ([self nameForObject: anObject] == nil)
{
return NO;
}
return YES;
}
- (BOOL) containsObjectWithName: (NSString*)aName forParent: (id)parent
{
id obj = [nameTable objectForKey: aName];
if (obj == nil)
{
return NO;
}
/* FIXME */
return YES;
}
- (BOOL) copyObject: (id)anObject
type: (NSString*)aType
toPasteboard: (NSPasteboard*)aPasteboard
{
return [self copyObjects: [NSArray arrayWithObject: anObject]
type: aType
toPasteboard: aPasteboard];
}
- (BOOL) copyObjects: (NSArray*)anArray
type: (NSString*)aType
toPasteboard: (NSPasteboard*)aPasteboard
{
NSData *obj = [NSArchiver archivedDataWithRootObject: anArray];
[aPasteboard declareTypes: [NSArray arrayWithObject: aType]
owner: self];
return [aPasteboard setData: obj forType: aType];
}
- (void) dealloc
{
[[resourcesManager window] performClose: self];
RELEASE(resourcesManager);
NSFreeMapTable(objToName);
RELEASE(documentPath);
RELEASE(owner);
[super dealloc];
}
- (void) detachObject: (id)anObject
{
NSString *name = [self nameForObject: anObject];
unsigned count = [connections count];
while (count-- > 0)
{
id<IBConnectors> con = [connections objectAtIndex: count];
if ([con destination] == anObject || [con source] == anObject)
{
[connections removeObjectAtIndex: count];
}
}
NSMapRemove(objToName, (void*)anObject);
if ([anObject isKindOfClass: [NSWindow class]] == YES)
{
[resourcesManager removeObject: anObject];
}
else if ([anObject isKindOfClass: [NSMenu class]] == YES)
{
[resourcesManager removeObject: anObject];
}
[nameTable removeObjectForKey: name];
}
- (void) detachObjects: (NSArray*)anArray
{
NSEnumerator *enumerator = [anArray objectEnumerator];
NSObject *obj;
while ((obj = [enumerator nextObject]) != nil)
{
[self detachObject: obj];
}
}
- (NSString*) documentPath
{
return documentPath;
}
- (BOOL) documentShouldClose
{
if ([[resourcesManager window] isDocumentEdited] == YES)
{
NSString *msg;
int result;
if (documentPath == nil || [documentPath isEqualToString: @""])
{
msg = @"Document 'UNTITLED' has been modified";
}
else
{
msg = [NSString stringWithFormat: @"Document '%@' has been modified",
[documentPath lastPathComponent]];
}
result = NSRunAlertPanel(NULL, msg, @"Save", @"Cancel", @"Don't Save");
if (result == NSAlertAlternateReturn)
{
return NO;
}
else if (result != NSAlertOtherReturn)
{
[self saveDocument: self];
}
}
return YES;
}
- (void) documentWillClose
{
NSEnumerator *enumerator = [nameTable objectEnumerator];
Class winClass = [NSWindow class];
id obj;
/*
* Close all open windows in this document befoew we go away.
*/
while ((obj = [enumerator nextObject]) != nil)
{
if ([obj isKindOfClass: winClass] == YES)
{
[obj setReleasedWhenClosed: YES];
[obj close];
}
}
[self setDocumentActive: NO];
}
- (void) encodeWithCoder: (NSCoder*)aCoder
{
NSEnumerator *enumerator;
id<IBConnectors> con;
/*
* Map all connector sources and destinations to their name strings.
* The 'owner' dummy object maps to 'NSOwner'.
* The nil object maps to 'NSFirstResponder'.
*/
enumerator = [connections objectEnumerator];
while ((con = [enumerator nextObject]) != nil)
{
NSString *name;
id obj;
obj = [con source];
name = [self nameForObject: obj];
[con setSource: name];
obj = [con destination];
name = [self nameForObject: obj];
[con setDestination: name];
}
[super encodeWithCoder: aCoder];
/*
* Map all connector source and destination names to their objects.
* The string 'NSOwner' maps to the 'owner' dummy object.
* The string 'NSFirstResponder' maps to nil.
*/
enumerator = [connections objectEnumerator];
while ((con = [enumerator nextObject]) != nil)
{
NSString *name;
id obj;
name = (NSString*)[con source];
obj = [self objectForName: name];
[con setSource: obj];
name = (NSString*)[con destination];
obj = [self objectForName: name];
[con setDestination: obj];
}
}
- (id) init
{
self = [super init];
if (self != nil)
{
objToName = NSCreateMapTableWithZone(NSNonRetainedObjectMapKeyCallBacks,
NSNonRetainedObjectMapValueCallBacks, 128, [self zone]);
owner = [NSObject new];
resourcesManager = [GormResourcesManager newManagerForDocument: self];
}
return self;
}
- (NSString*) nameForObject: (id)anObject
{
if (anObject == nil)
{
return @"NSFirstResponder";
}
else if (anObject == owner)
{
return @"NSOwner";
}
else
{
return (NSString*)NSMapGet(objToName, (void*)anObject);
}
}
- (id) objectForName: (NSString*)name
{
id obj = [nameTable objectForKey: name];
if (obj == nil)
{
if ([name isEqualToString: @"NSOwner"] == YES)
{
obj = owner;
}
}
return obj;
}
- (NSArray*) objects
{
return [nameTable allValues];
}
/*
* NB. This assumes we have an empty document to start with - the loaded
* document is merged in to it.
*/
- (id) openDocument: (id)sender
{
NSArray *fileTypes = [NSArray arrayWithObject: @"nib"];
NSOpenPanel *oPanel = [NSOpenPanel openPanel];
int result;
[oPanel setAllowsMultipleSelection: NO];
[oPanel setCanChooseFiles: YES];
[oPanel setCanChooseDirectories: NO];
result = [oPanel runModalForDirectory: NSHomeDirectory()
file: nil
types: fileTypes];
if (result == NSOKButton)
{
NSString *aFile = [oPanel filename];
NSData *data;
NSUnarchiver *u;
GSNibContainer *c;
NSEnumerator *enumerator;
NSDictionary *nt;
id <IBConnectors> con;
NSString *name;
data = [NSData dataWithContentsOfFile: aFile];
if (data == nil)
{
NSRunAlertPanel(NULL,
[NSString stringWithFormat: @"Could not read '%@' data", aFile],
@"OK", NULL, NULL);
return nil;
}
u = AUTORELEASE([[NSUnarchiver alloc] initForReadingWithData: data]);
/* FIXME - need to handle class replacement here */
c = [u decodeObject];
if (c == nil || [c isKindOfClass: [GSNibContainer class]] == NO)
{
NSRunAlertPanel(NULL, @"Could not unarchive document data",
@"OK", NULL, NULL);
return nil;
}
/*
* 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'.
*/
[[c nameTable] setObject: owner forKey: @"NSOwner"];
nt = [c nameTable];
enumerator = [[c 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];
}
[[c nameTable] removeObjectForKey: @"NSOwner"];
/*
* Now we merge the objects from the nib container into our own
* data structures.
*/
[connections addObjectsFromArray: [c connections]];
[nameTable addEntriesFromDictionary: [c nameTable]];
/*
* Now we build our reverse mapping information and other initialisation
*/
NSResetMapTable(objToName);
enumerator = [nameTable keyEnumerator];
while ((name = [enumerator nextObject]) != nil)
{
id obj = [nameTable objectForKey: name];
NSMapInsert(objToName, (void*)obj, (void*)name);
if ([obj isKindOfClass: [NSWindow class]] == YES)
{
[resourcesManager addObject: obj];
}
else if ([obj isKindOfClass: [NSMenu class]] == YES)
{
[resourcesManager addObject: obj];
}
}
/*
* Finally, we set our new file name
*/
ASSIGN(documentPath, aFile);
[[resourcesManager window] setTitleWithRepresentedFilename: documentPath];
return self;
}
return nil; /* Failed */
}
- (id) parentOfObject: (id)anObject
{
NSArray *old;
id<IBConnectors> con;
old = [self connectorsForSource: anObject ofClass: [GormConnector class]];
con = [old lastObject];
if (con != nil && [con destination] != owner)
{
return [con destination];
}
return nil;
}
- (NSArray*) pasteType: (NSString*)aType
fromPasteboard: (NSPasteboard*)aPasteboard
parent: (id)parent
{
NSData *data = [aPasteboard dataForType: aType];
NSArray *objects = [NSUnarchiver unarchiveObjectWithData: data];
NSEnumerator *enumerator = [objects objectEnumerator];
NSPoint filePoint;
NSPoint screenPoint;
filePoint = [[resourcesManager window] mouseLocationOutsideOfEventStream];
screenPoint = [[resourcesManager window] convertBaseToScreen: filePoint];
if ([aType isEqualToString: IBWindowPboardType] == YES)
{
NSWindow *win;
while ((win = [enumerator nextObject]) != nil)
{
[win setFrameTopLeftPoint: screenPoint];
[win orderFront: self];
}
}
else
{
NSLog(@"Pasting %@ not implemented", aType);
objects = nil;
/* FIXME */
}
[self attachObjects: objects toParent: parent];
[self touch];
return objects;
}
- (void) removeConnector: (id<IBConnectors>)aConnector
{
[connections removeObjectIdenticalTo: aConnector];
}
- (GormResourcesManager*) resourcesManager
{
return resourcesManager;
}
- (void) setName: (NSString*)aName forObject: (id)object
{
id oldObject;
NSString *oldName;
if (object == nil)
{
NSLog(@"Attempt to set name for nil object");
return;
}
if (aName == nil)
{
/*
* No name given - so we must generate one unless we already have one.
*/
oldName = [self nameForObject: object];
if (oldName == nil)
{
NSString *base;
unsigned i = 0;
/*
* Generate a sensible name for the object based on its class.
*/
base = NSStringFromClass([object class]);
if ([base hasPrefix: @"NS"] || [base hasPrefix: @"GS"])
{
base = [base substringFromIndex: 2];
}
aName = base;
while ([nameTable objectForKey: aName] != nil)
{
aName = [base stringByAppendingFormat: @"%u", ++i];
}
}
else
{
return; /* Already named ... nothing to do */
}
}
else
{
oldObject = [nameTable objectForKey: aName];
if (oldObject != nil)
{
NSLog(@"Attempt to re-use name '%@'", aName);
return;
}
oldName = [self nameForObject: object];
if (oldName != nil)
{
if ([oldName isEqual: aName] == YES)
{
return; /* Already have this namre ... nothing to do */
}
NSMapRemove(objToName, (void*)object);
}
}
if ([aName isEqualToString: @"NSOwner"]
|| [aName isEqualToString: @"NSFirstResponder"])
{
NSLog(@"Attempt to set object name to '%@' ignored", aName);
return;
}
[nameTable setObject: object forKey: aName];
NSMapInsert(objToName, (void*)object, (void*)aName);
if (oldName != nil)
{
[nameTable removeObjectForKey: oldName];
}
}
- (id) saveAsDocument: (id)sender
{
NSSavePanel *sp;
int result;
sp = [NSSavePanel savePanel];
[sp setRequiredFileType: @"nib"];
result = [sp runModalForDirectory: NSHomeDirectory() file: @""];
if (result == NSOKButton)
{
NSFileManager *mgr = [NSFileManager defaultManager];
NSString *path = [sp filename];
NSString *old = documentPath;
id retval;
if ([path isEqual: documentPath] == NO
&& [mgr fileExistsAtPath: path] == YES)
{
if (NSRunAlertPanel(NULL, @"A document with that name exists",
@"Replace", @"Cancel", NULL) != NSAlertDefaultReturn)
{
return nil;
}
else
{
NSString *bPath = [path stringByAppendingString: @"~"];
[mgr removeFileAtPath: bPath handler: nil];
[mgr movePath: path toPath: bPath handler: nil];
}
}
documentPath = RETAIN(path);
retval = [self saveDocument: sender];
if (retval == nil)
{
RELEASE(documentPath);
documentPath = old;
}
else
{
RELEASE(old);
/* FIXME - need to update files window title etc */
return self;
}
}
return nil;
}
- (id) saveDocument: (id)sender
{
if (documentPath == nil || [documentPath isEqualToString: @""])
{
return [self saveAsDocument: sender];
}
if ([NSArchiver archiveRootObject: self toFile: documentPath] == NO)
{
NSRunAlertPanel(NULL, @"Could not save document",
@"OK", NULL, NULL);
return nil;
}
[[resourcesManager window] setDocumentEdited: NO];
[[resourcesManager window] setTitleWithRepresentedFilename: documentPath];
return self;
}
- (void) setDocumentActive: (BOOL)flag
{
NSEnumerator *enumerator = [nameTable objectEnumerator];
Class winClass = [NSWindow class];
id obj;
if (flag == YES)
{
while ((obj = [enumerator nextObject]) != nil)
{
if ([obj isKindOfClass: winClass] == YES)
{
[obj orderFront: self];
}
}
[[resourcesManager window] orderFront: self];
}
else
{
while ((obj = [enumerator nextObject]) != nil)
{
if ([obj isKindOfClass: winClass] == YES)
{
[obj orderOut: self];
}
}
[[resourcesManager window] orderOut: self];
}
}
- (void) touch
{
[[resourcesManager window] setDocumentEdited: YES];
}
@end

133
GormEditors.m Normal file
View file

@ -0,0 +1,133 @@
/* GormEditors.m
*
* Copyright (C) 1999 Free Software Foundation, Inc.
*
* Author: Richard Frith-Macdonald <richard@brainstrom.co.uk>
* Date: 1999
*
* 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 "GormPrivate.h"
@implementation NSObject (IBEditorSpecification)
- (NSString*) editorClassName
{
return @"GormObjectEditor";
}
@end
@interface GormObjectEditor : NSObject <IBEditors>
{
id object;
id<IBDocuments> document;
NSMutableArray *subeditors;
}
- (BOOL) acceptsTypeFromArray: (NSArray*)types;
- (BOOL) activate;
- (id) initWithObject: (id)anObject inDocument: (id<IBDocuments>)aDocument;
- (void) close;
- (void) closeSubeditors;
- (void) copySelection;
- (void) deleteSelection;
- (id<IBDocuments>) document;
- (id) editedObject;
- (void) makeSelectionVisible: (BOOL)flag;
- (id<IBEditors>) openSubeditorForObject: (id)anObject;
- (void) orderFront;
- (void) pasteInSelection;
- (void) resetObject: (id)anObject;
- (void) selectObjects: (NSArray*)objects;
- (void) validateEditing;
- (BOOL) wantsSelection;
- (NSWindow*) window;
@end
@implementation GormObjectEditor
- (BOOL) acceptsTypeFromArray: (NSArray*)types
{
return NO;
}
- (BOOL) activate
{
return NO;
}
- (void) dealloc
{
RELEASE(subeditors);
RELEASE(object);
RELEASE(document);
[super dealloc];
}
- (id) initWithObject: (id)anObject inDocument: (id<IBDocuments>)aDocument
{
self = [super init];
if (self)
{
object = RETAIN(anObject);
document = RETAIN(aDocument);
subeditors = [NSMutableArray new];
}
return self;
}
- (void) close
{
[self closeSubeditors];
}
- (void) closeSubeditors
{
unsigned i = [subeditors count];
while (i-- > 0)
{
[[subeditors objectAtIndex: i] close];
[subeditors removeObjectAtIndex: i];
}
}
- (void) copySelection
{
}
- (void) deleteSelection
{
}
- (id<IBDocuments>) document
{
return document;
}
- (id) editedObject
{
return object;
}
- (void) makeSelectionVisible: (BOOL)flag
{
}
@end

19
GormInspectorsManager.h Normal file
View file

@ -0,0 +1,19 @@
#ifndef GORMINSPECTORSMANAGER_H
#define GORMINSPECTORSMANAGER_H
@interface GormInspectorsManager : NSObject
{
NSPanel *panel;
NSMatrix *selectionView;
NSView *inspectorView;
NSArray *selection;
NSButton *emptyView;
NSButton *multipleView;
IBInspector *inspector;
int current;
}
- (NSPanel*) panel;
- (void) setCurrentInspector: (id)anObject;
@end
#endif

225
GormInspectorsManager.m Normal file
View file

@ -0,0 +1,225 @@
/* GormInspectorsManager.m
*
* Copyright (C) 1999 Free Software Foundation, Inc.
*
* Author: Richard Frith-Macdonald <richard@brainstrom.co.uk>
* Date: 1999
*
* 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 "GormPrivate.h"
@implementation NSObject (IBInspectorClassNames)
- (NSString*) inspectorClassName
{
return @"GormObjectAttributesInspector";
}
- (NSString*) connectInspectorClassName
{
return @"GormObjectConnectionsInspector";
}
- (NSString*) sizeInspectorClassName
{
return @"GormObjectSizeInspector";
}
- (NSString*) helpInspectorClassName
{
return @"GormObjectHelpInspector";
}
- (NSString*) classInspectorClassName
{
return @"GormObjectClassInspector";
}
@end
@implementation GormInspectorsManager
- (void) dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver: self];
RELEASE(selectionView);
RELEASE(inspectorView);
RELEASE(emptyView);
RELEASE(multipleView);
RELEASE(panel);
[super dealloc];
}
- (id) init
{
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
NSBox *box;
NSCell *cell;
NSRect contentRect = {{0, 0}, {272, 420}};
NSRect selectionRect = {{0, 378}, {272, 52}};
NSRect boxRect = {{0, 361}, {272, 2}};
NSRect inspectorRect = {{0, 0}, {272, 360}};
unsigned int style = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask;
panel = [[NSPanel alloc] initWithContentRect: contentRect
styleMask: style
backing: NSBackingStoreRetained
defer: NO];
box = [[NSBox alloc] initWithFrame: boxRect];
[box setBorderType: NSLineBorder];
[box setTitlePosition: NSNoTitle];
[box setAutoresizingMask: NSViewWidthSizable|NSViewMinYMargin];
[[panel contentView] addSubview: box];
RELEASE(box);
[panel setTitle: @"Inspector"];
[panel setMinSize: [panel frame].size];
selectionView = [[NSMatrix alloc] initWithFrame: selectionRect
mode: NSRadioModeMatrix
cellClass: [NSCell class]
numberOfRows: 1
numberOfColumns: 4];
[selectionView setTarget: self];
[selectionView setAction: @selector(setCurrentInspector:)];
[selectionView setCellSize: NSMakeSize(52,52)];
[selectionView setIntercellSpacing: NSMakeSize(0,0)];
[selectionView setAutoresizingMask: NSViewWidthSizable|NSViewMinYMargin];
cell = [selectionView cellAtRow: 0 column: 0];
[cell setStringValue: @"Attr"];
cell = [selectionView cellAtRow: 0 column: 1];
[cell setStringValue: @"Size"];
cell = [selectionView cellAtRow: 0 column: 2];
[cell setStringValue: @"Conn"];
cell = [selectionView cellAtRow: 0 column: 3];
[cell setStringValue: @"Help"];
[[panel contentView] addSubview: selectionView];
RELEASE(selectionView);
inspectorView = [[NSView alloc] initWithFrame: inspectorRect];
[inspectorView setAutoresizingMask:
NSViewHeightSizable | NSViewWidthSizable];
[[panel contentView] addSubview: inspectorView];
RELEASE(inspectorView);
[panel setFrameUsingName: @"Inspector"];
[panel setFrameAutosaveName: @"Inspector"];
current = -1;
emptyView = [[NSButton alloc] initWithFrame: inspectorRect];
[emptyView setAutoresizingMask:
NSViewHeightSizable | NSViewWidthSizable];
[emptyView setStringValue: @"Empty Selection"];
[emptyView setBordered: NO];
multipleView = [[NSButton alloc] initWithFrame: inspectorRect];
[multipleView setAutoresizingMask:
NSViewHeightSizable | NSViewWidthSizable];
[multipleView setStringValue: @"Multiple Selection"];
[multipleView setBordered: NO];
[nc addObserver: self
selector: @selector(selectionChanged:)
name: IBSelectionChangedNotification
object: nil];
[self setCurrentInspector: 0];
return self;
}
- (NSPanel*) panel
{
return panel;
}
- (void) selectionChanged: (NSNotification*)notification
{
[self setCurrentInspector: self];
}
- (void) setCurrentInspector: (id)anObj
{
id<IBSelectionOwners> owner = [(id<IB>)NSApp selectionOwner];
unsigned count = [owner selectionCount];
NSArray *sub = [inspectorView subviews];
IBInspector *newInspector = nil;
NSView *newView = nil;
if (anObj != self)
{
current = [anObj selectedColumn];
}
if (count == 0)
{
newView = emptyView;
}
else if (count > 1)
{
newView = multipleView;
}
else
{
id obj = [[owner selection] lastObject];
NSString *name;
Class c;
switch (current)
{
case 0: name = [obj inspectorClassName]; break;
case 1: name = [obj connectInspectorClassName]; break;
case 2: name = [obj sizeInspectorClassName]; break;
case 3: name = [obj helpInspectorClassName]; break;
default: name = [obj classInspectorClassName]; break;
}
c = NSClassFromString(name);
if (inspector == nil || [inspector class] != c)
{
newInspector = [c new];
newView = [[newInspector window] contentView];
}
else
{
newInspector = inspector;
}
}
if (newInspector != inspector)
{
if (inspector != nil)
{
[[inspector window] setContentView: [sub lastObject]];
RELEASE((id)inspector);
sub = [inspectorView subviews];
}
inspector = newInspector;
}
if (newView != nil)
{
if ([sub count] > 0)
{
[inspectorView replaceSubview: [sub lastObject] with: newView];
}
else
{
[inspectorView addSubview: newView];
}
}
}
@end

20
GormPalettesManager.h Normal file
View file

@ -0,0 +1,20 @@
#ifndef GORMPALETTESMANAGER_H
#define GORMPALETTESMANAGER_H
@interface GormPalettesManager : NSObject
{
NSPanel *panel;
NSMatrix *selectionView;
NSView *dragView;
NSMutableArray *bundles;
NSMutableArray *palettes;
int current;
}
- (void) loadPalette: (NSString*)path;
- (id) openPalette: (id) sender;
- (NSPanel*) panel;
- (void) setCurrentPalette: (id)anObject;
@end
#endif

434
GormPalettesManager.m Normal file
View file

@ -0,0 +1,434 @@
/* GormPalettesPanager.m
*
* Copyright (C) 1999 Free Software Foundation, Inc.
*
* Author: Richard Frith-Macdonald <richard@brainstrom.co.uk>
* Date: 1999
*
* 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 "GormPrivate.h"
@interface GormPaletteView : NSView
{
NSPoint mouseDownPoint;
BOOL shouldBeginDrag;
NSPasteboard *dragPb;
}
- (void) draggedImage: (NSImage*)i endedAt: (NSPoint)p deposited: (BOOL)f;
- (unsigned int) draggingSourceOperationMaskForLocal: (BOOL)flag;
@end
@implementation GormPaletteView
static NSImage *dragImage = nil;
+ (void) initialize
{
if (self == [GormPaletteView class])
{
NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle pathForImageResource: @"GormLinkImage"];
dragImage = [[NSImage alloc] initWithContentsOfFile: path];
}
}
/*
* Initialisation - register to receive DnD with our own types.
*/
- (id) initWithFrame: (NSRect)aFrame
{
self = [super initWithFrame: aFrame];
if (self != nil)
{
[self registerForDraggedTypes: [NSArray arrayWithObjects:
IBCellPboardType, IBMenuPboardType, IBMenuCellPboardType,
IBObjectPboardType, IBViewPboardType, IBWindowPboardType, nil]];
}
return self;
}
/*
* Dragging source protocol implementation
*/
- (void) draggedImage: (NSImage*)i endedAt: (NSPoint)p deposited: (BOOL)f
{
NSString *type = [[dragPb types] lastObject];
/*
* Windows are an exception to the normal DnD mechanism - we create them
* if they are dropped anywhere except back in the pallettes view -
* ie. if they are dragged, but the drop fails.
*/
if (f == NO && [type isEqual: IBWindowPboardType] == YES)
{
id<IBDocuments> active = [(id<IB>)NSApp activeDocument];
if (active != nil)
{
[active pasteType: type fromPasteboard: dragPb parent: nil];
}
}
}
- (unsigned int) draggingSourceOperationMaskForLocal: (BOOL)flag
{
return NSDragOperationCopy;
}
/*
* Dragging destination protocol implementation
*
* We actually don't handle anything being dropped on the palette,
* but we pretend to accept drops from ourself, so that the drag
* session quietly terminates - and it looks like the drop has
* been successful - this stops windows being created when they are
* dropped back on the palette (a window is normally created if the
* dnd drop is refused).
*/
- (unsigned) draggingEntered: (id<NSDraggingInfo>)sender
{
return NSDragOperationCopy;;
}
- (BOOL) performDragOperation: (id<NSDraggingInfo>)sender
{
return YES;
}
- (BOOL) prepareForDragOperation: (id<NSDraggingInfo>)sender
{
return YES;
}
/*
* Intercepting events in the view and handling them
*/
- (NSView*) hitTest: (NSPoint)loc
{
/*
* Stop the subviews receiving events - we grab them all.
*/
if ([super hitTest: loc] != nil)
return self;
return nil;
}
- (void) mouseDown: (NSEvent*)theEvent
{
NSView *view;
mouseDownPoint = [theEvent locationInWindow];
view = [super hitTest: mouseDownPoint];
if (view == self)
{
shouldBeginDrag = NO;
}
else
{
shouldBeginDrag = YES;
}
}
- (void) mouseDragged: (NSEvent*)theEvent
{
if (shouldBeginDrag == YES)
{
NSPoint dragPoint = [theEvent locationInWindow];
NSView *view = [super hitTest: mouseDownPoint];
GormDocument *active = [(id<IB>)NSApp activeDocument];
NSRect rect = [view frame];
NSString *type;
id obj;
NSPasteboard *pb;
NSImageRep *rep;
NSSize offset;
offset.width = mouseDownPoint.x - dragPoint.x;
offset.height = mouseDownPoint.y - dragPoint.y;
RELEASE(dragImage);
dragImage = [NSImage new];
rep = [[NSCachedImageRep alloc] initWithWindow: [self window]
rect: rect];
[dragImage setSize: rect.size];
[dragImage addRepresentation: rep];
type = [IBPalette typeForView: view];
obj = [IBPalette objectForView: view];
pb = [NSPasteboard pasteboardWithName: NSDragPboard];
ASSIGN(dragPb, pb);
[active copyObject: obj type: type toPasteboard: pb];
[self dragImage: dragImage
at: rect.origin
offset: offset
event: theEvent
pasteboard: pb
source: self
slideBack: [type isEqual: IBWindowPboardType] ? NO : YES];
}
}
@end
@implementation GormPalettesManager
- (void) dealloc
{
RELEASE(panel);
RELEASE(bundles);
RELEASE(palettes);
[super dealloc];
}
- (id) init
{
NSScrollView *scrollView;
NSArray *array;
NSRect contentRect = {{0, 0}, {272, 266}};
NSRect selectionRect = {{0, 0}, {52, 52}};
NSRect scrollRect = {{0, 192}, {272, 74}};
NSRect dragRect = {{0, 0}, {272, 192}};
unsigned int style = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask;
panel = [[NSPanel alloc] initWithContentRect: contentRect
styleMask: style
backing: NSBackingStoreRetained
defer: NO];
[panel setTitle: @"Palettes"];
[panel setMinSize: [panel frame].size];
bundles = [NSMutableArray new];
palettes = [NSMutableArray new];
scrollView = [[NSScrollView alloc] initWithFrame: scrollRect];
[scrollView setHasHorizontalScroller: YES];
[scrollView setHasVerticalScroller: NO];
[scrollView setAutoresizingMask: NSViewMinYMargin | NSViewWidthSizable];
selectionView = [[NSMatrix alloc] initWithFrame: selectionRect
mode: NSRadioModeMatrix
cellClass: [NSImageCell class]
numberOfRows: 1
numberOfColumns: 0];
[selectionView setTarget: self];
[selectionView setAction: @selector(setCurrentPalette:)];
[selectionView setCellSize: NSMakeSize(52,52)];
[selectionView setIntercellSpacing: NSMakeSize(0,0)];
[scrollView setDocumentView: selectionView];
RELEASE(selectionView);
[[panel contentView] addSubview: scrollView];
RELEASE(scrollView);
dragView = [[GormPaletteView alloc] initWithFrame: dragRect];
[dragView setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
[[panel contentView] addSubview: dragView];
RELEASE(dragView);
[panel setFrameUsingName: @"Palettes"];
[panel setFrameAutosaveName: @"Palettes"];
current = -1;
array = [[NSBundle mainBundle] pathsForResourcesOfType: @"palette"
inDirectory: nil];
if ([array count] > 0)
{
unsigned index;
for (index = 0; index < [array count]; index++)
{
[self loadPalette: [array objectAtIndex: index]];
}
}
return self;
}
- (void) loadPalette: (NSString*)path
{
NSBundle *bundle;
NSWindow *window;
Class paletteClass;
NSDictionary *paletteInfo;
NSString *className;
IBPalette *palette;
NSImageCell *cell;
int col;
for (col = 0; col < [bundles count]; col++)
{
bundle = [bundles objectAtIndex: col];
if ([path isEqualToString: [bundle bundlePath]] == YES)
{
NSRunAlertPanel (NULL, @"Palette has already been loaded",
@"OK", NULL, NULL);
return;
}
}
bundle = [NSBundle bundleWithPath: path];
if (bundle == nil)
{
NSRunAlertPanel(NULL, @"Could not load Palette",
@"OK", NULL, NULL);
return;
}
[bundles addObject: bundle];
path = [bundle pathForResource: @"palette" ofType: @"table"];
if (path == nil)
{
NSRunAlertPanel(NULL, @"File 'palette.table' missing",
@"OK", NULL, NULL);
return;
}
paletteInfo = [[NSString stringWithContentsOfFile: path]
propertyListFromStringsFileFormat];
if (paletteInfo == nil)
{
NSRunAlertPanel(NULL, @"Failed to load 'palette.table'",
@"OK", NULL, NULL);
return;
}
className = [paletteInfo objectForKey: @"Class"];
if (className == nil)
{
NSRunAlertPanel(NULL, @"No palette class in 'palette.table'",
@"OK", NULL, NULL);
return;
}
paletteClass = [bundle classNamed: className];
if (paletteClass == 0)
{
NSRunAlertPanel (NULL, @"Could not load palette class",
@"OK", NULL, NULL);
return;
}
palette = [paletteClass new];
if ([palette isKindOfClass: [IBPalette class]] == NO)
{
NSRunAlertPanel (NULL, @"Palette contains wrong type of class",
@"OK", NULL, NULL);
RELEASE(palette);
return;
}
[palette finishInstantiate];
window = [palette originalWindow];
[window setExcludedFromWindowsMenu: YES];
[palettes addObject: palette];
[selectionView addColumn];
[[palette paletteIcon] setBackgroundColor: [selectionView backgroundColor]];
col = [selectionView numberOfColumns] - 1;
cell = [selectionView cellAtRow: 0 column: col];
[cell setImageFrameStyle: NSImageFrameButton];
[cell setImage: [palette paletteIcon]];
[selectionView sizeToCells];
[selectionView selectCellAtRow: 0 column: col];
[selectionView setNeedsDisplay: YES];
RELEASE(palette);
}
- (id) openPalette: (id) sender
{
NSArray *fileTypes = [NSArray arrayWithObject: @"palette"];
NSOpenPanel *oPanel = [NSOpenPanel openPanel];
int result;
[oPanel setAllowsMultipleSelection: YES];
[oPanel setCanChooseFiles: YES];
[oPanel setCanChooseDirectories: NO];
result = [oPanel runModalForDirectory: NSHomeDirectory()
file: nil
types: fileTypes];
if (result == NSOKButton)
{
NSArray *filesToOpen = [oPanel filenames];
unsigned count = [filesToOpen count];
unsigned i;
for (i = 0; i < count; i++)
{
NSString *aFile = [filesToOpen objectAtIndex: i];
[self loadPalette: aFile];
}
return self;
}
return nil;
}
- (NSPanel*) panel
{
return panel;
}
- (void) setCurrentPalette: (id)anObj
{
NSView *wv;
NSView *sv;
NSEnumerator *enumerator;
if (current >= 0)
{
/*
* Move the views in the drag view back to the content view of the
* window they originally came from.
*/
wv = [[[palettes objectAtIndex: current] originalWindow] contentView];
enumerator = [[dragView subviews] objectEnumerator];
while ((sv = [enumerator nextObject]) != nil)
{
RETAIN(sv);
[sv removeFromSuperview];
[wv addSubview: sv];
RELEASE(sv);
}
}
current = [anObj selectedColumn];
if (current >= 0 && current < [palettes count])
{
/*
* Move the views from their original window into our drag view.
* Resize our drag view to the right size fitrst.
*/
wv = [[[palettes objectAtIndex: current] originalWindow] contentView];
[dragView setFrameSize: [wv frame].size];
enumerator = [[wv subviews] objectEnumerator];
while ((sv = [enumerator nextObject]) != nil)
{
RETAIN(sv);
[sv removeFromSuperview];
[dragView addSubview: sv];
RELEASE(sv);
}
}
else
{
NSLog(@"Bad palette selection - %d", [anObj selectedColumn]);
current = -1;
}
[dragView setNeedsDisplay: YES];
}
@end

34
GormPrivate.h Normal file
View file

@ -0,0 +1,34 @@
#ifndef GORMPRIVATE_H
#define GORMPRIVATE_H
@class GormDocument;
@class GormInspectorsManager;
@class GormPalettesManager;
@class GormResourcesManager;
#include "Gorm.h"
#include "GormDocument.h"
#include "GormInspectorsManager.h"
#include "GormPalettesManager.h"
#include "GormResourcesManager.h"
@interface Gorm : NSApplication <IB>
{
id infoPanel;
GormInspectorsManager *inspectorsManager;
GormPalettesManager *palettesManager;
id<IBSelectionOwners> selectionOwner;
NSMutableArray *documents;
}
- (id<IBDocuments>) activeDocument;
- (GormInspectorsManager*) inspectorsManager;
- (id) makeNewDocument: (id) sender;
- (id) openPalette: (id) sender;
- (GormPalettesManager*) palettesManager;
- (id) runInfoPanel: (id) sender;
- (id) runGormInspectors: (id) sender;
- (id) runGormPalettes: (id) sender;
@end
#endif

22
GormResourcesManager.h Normal file
View file

@ -0,0 +1,22 @@
#ifndef GORMRESOURCESMANAGER_H
#define GORMRESOURCESMANAGER_H
@interface GormResourcesManager : NSObject
{
NSWindow *window;
NSMatrix *selectionView;
NSScrollView *scrollView;
id objectsView;
id<IBDocuments> document;
}
+ (GormResourcesManager*) newManagerForDocument: (id<IBDocuments>)doc;
- (void) addObject: (id)anObject;
- (void) changeView: (id)sender;
- (id<IBDocuments>) document;
- (void) removeObject: (id)anObject;
- (NSWindow*) window;
- (BOOL) windowShouldClose: (NSWindow*)aWindow;
- (void) windowWillClose: (NSNotification*)aNotification;
@end
#endif

535
GormResourcesManager.m Normal file
View file

@ -0,0 +1,535 @@
/* GormResourcesManager.m
*
* Copyright (C) 1999 Free Software Foundation, Inc.
*
* Author: Richard Frith-Macdonald <richard@brainstrom.co.uk>
* Date: 1999
*
* 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 "GormPrivate.h"
@interface GormObjectsView : NSMatrix
{
NSMutableArray *objects;
NSPoint mouseDownPoint;
BOOL shouldBeginDrag;
NSPasteboard *dragPb;
}
- (void) addObject: (id)anObject;
- (void) draggedImage: (NSImage*)i endedAt: (NSPoint)p deposited: (BOOL)f;
- (unsigned int) draggingSourceOperationMaskForLocal: (BOOL)flag;
- (void) refreshCells;
- (void) removeObject: (id)anObject;
@end
@implementation GormObjectsView
static NSImage *objectImage = nil;
static NSImage *windowImage = nil;
static NSImage *menuImage = nil;
static NSImage *firstImage = nil;
static NSImage *ownerImage = nil;
static NSImage *fontImage = nil;
static NSImage *dragImage = nil;
+ (void) initialize
{
if (self == [GormObjectsView class])
{
NSBundle *bundle;
NSString *path;
bundle = [NSBundle mainBundle];
path = [bundle pathForImageResource: @"GormLinkImage"];
if (path != nil)
{
dragImage = [[NSImage alloc] initWithContentsOfFile: path];
}
path = [bundle pathForImageResource: @"GormObject"];
if (path != nil)
{
objectImage = [[NSImage alloc] initWithContentsOfFile: path];
}
path = [bundle pathForImageResource: @"GormFilesOwner"];
if (path != nil)
{
ownerImage = [[NSImage alloc] initWithContentsOfFile: path];
}
path = [bundle pathForImageResource: @"GormFirstResponder"];
if (path != nil)
{
firstImage = [[NSImage alloc] initWithContentsOfFile: path];
}
path = [bundle pathForImageResource: @"GormFontManager"];
if (path != nil)
{
fontImage = [[NSImage alloc] initWithContentsOfFile: path];
}
path = [bundle pathForImageResource: @"GormMenu"];
if (path != nil)
{
menuImage = [[NSImage alloc] initWithContentsOfFile: path];
}
path = [bundle pathForImageResource: @"GormWindow"];
if (path != nil)
{
windowImage = [[NSImage alloc] initWithContentsOfFile: path];
}
}
}
- (void) addObject: (id)anObject
{
if ([objects indexOfObjectIdenticalTo: anObject] == NSNotFound)
{
[objects addObject: anObject];
[self refreshCells];
}
}
- (void) dealloc
{
RELEASE(objects);
[super dealloc];
}
/*
* Initialisation - register to receive DnD with our own types.
*/
- (id) initWithFrame: (NSRect)aFrame
{
self = [super initWithFrame: aFrame];
if (self != nil)
{
NSButtonCell *proto;
[self registerForDraggedTypes: [NSArray arrayWithObjects:
IBCellPboardType, IBMenuPboardType, IBMenuCellPboardType,
IBObjectPboardType, IBViewPboardType, IBWindowPboardType, nil]];
[self setAutosizesCells: NO];
[self setCellSize: NSMakeSize(72,72)];
[self setIntercellSpacing: NSMakeSize(8,8)];
[self setAutoresizingMask: NSViewMinYMargin|NSViewWidthSizable];
objects = [NSMutableArray new];
[objects addObject: ownerImage];
[objects addObject: firstImage];
proto = [NSButtonCell new];
[proto setBordered: NO];
[proto setAlignment: NSCenterTextAlignment];
[proto setImagePosition: NSImageAbove];
[self setPrototype: proto];
RELEASE(proto);
[self renewRows: 2 columns: 3];
[self refreshCells];
}
return self;
}
/*
* Dragging source protocol implementation
*/
- (void) draggedImage: (NSImage*)i endedAt: (NSPoint)p deposited: (BOOL)f
{
NSString *type = [[dragPb types] lastObject];
/*
* Windows are an exception to the normal DnD mechanism - we create them
* if they are dropped anywhere except back in the pallettes view -
* ie. if they are dragged, but the drop fails.
*/
if (f == NO && [type isEqual: IBWindowPboardType] == YES)
{
id<IBDocuments> active = [(id<IB>)NSApp activeDocument];
if (active != nil)
{
[active pasteType: type fromPasteboard: dragPb parent: nil];
}
}
}
- (unsigned int) draggingSourceOperationMaskForLocal: (BOOL)flag
{
return NSDragOperationCopy;
}
/*
* Dragging destination protocol implementation
*
* We actually don't handle anything being dropped on the palette,
* but we pretend to accept drops from ourself, so that the drag
* session quietly terminates - and it looks like the drop has
* been successful - this stops windows being created when they are
* dropped back on the palette (a window is normally created if the
* dnd drop is refused).
*/
- (unsigned) draggingEntered: (id<NSDraggingInfo>)sender
{
return NSDragOperationCopy;;
}
- (BOOL) performDragOperation: (id<NSDraggingInfo>)sender
{
return YES;
}
- (BOOL) prepareForDragOperation: (id<NSDraggingInfo>)sender
{
return YES;
}
/*
* Intercepting events in the view and handling them
*/
- (NSView*) hitTest: (NSPoint)loc
{
/*
* Stop the subviews receiving events - we grab them all.
*/
if ([super hitTest: loc] != nil)
return self;
return nil;
}
- (void) mouseDown: (NSEvent*)theEvent
{
NSView *view;
mouseDownPoint = [theEvent locationInWindow];
view = [super hitTest: mouseDownPoint];
if (view == self)
{
shouldBeginDrag = NO;
}
else
{
shouldBeginDrag = YES;
}
}
- (void) mouseDragged: (NSEvent*)theEvent
{
if (shouldBeginDrag == YES)
{
NSPoint dragPoint = [theEvent locationInWindow];
NSView *view = [super hitTest: mouseDownPoint];
GormDocument *active = [(id<IB>)NSApp activeDocument];
NSRect rect = [view frame];
NSString *type;
id obj;
NSPasteboard *pb;
NSImageRep *rep;
NSSize offset;
offset.width = mouseDownPoint.x - dragPoint.x;
offset.height = mouseDownPoint.y - dragPoint.y;
RELEASE(dragImage);
dragImage = [NSImage new];
rep = [[NSCachedImageRep alloc] initWithWindow: [self window]
rect: rect];
[dragImage setSize: rect.size];
[dragImage addRepresentation: rep];
type = [IBPalette typeForView: view];
obj = [IBPalette objectForView: view];
pb = [NSPasteboard pasteboardWithName: NSDragPboard];
ASSIGN(dragPb, pb);
[active copyObject: obj type: type toPasteboard: pb];
[self dragImage: dragImage
at: rect.origin
offset: offset
event: theEvent
pasteboard: pb
source: self
slideBack: [type isEqual: IBWindowPboardType] ? NO : YES];
}
}
- (void) refreshCells
{
unsigned count = [objects count];
unsigned index;
int cols = 0;
int rows;
int width;
id<IBDocuments> document;
document = [(id<IB>)NSApp activeDocument];
width = [[self superview] bounds].size.width;
while (width >= 72)
{
width -= (72 + 8);
cols++;
}
if (cols == 0)
{
cols = 1;
}
rows = count / cols;
if (rows == 0 || rows * cols != count)
{
rows++;
}
[self renewRows: rows columns: cols];
for (index = 0; index < count; index++)
{
id obj = [objects objectAtIndex: index];
NSButtonCell *but = [self cellAtRow: index/cols column: index%cols];
if (obj == ownerImage)
{
[but setImage: obj];
[but setTitle: @"File's Owner"];
}
else if (obj == firstImage)
{
[but setImage: obj];
[but setTitle: @"1st Responder"];
}
else if (obj == fontImage)
{
[but setImage: obj];
[but setTitle: @"Font Manager"];
}
else if ([obj isKindOfClass: [NSWindow class]])
{
[but setImage: windowImage];
[but setTitle: [document nameForObject: obj]];
}
else if ([obj isKindOfClass: [NSMenu class]])
{
[but setImage: menuImage];
[but setTitle: [document nameForObject: obj]];
}
else
{
[but setImage: objectImage];
[but setTitle: [document nameForObject: obj]];
}
}
while (index < rows * cols)
{
NSButtonCell *but = [self cellAtRow: index/cols column: index%cols];
[but setImage: nil];
[but setTitle: nil];
index++;
}
[self setIntercellSpacing: NSMakeSize(8,8)];
[self sizeToCells];
[self setNeedsDisplay: YES];
}
- (void) removeObject: (id)anObject
{
unsigned pos;
pos = [objects indexOfObjectIdenticalTo: anObject];
if (pos == NSNotFound)
{
return;
}
if (anObject == ownerImage || anObject == firstImage)
{
return;
}
[objects removeObjectAtIndex: pos];
[self refreshCells];
}
- (void) resizeWithOldSuperviewSize: (NSSize)oldSize
{
[self refreshCells];
}
@end
@implementation GormResourcesManager
+ (GormResourcesManager*) newManagerForDocument: (id<IBDocuments>)doc
{
GormResourcesManager *mgr;
mgr = [[self alloc] init];
mgr->document = doc;
return mgr;
}
- (void) addObject: (id)anObject
{
[objectsView addObject: anObject];
}
- (void) dealloc
{
[window performClose: self];
RELEASE(window);
RELEASE(objectsView);
[super dealloc];
}
- (id<IBDocuments>) document
{
return document;
}
- (id) init
{
self = [super init];
if (self != nil)
{
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
NSRect winrect = NSMakeRect(100,100,340,252);
NSRect selectionRect = {{0, 188}, {240, 64}};
NSRect scrollRect = {{0, 0}, {340, 188}};
NSRect mainRect = {{20, 0}, {320, 188}};
NSBundle *bundle;
NSString *path;
NSImage *image;
NSButtonCell *cell;
unsigned style = NSTitledWindowMask | NSClosableWindowMask
| NSResizableWindowMask | NSMiniaturizableWindowMask;
window = [[NSWindow alloc] initWithContentRect: winrect
styleMask: style
backing: NSBackingStoreRetained
defer: NO];
[window setDelegate: self];
[window setMinSize: [window frame].size];
[window setTitle: @"UNTITLED"];
[nc addObserver: self
selector: @selector(windowWillClose:)
name: NSWindowWillCloseNotification
object: window];
selectionView = [[NSMatrix alloc] initWithFrame: selectionRect
mode: NSRadioModeMatrix
cellClass: [NSButtonCell class]
numberOfRows: 1
numberOfColumns: 4];
[selectionView setTarget: self];
[selectionView setAction: @selector(changeView:)];
[selectionView setAutosizesCells: NO];
[selectionView setCellSize: NSMakeSize(64,64)];
[selectionView setIntercellSpacing: NSMakeSize(28,0)];
[selectionView setAutoresizingMask: NSViewMinYMargin|NSViewWidthSizable];
bundle = [NSBundle mainBundle];
path = [bundle pathForImageResource: @"GormObject"];
if (path != nil)
{
image = [[NSImage alloc] initWithContentsOfFile: path];
cell = [selectionView cellAtRow: 0 column: 0];
[cell setImage: image];
RELEASE(image);
[cell setTitle: @"Objects"];
[cell setBordered: NO];
[cell setAlignment: NSCenterTextAlignment];
[cell setImagePosition: NSImageAbove];
}
path = [bundle pathForImageResource: @"GormImage"];
if (path != nil)
{
image = [[NSImage alloc] initWithContentsOfFile: path];
cell = [selectionView cellAtRow: 0 column: 1];
[cell setImage: image];
RELEASE(image);
[cell setTitle: @"Images"];
[cell setBordered: NO];
[cell setAlignment: NSCenterTextAlignment];
[cell setImagePosition: NSImageAbove];
}
path = [bundle pathForImageResource: @"GormSound"];
if (path != nil)
{
image = [[NSImage alloc] initWithContentsOfFile: path];
cell = [selectionView cellAtRow: 0 column: 2];
[cell setImage: image];
RELEASE(image);
[cell setTitle: @"Sounds"];
[cell setBordered: NO];
[cell setAlignment: NSCenterTextAlignment];
[cell setImagePosition: NSImageAbove];
}
path = [bundle pathForImageResource: @"GormClass"];
if (path != nil)
{
image = [[NSImage alloc] initWithContentsOfFile: path];
cell = [selectionView cellAtRow: 0 column: 3];
[cell setImage: image];
RELEASE(image);
[cell setTitle: @"Classes"];
[cell setBordered: NO];
[cell setAlignment: NSCenterTextAlignment];
[cell setImagePosition: NSImageAbove];
}
[[window contentView] addSubview: selectionView];
RELEASE(selectionView);
scrollView = [[NSScrollView alloc] initWithFrame: scrollRect];
[scrollView setHasVerticalScroller: YES];
[scrollView setHasHorizontalScroller: NO];
[scrollView setAutoresizingMask: NSViewHeightSizable|NSViewWidthSizable];
[[window contentView] addSubview: scrollView];
RELEASE(scrollView);
mainRect.origin = NSMakePoint(0,0);
mainRect.size = [scrollView contentSize];
objectsView = [[GormObjectsView alloc] initWithFrame: mainRect];
[objectsView setAutoresizingMask: NSViewHeightSizable|NSViewWidthSizable];
[scrollView setDocumentView: objectsView];
}
return self;
}
- (void) removeObject: (id)anObject
{
[objectsView removeObject: anObject];
}
- (NSWindow*) window
{
return window;
}
- (BOOL) windowShouldClose: (NSWindow*)aWindow
{
return [document documentShouldClose];
}
- (void) windowWillClose: (NSNotification*)aNotification
{
[document documentWillClose];
}
@end

83
IBInspector.m Normal file
View file

@ -0,0 +1,83 @@
/* IBInspector.m
*
* Copyright (C) 1999 Free Software Foundation, Inc.
*
* Author: Richard Frith-Macdonald <richard@brainstrom.co.uk>
* Date: 1999
*
* 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 "Gorm.h"
NSString *IBInspectorDidModifyObjectNotification
= @"IBInspectorDidModifyObjectNotification";
NSString *IBSelectionChangedNotification
= @"IBSelectionChangedNotification";
@implementation IBInspector
- (void) dealloc
{
[super dealloc];
}
- (id) init
{
return self;
}
- (id) object
{
return object;
}
- (void) ok: sender
{
}
- (NSButton*) okButton
{
return okButton;
}
- (void) revert: (id)sender
{
}
- (NSButton*) revertButton
{
return revertButton;
}
- (void) touch: (id)sender
{
[window setDocumentEdited];
}
- (BOOL) wantsButtons
{
return NO;
}
- (NSWindow*) window
{
return window;
}
@end

139
IBPalette.m Normal file
View file

@ -0,0 +1,139 @@
/* IBPalette.m
*
* Copyright (C) 1999 Free Software Foundation, Inc.
*
* Author: Richard Frith-Macdonald <richard@brainstrom.co.uk>
* Date: 1999
*
* 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 "Gorm.h"
NSString *IBCellPboardType = @"IBCellPboardType";
NSString *IBMenuPboardType = @"IBMenuPboardType";
NSString *IBMenuCellPboardType = @"IBMenuCellPboardType";
NSString *IBObjectPboardType = @"IBObjectPboardType";
NSString *IBViewPboardType = @"IBViewPboardType";
NSString *IBWindowPboardType = @"IBWindowPboardType";
@implementation IBPalette
static NSMapTable *viewToObject = 0;
static NSMapTable *viewToType = 0;
+ (void) initialize
{
if (self == [IBPalette class])
{
viewToObject = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
NSObjectMapValueCallBacks, 20);
viewToType = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
NSObjectMapValueCallBacks, 20);
}
}
+ (id) objectForView: (NSView*)aView
{
id obj = (id)NSMapGet(viewToObject, (void*)aView);
if (obj == nil)
{
obj = aView;
}
return obj;
}
+ (NSString*) typeForView: (NSView*)aView
{
NSString *type = (NSString*)NSMapGet(viewToType, (void*)aView);
if (type == nil)
{
type = IBViewPboardType;
}
return type;
}
- (void) associateObject: (id)anObject
type: (NSString*)aType
with: (NSView*)aView
{
NSMapInsert(viewToType, (void*)aView, (id)aType);
NSMapInsert(viewToObject, (void*)aView, (id)anObject);
}
- (void) dealloc
{
RELEASE(icon);
RELEASE(window);
[super dealloc];
}
- (void) finishInstantiate
{
}
- (id) init
{
NSBundle *bundle;
NSDictionary *paletteInfo;
NSString *fileName;
bundle = [NSBundle bundleForClass: [self class]];
fileName = [bundle pathForResource: @"palette" ofType: @"table"];
paletteInfo = [[NSString stringWithContentsOfFile: fileName]
propertyListFromStringsFileFormat];
fileName = [paletteInfo objectForKey: @"Icon"];
fileName = [bundle pathForImageResource: fileName];
if (fileName == nil)
{
NSRunAlertPanel(NULL, @"Icon for palette is missing",
@"OK", NULL, NULL);
AUTORELEASE(self);
return nil;
}
icon = [[NSImage alloc] initWithContentsOfFile: fileName];
fileName = [paletteInfo objectForKey: @"NibFile"];
if (fileName != nil && [fileName isEqual: @""] == NO)
{
if ([NSBundle loadNibNamed: fileName owner: self] == NO)
{
NSRunAlertPanel(NULL, @"Nib for palette would not load",
@"OK", NULL, NULL);
AUTORELEASE(self);
return nil;
}
}
return self;
}
- (NSImage*) paletteIcon
{
return icon;
}
- (NSWindow*) originalWindow
{
return window;
}
@end

23
Implementation Normal file
View file

@ -0,0 +1,23 @@
Notes on implementation
=======================
The IB documentation on how object selection is managed and how editors and
inspectors are used is unclear ... so I've gone my own way.
1. When a document is loaded, the document object creates an editor attached
to each top-level object in the user interface (NSMenu and NSWindow objects).
These editors must be aware of their edited objects being clicked upon, and
clicking on one of these should cause the corresponding editor to become the
active editor.
The active editor is responsible for handling selection of the edited object
(and any objects below it in the object hierarchy). Upon change of selection,
the editor is responsible for sending an IBSelectionChangedNotification with
the selection owner (normally the editor itsself) as the notification owner.
The main application watches for these notifications in order to keep track
of who has the selection.

104
InfoPanel.m Normal file
View file

@ -0,0 +1,104 @@
/* InfoPanel.m
*
* Copyright (C) 1999 Free Software Foundation, Inc.
*
* Author: Richard Frith-Macdonald <richard@brainstrom.co.uk>
* Date: 1999
*
* 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 <Foundation/Foundation.h>
#include <AppKit/AppKit.h>
@interface InfoPanel : NSPanel
{
NSTextField *versionfield;
NSTextField *authorfield;
NSTextField *addressfield;
}
@end
@implementation InfoPanel
- (id) init
{
NSRect contentRect = {{0, 0}, {380, 120}};
NSRect versionRect = {{30, 75}, {320, 20}};
NSRect authorRect = {{30, 50}, {320, 20}};
NSRect addressRect = {{30, 25}, {320, 20}};
NSFont *font;
unsigned int style = NSTitledWindowMask | NSClosableWindowMask;
self = [super initWithContentRect: contentRect
styleMask: style
backing: NSBackingStoreRetained
defer: NO];
if (self != nil)
{
[self setTitle: @"Info"];
font = [NSFont systemFontOfSize: 10];
versionfield = [[NSTextField alloc] init];
[versionfield setFrame: versionRect];
[versionfield setFont: font];
[versionfield setBezeled: NO];
[versionfield setEditable: NO];
[versionfield setSelectable: NO];
[versionfield setAlignment: NSCenterTextAlignment];
[versionfield setBackgroundColor: [NSColor lightGrayColor]];
[versionfield setStringValue:
@"GNUstep Graphicsl Object Relationship Modeller v0.0 1999"];
[[self contentView] addSubview: versionfield];
authorfield = [[NSTextField alloc] init];
[authorfield setFrame: authorRect];
[authorfield setFont: font];
[authorfield setBezeled: NO];
[authorfield setEditable: NO];
[authorfield setSelectable: NO];
[authorfield setAlignment: NSCenterTextAlignment];
[authorfield setBackgroundColor: [NSColor lightGrayColor]];
[authorfield setStringValue: @"by Richard Frith-Macdonald"];
[[self contentView] addSubview: authorfield];
addressfield = [[NSTextField alloc] init];
[addressfield setFrame: addressRect];
[addressfield setFont: font];
[addressfield setBezeled: NO];
[addressfield setEditable: NO];
[addressfield setSelectable: NO];
[addressfield setAlignment: NSCenterTextAlignment];
[addressfield setBackgroundColor: [NSColor lightGrayColor]];
[addressfield setStringValue: @"http://www.gnustep.org"];
[[self contentView] addSubview: addressfield];
[self center];
[self setFrameUsingName: @"Info"];
[self setFrameAutosaveName: @"Info"];
}
return self;
}
- (void) dealloc
{
[versionfield release];
[authorfield release];
[addressfield release];
[super dealloc];
}
@end