mirror of
https://github.com/gnustep/apps-gorm.git
synced 2025-02-23 11:41:05 +00:00
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:
commit
b24b1706c8
18 changed files with 3161 additions and 0 deletions
6
ChangeLog
Normal file
6
ChangeLog
Normal 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
82
GNUmakefile
Normal 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
205
Gorm.h
Normal 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
324
Gorm.m
Normal 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
51
GormDocument.h
Normal 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
722
GormDocument.m
Normal 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
133
GormEditors.m
Normal 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
19
GormInspectorsManager.h
Normal 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
225
GormInspectorsManager.m
Normal 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
20
GormPalettesManager.h
Normal 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
434
GormPalettesManager.m
Normal 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
34
GormPrivate.h
Normal 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
22
GormResourcesManager.h
Normal 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
535
GormResourcesManager.m
Normal 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
83
IBInspector.m
Normal 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
139
IBPalette.m
Normal 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
23
Implementation
Normal 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
104
InfoPanel.m
Normal 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
|
Loading…
Reference in a new issue