mirror of
https://github.com/gnustep/apps-gorm.git
synced 2025-04-22 22:20:44 +00:00
Better inspector support
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/apps/gorm/trunk@5593 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
e40f8fce22
commit
40df44a9ee
6 changed files with 439 additions and 1 deletions
8
Gorm.h
8
Gorm.h
|
@ -273,6 +273,9 @@ extern NSString *IBDidEndTestingInterfaceNotification;
|
|||
NSButton *okButton;
|
||||
NSButton *revertButton;
|
||||
}
|
||||
|
||||
- (NSView*) initialFirstResponder;
|
||||
|
||||
/*
|
||||
* The object being inspected.
|
||||
*/
|
||||
|
@ -306,6 +309,11 @@ extern NSString *IBDidEndTestingInterfaceNotification;
|
|||
*/
|
||||
- (void) setObject: (id)anObject;
|
||||
|
||||
/*
|
||||
* Used to take notice of textfields in inspector being updated.
|
||||
*/
|
||||
- (void) textDidBeginEditing: (NSNotification*)aNotification;
|
||||
|
||||
/*
|
||||
* Method to mark the inspector as needing saving (ok or revert).
|
||||
*/
|
||||
|
|
|
@ -5,11 +5,17 @@
|
|||
{
|
||||
NSMutableDictionary *classInformation;
|
||||
}
|
||||
- (void) addAction: (NSString*)anAction forObject: (NSObject*)anObject;
|
||||
- (void) addOutlet: (NSString*)anOutlet forObject: (NSObject*)anObject;
|
||||
- (NSArray*) allActionsForClassNamed: (NSString*)className;
|
||||
- (NSArray*) allActionsForObject: (NSObject*)anObject;
|
||||
- (NSArray*) allClassNames;
|
||||
- (NSArray*) allOutletsForClassNamed: (NSString*)className;
|
||||
- (NSArray*) allOutletsForObject: (NSObject*)anObject;
|
||||
- (NSArray*) extraActionsForObject: (NSObject*)anObject;
|
||||
- (NSArray*) extraOutletsForObject: (NSObject*)anObject;
|
||||
- (void) removeAction: (NSString*)anAction forObject: (NSObject*)anObject;
|
||||
- (void) removeOutlet: (NSString*)anOutlet forObject: (NSObject*)anObject;
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,8 +24,56 @@
|
|||
|
||||
#include "GormPrivate.h"
|
||||
|
||||
@interface GormClassManager (Private)
|
||||
- (NSMutableDictionary*) classInfoForClassName: (NSString*)className;
|
||||
- (NSMutableDictionary*) classInfoForObject: (NSObject*)anObject;
|
||||
@end
|
||||
|
||||
@implementation GormClassManager
|
||||
|
||||
- (void) addAction: (NSString*)anAction forObject: (id)anObject
|
||||
{
|
||||
NSMutableDictionary *info = [self classInfoForObject: anObject];
|
||||
NSMutableArray *extraActions = [info objectForKey: @"ExtraActions"];
|
||||
NSMutableArray *allActions = [self allActionsForObject: anObject];
|
||||
|
||||
if ([extraActions containsObject: anAction] == YES)
|
||||
{
|
||||
return; /* Can't add action twice. */
|
||||
}
|
||||
if (extraActions == nil)
|
||||
{
|
||||
extraActions = [[NSMutableArray alloc] initWithCapacity: 1];
|
||||
[info setObject: extraActions forKey: @"ExtraActions"];
|
||||
RELEASE(extraActions);
|
||||
}
|
||||
[extraActions addObject: anAction];
|
||||
if ([allActions containsObject: anAction] == NO)
|
||||
{
|
||||
[[info objectForKey: @"AllActions"] addObject: anAction];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) addOutlet: (NSString*)anOutlet forObject: (id)anObject
|
||||
{
|
||||
NSMutableDictionary *info = [self classInfoForObject: anObject];
|
||||
NSMutableArray *extraOutlets = [info objectForKey: @"ExtraOutlets"];
|
||||
NSArray *allOutlets = [self allOutletsForObject: anObject];
|
||||
|
||||
if ([allOutlets containsObject: anOutlet] == YES)
|
||||
{
|
||||
return; /* Can't add outlet with same name. */
|
||||
}
|
||||
if (extraOutlets == nil)
|
||||
{
|
||||
extraOutlets = [[NSMutableArray alloc] initWithCapacity: 1];
|
||||
[info setObject: extraOutlets forKey: @"ExtraOutlets"];
|
||||
RELEASE(extraOutlets);
|
||||
}
|
||||
[extraOutlets addObject: anOutlet];
|
||||
[[info objectForKey: @"AllOutlets"] addObject: anOutlet];
|
||||
}
|
||||
|
||||
- (NSArray*) allActionsForObject: (NSObject*)obj
|
||||
{
|
||||
NSString *className;
|
||||
|
@ -223,12 +271,86 @@
|
|||
return nil;
|
||||
}
|
||||
|
||||
- (NSMutableDictionary*) classInfoForClassName: (NSString*)className
|
||||
{
|
||||
NSMutableDictionary *info;
|
||||
|
||||
info = [classInformation objectForKey: className];
|
||||
if (info == nil)
|
||||
{
|
||||
Class theClass = NSClassFromString(className);
|
||||
|
||||
if (theClass != nil)
|
||||
{
|
||||
theClass = class_get_super_class(theClass);
|
||||
if (theClass != nil && theClass != [NSObject class])
|
||||
{
|
||||
NSString *name;
|
||||
NSMutableDictionary *dict;
|
||||
|
||||
name = NSStringFromClass(theClass);
|
||||
dict = [self classInfoForClassName: name];
|
||||
if (dict != nil)
|
||||
{
|
||||
id o;
|
||||
|
||||
info = [[NSMutableDictionary alloc] initWithCapacity: 3];
|
||||
[info setObject: name forKey: @"Super"];
|
||||
o = [[self allActionsForClassNamed: name] mutableCopy];
|
||||
[info setObject: o forKey: @"AllActions"];
|
||||
o = [[self allOutletsForClassNamed: name] mutableCopy];
|
||||
[info setObject: o forKey: @"AllOutlets"];
|
||||
[classInformation setObject: info forKey: className];
|
||||
RELEASE(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
- (NSMutableDictionary*) classInfoForObject: (NSObject*)obj
|
||||
{
|
||||
NSString *className;
|
||||
Class theClass = [obj class];
|
||||
|
||||
if (theClass == [GormFilesOwner class])
|
||||
{
|
||||
className = [(GormFilesOwner*)obj className];
|
||||
}
|
||||
else
|
||||
{
|
||||
className = NSStringFromClass(theClass);
|
||||
}
|
||||
|
||||
if (className == nil)
|
||||
{
|
||||
NSLog(@"attempt to get outlets for non-existent class");
|
||||
return nil;
|
||||
}
|
||||
return [self classInfoForClassName: className];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE(classInformation);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSArray*) extraActionsForObject: (NSObject*)anObject
|
||||
{
|
||||
NSMutableDictionary *info = [self classInfoForObject: anObject];
|
||||
|
||||
return [info objectForKey: @"ExtraActions"];
|
||||
}
|
||||
|
||||
- (NSArray*) extraOutletsForObject: (NSObject*)anObject
|
||||
{
|
||||
NSMutableDictionary *info = [self classInfoForObject: anObject];
|
||||
|
||||
return [info objectForKey: @"ExtraOutlets"];
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
self = [super init];
|
||||
|
@ -292,6 +414,295 @@
|
|||
return self;
|
||||
}
|
||||
|
||||
- (void) removeAction: (NSString*)anAction forObject: (id)anObject
|
||||
{
|
||||
NSMutableDictionary *info = [self classInfoForObject: anObject];
|
||||
NSMutableArray *extraActions = [info objectForKey: @"ExtraActions"];
|
||||
|
||||
if ([extraActions containsObject: anAction] == YES)
|
||||
{
|
||||
NSString *superName = [info objectForKey: @"Super"];
|
||||
|
||||
if (superName != nil)
|
||||
{
|
||||
NSArray *superActions;
|
||||
|
||||
/*
|
||||
* If this action is new in this class (ie not overriding an
|
||||
* action in a parent) then we remove it from the list of all
|
||||
* actions that the object responds to.
|
||||
*/
|
||||
superActions = [self allActionsForClassNamed: superName];
|
||||
if ([superActions containsObject: anAction] == NO)
|
||||
{
|
||||
NSMutableArray *array = [info objectForKey: @"AllActions"];
|
||||
|
||||
[array removeObject: anAction];
|
||||
}
|
||||
}
|
||||
[extraActions removeObject: anAction];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) removeOutlet: (NSString*)anOutlet forObject: (id)anObject
|
||||
{
|
||||
NSMutableDictionary *info = [self classInfoForObject: anObject];
|
||||
NSMutableArray *extraOutlets = [info objectForKey: @"ExtraOutlets"];
|
||||
|
||||
if ([extraOutlets containsObject: anOutlet] == YES)
|
||||
{
|
||||
NSMutableArray *allOutlets = [info objectForKey: @"AllOutlets"];
|
||||
|
||||
[allOutlets removeObject: anOutlet];
|
||||
[extraOutlets removeObject: anOutlet];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface GormClassInspector : IBInspector
|
||||
{
|
||||
NSArray *actions;
|
||||
NSArray *outlets;
|
||||
NSBrowser *browser;
|
||||
BOOL editClass;
|
||||
BOOL editActions;
|
||||
}
|
||||
- (void) updateButtons;
|
||||
@end
|
||||
|
||||
@implementation GormClassInspector
|
||||
|
||||
- (int) browser: (NSBrowser*)sender numberOfRowsInColumn: (int)column
|
||||
{
|
||||
if (column == 0)
|
||||
{
|
||||
return [outlets count];
|
||||
}
|
||||
else
|
||||
{
|
||||
return [actions count];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) browser: (NSBrowser*)sender
|
||||
selectCellWithString: (NSString*)title
|
||||
inColumn: (int)col
|
||||
{
|
||||
if (col == 0)
|
||||
{
|
||||
}
|
||||
[self updateButtons];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) browser: (NSBrowser*)sender
|
||||
willDisplayCell: (id)aCell
|
||||
atRow: (int)row
|
||||
column: (int)col
|
||||
{
|
||||
NSString *name;
|
||||
|
||||
if (col == 0)
|
||||
{
|
||||
if (row >= 0 && row < [outlets count])
|
||||
{
|
||||
name = [outlets objectAtIndex: row];
|
||||
[aCell setStringValue: name];
|
||||
[aCell setEnabled: YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
[aCell setStringValue: @""];
|
||||
[aCell setEnabled: NO];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (row >= 0 && row < [actions count])
|
||||
{
|
||||
name = [actions objectAtIndex: row];
|
||||
[aCell setStringValue: name];
|
||||
[aCell setEnabled: YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
[aCell setStringValue: @""];
|
||||
[aCell setEnabled: NO];
|
||||
}
|
||||
}
|
||||
[aCell setLeaf: YES];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE(actions);
|
||||
RELEASE(outlets);
|
||||
RELEASE(okButton);
|
||||
RELEASE(revertButton);
|
||||
RELEASE(window);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
self = [super init];
|
||||
if (self != nil)
|
||||
{
|
||||
NSView *contents;
|
||||
NSRect windowRect = NSMakeRect(0, 0, IVW, IVH-IVB);
|
||||
NSRect rect;
|
||||
NSButtonCell *cell;
|
||||
NSTextField *text;
|
||||
NSMatrix *matrix;
|
||||
|
||||
window = [[NSWindow alloc] initWithContentRect: windowRect
|
||||
styleMask: NSBorderlessWindowMask
|
||||
backing: NSBackingStoreRetained
|
||||
defer: NO];
|
||||
contents = [window contentView];
|
||||
|
||||
rect = windowRect;
|
||||
rect.origin.y += rect.size.height - 22;
|
||||
rect.size.height = 22;
|
||||
|
||||
text = [[NSTextField alloc] initWithFrame: rect];
|
||||
[contents addSubview: text];
|
||||
RELEASE(text);
|
||||
|
||||
cell = [[NSButtonCell alloc] init];
|
||||
[cell setButtonType: NSRadioButton];
|
||||
[cell setBordered: NO];
|
||||
[cell setImagePosition: NSImageLeft];
|
||||
|
||||
rect.origin.y -= 22;
|
||||
rect.size.height = 20;
|
||||
matrix = [[NSMatrix alloc] initWithFrame: rect
|
||||
mode: NSRadioModeMatrix
|
||||
prototype: cell
|
||||
numberOfRows: 1
|
||||
numberOfColumns: 2];
|
||||
RELEASE(cell);
|
||||
|
||||
rect.size.width /= 2;
|
||||
[matrix setIntercellSpacing: NSZeroSize];
|
||||
[matrix setCellSize: rect.size];
|
||||
[matrix setTarget: self];
|
||||
[matrix setAutosizesCells: YES];
|
||||
|
||||
cell = [matrix cellAtRow: 0 column: 0];
|
||||
[cell setTitle: @"Outlets"];
|
||||
[cell setAction: @selector(setOutlets:)];
|
||||
|
||||
cell = [matrix cellAtRow: 0 column: 1];
|
||||
[cell setTitle: @"Actions"];
|
||||
[cell setAction: @selector(setActions:)];
|
||||
|
||||
[matrix selectCellAtRow: 0 column: 0];
|
||||
[matrix setAutoresizingMask: (NSViewMinYMargin | NSViewWidthSizable)];
|
||||
[contents addSubview: matrix];
|
||||
RELEASE(matrix);
|
||||
|
||||
rect = windowRect;
|
||||
rect.size.height -= 70;
|
||||
rect.origin.y += 25;
|
||||
|
||||
browser = [[NSBrowser alloc] initWithFrame: rect];
|
||||
[browser setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable];
|
||||
[browser setMaxVisibleColumns: 2];
|
||||
[browser setAllowsMultipleSelection: NO];
|
||||
[browser setHasHorizontalScroller: NO];
|
||||
[browser setTitled: NO];
|
||||
[browser setDelegate: self];
|
||||
|
||||
[contents addSubview: browser];
|
||||
RELEASE(browser);
|
||||
|
||||
rect = windowRect;
|
||||
rect.size.height = 22;
|
||||
rect.origin.y = 0;
|
||||
text = [[NSTextField alloc] initWithFrame: rect];
|
||||
[contents addSubview: text];
|
||||
RELEASE(text);
|
||||
|
||||
okButton = [[NSButton alloc] initWithFrame: NSMakeRect(0,0,90,20)];
|
||||
[okButton setAutoresizingMask: NSViewMaxYMargin | NSViewMinXMargin];
|
||||
[okButton setAction: @selector(ok:)];
|
||||
[okButton setTarget: self];
|
||||
[okButton setTitle: @"Add"];
|
||||
[okButton setEnabled: NO];
|
||||
|
||||
revertButton = [[NSButton alloc] initWithFrame: NSMakeRect(0,0,90,20)];
|
||||
[revertButton setAutoresizingMask: NSViewMaxYMargin | NSViewMinXMargin];
|
||||
[revertButton setAction: @selector(revert:)];
|
||||
[revertButton setTarget: self];
|
||||
[revertButton setTitle: @"Revert"];
|
||||
[revertButton setEnabled: NO];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) ok: (id)sender
|
||||
{
|
||||
}
|
||||
|
||||
- (id) setActions: (id)sender
|
||||
{
|
||||
if (editActions == NO)
|
||||
{
|
||||
editActions = YES;
|
||||
[self updateButtons];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) setObject: (id)anObject
|
||||
{
|
||||
if (anObject != nil && anObject != object)
|
||||
{
|
||||
ASSIGN(object, anObject);
|
||||
ASSIGN(actions, [[NSApp classManager] allActionsForObject: object]);
|
||||
ASSIGN(outlets, [[NSApp classManager] allOutletsForObject: object]);
|
||||
|
||||
[browser loadColumnZero];
|
||||
[browser reloadColumn: 1];
|
||||
[self updateButtons];
|
||||
}
|
||||
}
|
||||
|
||||
- (id) setOutlets: (id)sender
|
||||
{
|
||||
if (editActions == YES)
|
||||
{
|
||||
editActions = NO;
|
||||
[self updateButtons];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) updateButtons
|
||||
{
|
||||
if (editClass == YES)
|
||||
{
|
||||
[okButton setTitle: @"Rename Class"];
|
||||
[revertButton setTitle: @"Add Class"];
|
||||
}
|
||||
else if (editActions == YES)
|
||||
{
|
||||
[okButton setTitle: @"Rename Action"];
|
||||
[revertButton setTitle: @"Add Action"];
|
||||
}
|
||||
else
|
||||
{
|
||||
[okButton setTitle: @"Rename Outlet"];
|
||||
[revertButton setTitle: @"Add Outlet"];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) wantsButtons
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
@end
|
||||
|
||||
|
|
|
@ -43,6 +43,10 @@ NSString *IBWillCloseDocumentNotification = @"IBWillCloseDocumentNotification";
|
|||
}
|
||||
return image;
|
||||
}
|
||||
- (NSString*) inspectorClassName
|
||||
{
|
||||
return @"GormClassInspector";
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation GormFontManager
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
}
|
||||
- (NSString*) classInspectorClassName
|
||||
{
|
||||
return @"GormObjectInspector";
|
||||
return @"GormClassInspector";
|
||||
}
|
||||
- (NSString*) editorClassName
|
||||
{
|
||||
|
|
|
@ -38,6 +38,11 @@ NSString *IBSelectionChangedNotification
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSView*) initialFirstResponder
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (id) object
|
||||
{
|
||||
return object;
|
||||
|
@ -66,6 +71,10 @@ NSString *IBSelectionChangedNotification
|
|||
ASSIGN(object, anObject);
|
||||
}
|
||||
|
||||
- (void) textDidBeginEditing: (NSNotification*)aNotification
|
||||
{
|
||||
}
|
||||
|
||||
- (void) touch: (id)sender
|
||||
{
|
||||
[window setDocumentEdited: YES];
|
||||
|
|
Loading…
Reference in a new issue