/* GormInspectorsManager.m * * Copyright (C) 1999 Free Software Foundation, Inc. * * Author: Richard Frith-Macdonald * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. */ #include #include #include #include #include #include #include "GormPrivate.h" #include "GormImage.h" #include "GormSound.h" #define NUM_DEFAULT_INSPECTORS 5 @interface GormDummyInspector : IBInspector { NSButton *button; } - (NSString *)title; @end @implementation GormDummyInspector - (id) init { self = [super init]; if (self != nil) { if([NSBundle loadNibNamed: @"GormDummyInspector" owner: self]) { [button setStringValue: [self title]]; } } return self; } - (NSString *)title { return nil; } @end; /* * The GormEmptyInspector is a placeholder for an empty selection. */ @interface GormEmptyInspector : GormDummyInspector @end @implementation GormEmptyInspector - (NSString *)title { return _(@"Empty Selection"); } @end /* * The GormMultipleInspector is a placeholder for a multiple selection. */ @interface GormMultipleInspector : GormDummyInspector @end @implementation GormMultipleInspector - (NSString *)title { return _(@"Multiple Selection"); } @end /* * The GormNotApplicableInspector is a uitility for odd objects. */ @interface GormNotApplicableInspector : GormDummyInspector @end @implementation GormNotApplicableInspector - (NSString *)title { return _(@"Not Applicable"); } @end @implementation GormInspectorsManager - (void) dealloc { [[NSNotificationCenter defaultCenter] removeObserver: self]; RELEASE(oldInspector); RELEASE(cache); RELEASE(panel); [super dealloc]; } - (void) handleNotification: (NSNotification*)aNotification { NSString *name = [aNotification name]; if ([name isEqual: IBWillBeginTestingInterfaceNotification] == YES) { if ([panel isVisible] == YES) { hiddenDuringTest = YES; [panel orderOut: self]; } } else if ([name isEqual: IBWillEndTestingInterfaceNotification] == YES) { if (hiddenDuringTest == YES) { hiddenDuringTest = NO; [panel orderFront: self]; } } } - (id) init { if((self = [super init]) != nil) { NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; if([NSBundle loadNibNamed: @"GormInspectorPanel" owner: self]) { // initialized the cache... cache = [[NSMutableDictionary alloc] init]; // set the name under which this panel saves it's dimensions. [panel setFrameUsingName: @"Inspector"]; [panel setFrameAutosaveName: @"Inspector"]; // reset current tag indicator. current = -1; inspector = [[GormEmptyInspector alloc] init]; [cache setObject: inspector forKey: @"GormEmptyInspector"]; RELEASE(inspector); inspector = [[GormMultipleInspector alloc] init]; [cache setObject: inspector forKey: @"GormMultipleInspector"]; DESTROY(inspector); [self setCurrentInspector: 0]; [nc addObserver: self selector: @selector(handleNotification:) name: IBWillBeginTestingInterfaceNotification object: nil]; [nc addObserver: self selector: @selector(handleNotification:) name: IBWillEndTestingInterfaceNotification object: nil]; } } return self; } - (NSPanel*) panel { return panel; } - (void) updateSelection { if ([NSApp isConnecting] == YES) { [popup selectItemAtIndex: 1]; [popup setNeedsDisplay: YES]; [panel makeKeyAndOrderFront: self]; current = 1; } else if (current >= [popup numberOfItems]) { current = 1; } [self setCurrentInspector: self]; } - (void) setClassInspector { current = 4; [self setCurrentInspector: self]; } - (void) _addDefaultModes { // remove all items... clear out current state [modes removeAllObjects]; currentMode = nil; // Attributes inspector... [self addInspectorModeWithIdentifier: @"AttributesInspector" forObject: selectedObject localizedLabel: _(@"Attributes") inspectorClassName: [selectedObject inspectorClassName] ordering: 0.0]; // Connection inspector... [self addInspectorModeWithIdentifier: @"ConnectionInspector" forObject: selectedObject localizedLabel: _(@"Connections") inspectorClassName: [selectedObject connectInspectorClassName] ordering: 1.0]; // Size inspector... [self addInspectorModeWithIdentifier: @"SizeInspector" forObject: selectedObject localizedLabel: _(@"Size") inspectorClassName: [selectedObject sizeInspectorClassName] ordering: 2.0]; // Help inspector... [self addInspectorModeWithIdentifier: @"HelpInspector" forObject: selectedObject localizedLabel: _(@"Help") inspectorClassName: [selectedObject helpInspectorClassName] ordering: 3.0]; // Custom class inspector... [self addInspectorModeWithIdentifier: @"CustomClassInspector" forObject: selectedObject localizedLabel: _(@"Custom Class") inspectorClassName: [selectedObject classInspectorClassName] ordering: 4.0]; } - (void) _refreshPopUp { NSEnumerator *en = [modes objectEnumerator]; int index = 0; id obj = nil; [popup removeAllItems]; while((obj = [en nextObject]) != nil) { int tag = index + 1; NSMenuItem *item; [popup addItemWithTitle: [obj localizedLabel]]; item = (NSMenuItem *)[popup itemAtIndex: index]; [item setTarget: self]; [item setAction: @selector(setCurrentInspector:)]; [item setKeyEquivalent: [NSString stringWithFormat: @"%d",tag]]; [item setTag: tag]; index++; } } - (void) setCurrentInspector: (id)anObj { NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; NSArray *selection = [[(id)NSApp selectionOwner] selection]; unsigned count = [selection count]; id obj = [selection lastObject]; NSView *newView = nil; NSView *oldView = nil; NSString *newInspector = nil; int tag = 0; if (anObj != self) { tag = [anObj tag]; current = ((tag > 0)?(tag - 1):tag); } // reset current under certain conditions. if(current < 0) { current = 0; } NSDebugLog(@"current %i",current); // refresh object. selectedObject = obj; // remove any items beyond the original items on the list.. [self _addDefaultModes]; // inform the world that the object is about to be inspected. [nc postNotificationName: IBWillInspectObjectNotification object: obj]; // set key equivalent [self _refreshPopUp]; if([modes count] == NUM_DEFAULT_INSPECTORS) { if(current > (NUM_DEFAULT_INSPECTORS - 1)) { current = 0; } } if (count == 0) { newInspector = @"GormEmptyInspector"; } else if (count > 1) { newInspector = @"GormMultipleInspector"; } else { currentMode = [modes objectAtIndex: current]; newInspector = [currentMode inspectorClassName]; } /* * Set panel title for the type of object being inspected. */ if (selectedObject == nil) { [panel setTitle: _(@"Inspector")]; } else if([selectedObject isKindOfClass: [GormClassProxy class]]) { [panel setTitle: [NSString stringWithFormat: @"Class Edit Inspector:%@", [selectedObject className]]]; } else { NSString *newTitle = [selectedObject objectNameForInspectorTitle]; [panel setTitle: [NSString stringWithFormat:_(@"%@ Inspector"), newTitle]]; } if (newInspector == nil) { newInspector = @"GormNotApplicableInspector"; } if ([oldInspector isEqual: newInspector] == NO) { id prevInspector = nil; /* * Return the inspector view to its original window and release the old * inspector. */ if(inspector != nil) { [[inspector okButton] removeFromSuperview]; [[inspector revertButton] removeFromSuperview]; } ASSIGN(oldInspector, newInspector); prevInspector = inspector; inspector = [cache objectForKey: newInspector]; if (inspector == nil) { Class c = NSClassFromString(newInspector); inspector = [[c alloc] init]; /* Try to gracefully handle an inspector creation error */ while (inspector == nil && (obj = [obj superclass]) && current == 0) { NSDebugLog(@"Error loading %@ inspector", newInspector); newInspector = [obj inspectorClassName]; inspector = [[NSClassFromString(newInspector) alloc] init]; } [cache setObject: inspector forKey: newInspector]; RELEASE(inspector); } oldView = [inspectorView contentView]; newView = [[inspector window] contentView]; if (newView != nil) { id initialResponder = [[inspector window] initialFirstResponder]; NSView *outer = [panel contentView]; NSRect rect = [outer bounds]; /* Set initialFirstResponder */ if (buttonView != nil) { [buttonView removeFromSuperview]; buttonView = nil; } rect.size.height = [selectionView frame].origin.y - 3; if ([inspector wantsButtons] == YES) { NSRect buttonsRect; NSRect bRect = NSMakeRect(0, 0, 60, 20); NSButton *ok; NSButton *revert; rect.size.height = [selectionView frame].origin.y; buttonsRect = NSMakeRect(0,0,rect.size.width,IVB); rect.origin.y += IVB; rect.size.height -= (IVB + 3); buttonView = [[NSView alloc] initWithFrame: buttonsRect]; [buttonView setAutoresizingMask: NSViewWidthSizable]; [outer addSubview: buttonView]; RELEASE(buttonView); ok = [inspector okButton]; if (ok != nil) { bRect = [ok frame]; bRect.origin.y = 10; bRect.origin.x = buttonsRect.size.width-10-bRect.size.width; [ok setFrame: bRect]; [buttonView addSubview: ok]; } revert = [inspector revertButton]; if (revert != nil) { bRect = [revert frame]; bRect.origin.y = 10; bRect.origin.x = 10; [revert setFrame: bRect]; [buttonView addSubview: revert]; } } else { rect.size.height = [selectionView frame].origin.y - 3; [buttonView removeFromSuperview]; } /* * Make the inspector view the correct size for the viewable panel, * and set the frame size for the new contents before adding them. */ [inspectorView setFrame: rect]; rect.origin = NSZeroPoint; [newView setFrame: rect]; RETAIN(oldView); [inspectorView setContentView: newView]; [[prevInspector window] setContentView: oldView]; RELEASE(oldView); /* Set the default First responder to the new View */ if ( initialResponder ) { [panel setInitialFirstResponder:initialResponder]; } } } // reset the popup.. [popup selectItemAtIndex: current]; // inspect the object. [inspector setObject: [currentMode object]]; } @end