/** GSNibLoading These are templates for use with OSX Nib files. These classes are the templates and other things which are needed for reading/writing nib files. Copyright (C) 1997, 1999 Free Software Foundation, Inc. Author: Gregory John Casamento Date: 2003, 2005 This file is part of the GNUstep GUI Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; see the file COPYING.LIB. If not, see or write to the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "AppKit/AppKit.h" #include #include "GSGuiPrivate.h" /* * Setup for inline operation of arrays. */ #define GSI_ARRAY_RETAIN(A, X) RETAIN((X).obj) #define GSI_ARRAY_RELEASE(A, X) RELEASE((X).obj) #define GSI_ARRAY_TYPES GSUNION_OBJ #include #include #include static BOOL _isInInterfaceBuilder = NO; @interface NSKeyedUnarchiver (NSClassSwapperPrivate) - (BOOL) replaceObject: (id)oldObj withObject: (id)newObj; - (NSDictionary *)keyMap; - (Class) replacementClassForClassName: (NSString *)className; @end @interface NSApplication (NibCompatibility) - (void) _setMainMenu: (NSMenu*)aMenu; @end @interface NSView (NibCompatibility) - (void) _fixSubviews; @end /* Correct some instances where the ":" is missing from the method name in the label */ @interface NSNibControlConnector (NibCompatibility) - (void) instantiateWithInstantiator: (id)instantiator; @end @interface NSNibConnector (NibCompatibility) - (void) instantiateWithInstantiator: (id)instantiator; @end @interface NSDecimalNumberPlaceholder : NSObject @end @interface _NSCornerView : NSView @end @interface NSMenu (NibCompatibility) - (void) _setMain: (BOOL)isMain; @end @interface NSMenu (GNUstepPrivate) - (void) _setGeometry; @end @implementation NSMenu (NibCompatibility) // FIXME: Why can't this be merged with setMain: ? - (void) _setMain: (BOOL)isMain { if (isMain) { NSMenuView *oldRep; NSInterfaceStyle oldStyle; NSInterfaceStyle newStyle; NSString *processName; if([self numberOfItems] == 0) return; oldRep = [self menuRepresentation]; oldStyle = [oldRep interfaceStyle]; newStyle = NSInterfaceStyleForKey(@"NSMenuInterfaceStyle", nil); processName = [[NSProcessInfo processInfo] processName]; /* * If necessary, rebuild menu for (different) style */ if (oldStyle != newStyle) { NSMenuView *newRep; newRep = [[NSMenuView alloc] initWithFrame: NSZeroRect]; if (newStyle == NSMacintoshInterfaceStyle || newStyle == NSWindows95InterfaceStyle) { [newRep setHorizontal: YES]; } else { [newRep setHorizontal: NO]; } [newRep setInterfaceStyle: newStyle]; [self setMenuRepresentation: newRep]; RELEASE(newRep); } [[self window] setTitle: processName]; [[self window] setLevel: NSMainMenuWindowLevel]; // if it's a standard menu, transform it to be more NeXT'ish/GNUstep-like if(_menu.horizontal == NO) { NSString *infoString = NSLocalizedString (@"Info", @"Info"); NSString *quitString = [NSString stringWithFormat: @"%@ %@", NSLocalizedString (@"Quit", @"Quit"), processName]; NSMenuItem *quitItem = [[NSMenuItem alloc] initWithTitle: quitString action: @selector(terminate:) keyEquivalent: @"q"]; NSMenuItem *appItem; appItem = (NSMenuItem*)[self itemAtIndex: 0]; // Info item. [self addItem: quitItem]; [self setTitle: processName]; [appItem setTitle: infoString]; [[appItem submenu] setTitle: infoString]; } [self _setGeometry]; [self sizeToFit]; if ([NSApp isActive]) { [self display]; } } else { [self close]; [[self window] setLevel: NSSubmenuWindowLevel]; } } @end @implementation NSApplication (NibCompatibility) - (void) _setMainMenu: (NSMenu*)aMenu { if (_main_menu == aMenu) { return; } if (_main_menu != nil) { [_main_menu setMain: NO]; } ASSIGN(_main_menu, aMenu); if (_main_menu != nil) { [_main_menu _setMain: YES]; } } @end @implementation NSView (NibCompatibility) - (void) _setWindow: (id) w { _window = w; } - (void) _fixSubviews { NSEnumerator *en = [[self subviews] objectEnumerator]; id v = nil; while ((v = [en nextObject]) != nil) { if ([v window] != [self window] || [v superview] != self) { [v _setWindow: [self window]]; RETAIN(v); [_sub_views removeObject: v]; [self addSubview: v]; RELEASE(v); } [v _fixSubviews]; } } @end /** * NSWindowTemplate * * Instances of this class take the place of all windows in the nib file. */ @implementation NSWindowTemplate + (void) initialize { if (self == [NSWindowTemplate class]) { [self setVersion: 0]; } } - (void) dealloc { RELEASE(_title); RELEASE(_viewClass); RELEASE(_windowClass); RELEASE(_view); RELEASE(_autosaveName); [super dealloc]; } /** * Designated initializer for NSWindowTemplate. */ - (id) initWithWindow: (NSWindow *)window className: (NSString *)windowClass isDeferred: (BOOL) deferred isOneShot: (BOOL) oneShot isVisible: (BOOL) visible wantsToBeColor: (BOOL) wantsToBeColor autoPositionMask: (int) autoPositionMask { if ((self = [super init]) != nil) { if (window != nil) { // object members ASSIGN(_title, [window title]); ASSIGN(_viewClass, NSStringFromClass([[window contentView] class])); ASSIGN(_windowClass, windowClass); ASSIGN(_view, [window contentView]); ASSIGN(_autosaveName, [window frameAutosaveName]); // style & size _windowStyle = [window styleMask]; _backingStoreType = [window backingType]; _maxSize = [window maxSize]; _minSize = [window minSize]; _windowRect = [window frame]; _screenRect = [[NSScreen mainScreen] frame]; // flags _flags.isHiddenOnDeactivate = [window hidesOnDeactivate]; _flags.isNotReleasedOnClose = (![window isReleasedWhenClosed]); _flags.isDeferred = deferred; _flags.isOneShot = oneShot; _flags.isVisible = visible; _flags.wantsToBeColor = wantsToBeColor; _flags.dynamicDepthLimit = [window hasDynamicDepthLimit]; _flags.autoPositionMask = autoPositionMask; _flags.savePosition = YES; // not yet implemented. } } return self; } - (id) initWithCoder: (NSCoder *)coder { if ([coder allowsKeyedCoding]) { if ([coder containsValueForKey: @"NSViewClass"]) { ASSIGN(_viewClass, [coder decodeObjectForKey: @"NSViewClass"]); } if ([coder containsValueForKey: @"NSWindowClass"]) { ASSIGN(_windowClass, [coder decodeObjectForKey: @"NSWindowClass"]); } if ([coder containsValueForKey: @"NSWindowStyleMask"]) { _windowStyle = [coder decodeIntForKey: @"NSWindowStyleMask"]; } if ([coder containsValueForKey: @"NSWindowBacking"]) { _backingStoreType = [coder decodeIntForKey: @"NSWindowBacking"]; } if ([coder containsValueForKey: @"NSWindowView"]) { ASSIGN(_view, [coder decodeObjectForKey: @"NSWindowView"]); } if ([coder containsValueForKey: @"NSWTFlags"]) { unsigned long flags = [coder decodeIntForKey: @"NSWTFlags"]; memcpy((void *)&_flags,(void *)&flags,sizeof(struct _GSWindowTemplateFlags)); } if ([coder containsValueForKey: @"NSMinSize"]) { _minSize = [coder decodeSizeForKey: @"NSMinSize"]; } if ([coder containsValueForKey: @"NSMaxSize"]) { _maxSize = [coder decodeSizeForKey: @"NSMaxSize"]; } else { _maxSize = NSMakeSize (10e4, 10e4); } if ([coder containsValueForKey: @"NSWindowRect"]) { _windowRect = [coder decodeRectForKey: @"NSWindowRect"]; } if ([coder containsValueForKey: @"NSFrameAutosaveName"]) { ASSIGN(_autosaveName, [coder decodeObjectForKey: @"NSFrameAutosaveName"]); } if ([coder containsValueForKey: @"NSWindowTitle"]) { ASSIGN(_title, [coder decodeObjectForKey: @"NSWindowTitle"]); _windowStyle |= NSTitledWindowMask; } _baseWindowClass = [NSWindow class]; } else { [NSException raise: NSInvalidArgumentException format: @"Can't decode %@ with %@.",NSStringFromClass([self class]), NSStringFromClass([coder class])]; } return self; } - (void) encodeWithCoder: (NSCoder *)aCoder { if ([aCoder allowsKeyedCoding]) { unsigned long flags = 0; NSRect rect = [NSWindow contentRectForFrameRect: _windowRect styleMask: _windowStyle]; memcpy((void *)&flags,(void *)&_flags,sizeof(unsigned long)); [aCoder encodeObject: _viewClass forKey: @"NSViewClass"]; [aCoder encodeObject: _windowClass forKey: @"NSWindowClass"]; [aCoder encodeInt: _windowStyle forKey: @"NSWindowStyleMask"]; [aCoder encodeInt: _backingStoreType forKey: @"NSWindowBacking"]; [aCoder encodeObject: _view forKey: @"NSWindowView"]; [aCoder encodeInt: flags forKey: @"NSWTFlags"]; [aCoder encodeSize: _minSize forKey: @"NSMinSize"]; [aCoder encodeSize: _maxSize forKey: @"NSMaxSize"]; [aCoder encodeRect: rect forKey: @"NSWindowRect"]; [aCoder encodeObject: _title forKey: @"NSWindowTitle"]; [aCoder encodeObject: _autosaveName forKey: @"NSFrameAutosaveName"]; } } /** * This method is used to get the real object when connections are established. */ - (id) nibInstantiate { if (_realObject == nil) { Class aClass; if ([NSClassSwapper isInInterfaceBuilder]) { aClass = [self baseWindowClass]; } else { aClass = NSClassFromString(_windowClass); } if (aClass == nil) { [NSException raise: NSInternalInconsistencyException format: @"Unable to find class '%@'", _windowClass]; } _realObject = [[aClass allocWithZone: NSDefaultMallocZone()] initWithContentRect: _windowRect styleMask: _windowStyle backing: _backingStoreType defer: _flags.isDeferred screen: nil]; // set flags... [_realObject setHidesOnDeactivate: _flags.isHiddenOnDeactivate]; [_realObject setReleasedWhenClosed: !(_flags.isNotReleasedOnClose)]; [_realObject setOneShot: _flags.isOneShot]; // [_realObject setVisible: _flags.isVisible]; // this is determined by whether it's in the visible windows array... // [_realObject setWantsToBeColor: _flags.wantsToBeColor]; // not applicable on GNUstep. [_realObject setAutodisplay: YES]; [_realObject setDynamicDepthLimit: _flags.dynamicDepthLimit]; // [_realObject setAutoPositionMask: _flags.autoPositionMask]; // currently not implemented for nibs // [_realObject setAutoPosition: _flags.autoPosition]; [_realObject setDynamicDepthLimit: _flags.dynamicDepthLimit]; [_realObject setFrameAutosaveName: _autosaveName]; // reset attributes... [_realObject setContentView: _view]; [_realObject setMinSize: _minSize]; [_realObject setMaxSize: _maxSize]; [_realObject setTitle: _title]; [_view _fixSubviews]; // resize the window... [_realObject setFrame: [NSWindow frameRectForContentRect: [self windowRect] styleMask: [self windowStyle]] display: NO]; } return _realObject; } // setters and getters /** * sets the type of backing store the window uses. */ - (void) setBackingStoreType: (NSBackingStoreType)type { _backingStoreType = type; } /** * Returns the type of backing store which is used. */ - (NSBackingStoreType) backingStoreType { return _backingStoreType; } /** * Sets whether or not the window is deferred. */ - (void) setDeferred: (BOOL)flag { _flags.isDeferred = flag; } /** * Returns YES, if the window is deferred, NO otherwise. */ - (BOOL) isDeferred { return _flags.isDeferred; } /** * Sets the maximum size of the window. */ - (void) setMaxSize: (NSSize)maxSize { _maxSize = maxSize; } /** * Returns the maximum size of the window. */ - (NSSize) maxSize { return _maxSize; } /** * Sets the minimum size of the window. */ - (void) setMinSize: (NSSize)minSize { _minSize = minSize; } /** * Returns the maximum size of the window. */ - (NSSize) minSize { return _minSize; } /** * Sets the window style. */ - (void) setWindowStyle: (unsigned)style { _windowStyle = style; } /** * Returns the window style. */ - (unsigned) windowStyle { return _windowStyle; } /** * Sets the window title. */ - (void) setTitle: (NSString *) title { ASSIGN(_title, title); } /** * Returns the window style. */ - (NSString *)title; { return _title; } /** * Sets the class used for the content view. */ - (void) setViewClass: (NSString *)viewClass { ASSIGN(_viewClass,viewClass); } /** * Returns the name of the class used for the content view. */ - (NSString *)viewClass { return _viewClass; } /** * Sets the window rect. */ - (void) setWindowRect: (NSRect)rect { _windowRect = rect; } /** * Returns the window rect. */ - (NSRect)windowRect { return _windowRect; } /** * Sets the screen rect. */ - (void) setScreenRect: (NSRect)rect { _screenRect = rect; } /** * Returns the screen rect. */ - (NSRect) screenRect { return _screenRect; } /** * Sets the instantiated object/real object. */ - (void) setRealObject: (id)o { ASSIGN(_realObject,o); } /** * Returns the real object represented by this template. */ - (id) realObject { return _realObject; } /** * Sets the view instance. */ - (void) setView: (id)view { ASSIGN(_view,view); } /** * Gets the view instance. */ - (id) view { return _view; } /** * sets the class name to be used when unarchiving the window. */ - (void) setClassName: (NSString *)name { ASSIGN(_windowClass, name); } /** * Returns the class instance. */ - (NSString *)className { return _windowClass; } /** * Returns the base window class. This is usually NSWindow, but this method * is overriden in the editor so that a different class may be used to take the * place of the window. In the case of Gorm, this is GormNSWindow. */ - (Class) baseWindowClass { return _baseWindowClass; } @end /* * NSViewTemplate * * Template for any classes which derive from NSView */ @implementation NSViewTemplate + (void) initialize { if (self == [NSViewTemplate class]) { [self setVersion: 0]; } } /** * Designated initializer for NSViewTemplate. */ - (id) initWithObject: (id)o className: (NSString *)name { if((self = [super init]) != nil) { [self setRealObject: o]; [self setClassName: name]; } return self; } - (id) initWithCoder: (NSCoder *)coder { self = [super initWithCoder: coder]; if (self != nil) { if ([coder allowsKeyedCoding]) { _className = [coder decodeObjectForKey: @"NSClassName"]; } if (_realObject == nil) { Class aClass = NSClassFromString(_className); if (aClass == nil) { [NSException raise: NSInternalInconsistencyException format: @"Unable to find class '%@'", _className]; } else { _realObject = [[aClass allocWithZone: NSDefaultMallocZone()] initWithCoder: coder]; [[self superview] replaceSubview: self with: _realObject]; // replace the old view... } } // FIXME: Should release self return _realObject; } else { [NSException raise: NSInvalidArgumentException format: @"Can't decode %@ with %@.",NSStringFromClass([self class]), NSStringFromClass([coder class])]; } return nil; } - (void) encodeWithCoder: (NSCoder *)coder { if ([coder allowsKeyedCoding]) { [coder encodeObject: (id)_className forKey: @"NSClassName"]; [_realObject encodeWithCoder: coder]; } else { [NSException raise: NSInvalidArgumentException format: @"Can't encode %@ with %@.",NSStringFromClass([self class]), NSStringFromClass([coder class])]; } } // setters and getters /** * Set the class name to be used by the NSView subclass. */ - (void) setClassName: (NSString *)name { ASSIGN(_className, name); } /** * Returns the classname. */ - (NSString *)className { return _className; } /** * Set the real object of the template. */ - (void) setRealObject: (id)o { ASSIGN(_realObject, o); } /** * Get the real object represented by the template. */ - (id) realObject { return _realObject; } @end // Template for any classes which derive from NSText @implementation NSTextTemplate + (void) initialize { if (self == [NSTextTemplate class]) { [self setVersion: 0]; } } @end /** * NSTextViewTemplate * * Template for any classes which derive from NSTextView */ @implementation NSTextViewTemplate + (void) initialize { if (self == [NSTextViewTemplate class]) { [self setVersion: 0]; } } @end // Template for any classes which derive from NSMenu. @implementation NSMenuTemplate + (void) initialize { if (self == [NSMenuTemplate class]) { [self setVersion: 0]; } } - (id) initWithCoder: (NSCoder *)aCoder { RELEASE(self); return nil; } - (void) encodeWithCoder: (NSCoder *)aCoder { } - (void) setClassName: (NSString *)className { ASSIGN(_menuClass, className); } - (NSString *)className { return _menuClass; } - (void) setRealObject: (id)o { ASSIGN(_realObject,o); } - (id) realObject { return _realObject; } @end @implementation NSCustomObject - (void) setClassName: (NSString *)name { ASSIGNCOPY(_className, name); } - (NSString *)className { return _className; } - (void) setExtension: (NSString *)name { ASSIGNCOPY(_extension, name); } - (NSString *)extension { return _extension; } - (void) setRealObject: (id)obj { ASSIGN(_object, obj); } - (id) realObject { return _object; } - (id) initWithCoder: (NSCoder *)coder { if ([coder allowsKeyedCoding]) { ASSIGN(_className, [coder decodeObjectForKey: @"NSClassName"]); ASSIGN(_extension, [coder decodeObjectForKey: @"NSExtension"]); ASSIGN(_object, [coder decodeObjectForKey: @"NSObject"]); } else { [NSException raise: NSInvalidArgumentException format: @"Can't decode %@ with %@.",NSStringFromClass([self class]), NSStringFromClass([coder class])]; } return self; } - (void) encodeWithCoder: (NSCoder *)coder { if ([coder allowsKeyedCoding]) { [coder encodeObject: (id)_className forKey: @"NSClassName"]; [coder encodeConditionalObject: (id)_extension forKey: @"NSExtension"]; [coder encodeConditionalObject: (id)_object forKey: @"NSObject"]; } else { [NSException raise: NSInvalidArgumentException format: @"Keyed coding not implemented for %@.", NSStringFromClass([self class])]; } } - (id) nibInstantiate { if (_object == nil) { Class aClass; if ([NSClassSwapper isInInterfaceBuilder]) { aClass = [self class]; } else { aClass = NSClassFromString(_className); } if (aClass == nil) { [NSException raise: NSInternalInconsistencyException format: @"Unable to find class '%@'", _className]; } if(GSObjCIsKindOf(aClass, [NSApplication class]) || [_className isEqual: @"NSApplication"]) { _object = [aClass sharedApplication]; } else { _object = [[aClass allocWithZone: NSDefaultMallocZone()] init]; } } return _object; } - (void) awakeFromNib { NSDebugLog(@"Called awakeFromNib on an NSCustomObject instance: %@", self); if([_object respondsToSelector: @selector(awakeFromNib)]) { [_object awakeFromNib]; } } - (NSString *) description { return [NSString stringWithFormat: @"<%s: %lx> = <>", GSClassNameFromObject(self), (unsigned long)self, _className,_object]; } - (void) dealloc { RELEASE(_className); RELEASE(_extension); [super dealloc]; } @end @implementation NSCustomView - (void) setClassName: (NSString *)name { ASSIGNCOPY(_className, name); } - (NSString *)className { return _className; } - (void) setExtension: (NSString *)ext; { ASSIGNCOPY(_extension, ext); } - (NSString *)extension { return _extension; } - (id) nibInstantiate { Class aClass; if ([NSClassSwapper isInInterfaceBuilder]) { _view = self; return self; } else { aClass = NSClassFromString(_className); } // If the class name is nil, assume NSView. if(_className == nil) { aClass = [NSView class]; } if (aClass == nil) { [NSException raise: NSInternalInconsistencyException format: @"Unable to find class '%@'", _className]; } else { _view = [[aClass allocWithZone: NSDefaultMallocZone()] initWithFrame: [self frame]]; } return _view; } - (id) awakeAfterUsingCoder: (NSCoder *)coder { return _view; } - (id) nibInstantiateWithCoder: (NSCoder *)coder { if([NSClassSwapper isInInterfaceBuilder]) { return _view; } else if ([coder allowsKeyedCoding]) { NSArray *subs = nil; id nextKeyView = nil; id prevKeyView = nil; NSEnumerator *en = nil; id v = nil; prevKeyView = [coder decodeObjectForKey: @"NSPreviousKeyView"]; nextKeyView = [coder decodeObjectForKey: @"NSNextKeyView"]; if (nextKeyView != nil) { [_view setNextKeyView: nextKeyView]; } if (prevKeyView != nil) { [_view setPreviousKeyView: prevKeyView]; } if ([coder containsValueForKey: @"NSvFlags"]) { int vFlags = [coder decodeIntForKey: @"NSvFlags"]; [_view setAutoresizingMask: vFlags & 0x3F]; [_view setAutoresizesSubviews: ((vFlags & 0x100) == 0x100)]; [_view setHidden: ((vFlags & 0x80000000) == 0x80000000)]; } /* if ([coder containsValueForKey: @"NSNextResponder"]) { [_view setNextResponder: [coder decodeObjectForKey: @"NSNextResponder"]]; } */ // reset the bounds... // [_view setBounds: [_view frame]]; subs = [coder decodeObjectForKey: @"NSSubviews"]; en = [subs objectEnumerator]; while((v = [en nextObject]) != nil) { [_view addSubview: v]; } } else { [NSException raise: NSInternalInconsistencyException format: @"Called NSCustomView awakeAfterUsingCoder with non-keyed archiver."]; } return _view; } - (id) initWithCoder: (NSCoder *)coder { // if in interface builder, then initialize as normal. if([NSClassSwapper isInInterfaceBuilder]) { self = [super initWithCoder: coder]; } if (self != nil) { if ([coder allowsKeyedCoding]) { // get the super stuff without calling super... if ([coder containsValueForKey: @"NSFrame"]) { _frame = [coder decodeRectForKey: @"NSFrame"]; } else { _frame = NSZeroRect; if ([coder containsValueForKey: @"NSFrameSize"]) { _frame.size = [coder decodeSizeForKey: @"NSFrameSize"]; } } ASSIGN(_className, [coder decodeObjectForKey: @"NSClassName"]); ASSIGN(_extension, [coder decodeObjectForKey: @"NSExtension"]); if([self nibInstantiate] != nil) { [self nibInstantiateWithCoder: coder]; } if(self != _view) { AUTORELEASE(self); [(NSKeyedUnarchiver *)coder replaceObject: self withObject: _view]; } } else { [NSException raise: NSInvalidArgumentException format: @"Can't decode %@ with %@.",NSStringFromClass([self class]), NSStringFromClass([coder class])]; } } return _view; } - (void) encodeWithCoder: (NSCoder *)coder { [super encodeWithCoder: coder]; if ([coder allowsKeyedCoding]) { [coder encodeObject: _className forKey: @"NSClassName"]; [coder encodeObject: _extension forKey: @"NSExtension"]; } else { [NSException raise: NSInvalidArgumentException format: @"Can't encode %@ with %@.",NSStringFromClass([self class]), NSStringFromClass([coder class])]; } } @end /** * This class represents an image or a sound which is referenced by the nib file. */ @implementation NSCustomResource - (void) setClassName: (NSString *)className { ASSIGNCOPY(_className, className); } - (NSString *)className { return _className; } - (void) setResourceName: (NSString *)resourceName { ASSIGNCOPY(_resourceName, resourceName); } - (NSString *)resourceName { return _resourceName; } - (id) initWithCoder: (NSCoder *)coder { id realObject = nil; if ([coder allowsKeyedCoding]) { ASSIGN(_className, [coder decodeObjectForKey: @"NSClassName"]); ASSIGN(_resourceName, [coder decodeObjectForKey: @"NSResourceName"]); // this is a hack, but for now it should do. if ([_className isEqual: @"NSSound"]) { realObject = RETAIN([NSSound soundNamed: _resourceName]); } else if ([_className isEqual: @"NSImage"]) { realObject = RETAIN([NSImage imageNamed: _resourceName]); } // if an object has been substituted, then release the placeholder. if (realObject != nil) { RELEASE(self); } } else { [NSException raise: NSInvalidArgumentException format: @"Can't decode %@ with %@.",NSStringFromClass([self class]), NSStringFromClass([coder class])]; } return realObject; } - (void) encodeWithCoder: (NSCoder *)coder { if ([coder allowsKeyedCoding]) { [coder encodeObject: (id)_className forKey: @"NSClassName"]; [coder encodeObject: (id)_resourceName forKey: @"NSResourceName"]; } } @end /** * Category to add methods to NSKeyedUnarchiver which are needed during * nib reading. */ @implementation NSKeyedUnarchiver (NSClassSwapperPrivate) /** * This method is used to replace oldObj with newObj * in the map that is maintained in NSKeyedUnarchiver. */ - (BOOL) replaceObject: (id)oldObj withObject: (id)newObj { unsigned int i = 0; unsigned int count = GSIArrayCount(_objMap); for (i = 0; i < count; i++) { id obj = GSIArrayItemAtIndex(_objMap, i).obj; if (obj == oldObj) break; } if (i < count) { GSIArraySetItemAtIndex(_objMap, (GSIArrayItem)newObj, i); return YES; } return NO; } /** * This method is private and is purely for debugging purposes. */ - (NSDictionary *)keyMap { return _keyMap; } /** * This method returns the class which replaces the class named * by className. It uses the classes map to do this. */ - (Class) replacementClassForClassName: (NSString *)className { Class aClass; if ((aClass = [self classForClassName: className]) == nil) { aClass = NSClassFromString(className); } if (aClass == nil) { [NSException raise: NSInternalInconsistencyException format: @"NSClassSwapper unable to find class '%@'", className]; } return aClass; } @end /** * NSClassSwapper * * This class is used to stand-in for objects which need to be replaced by another object. * When this class is loaded in the live application, it unarchives and immediately replaces * itself with the instance of the object requested. This is necessary since IB/Gorm does * have objects this is used for in palettes, so there is no "live" or actual instance saved * in the gorm file... only this object as a stand in. */ @implementation NSClassSwapper - (id) initWithObject: (id)object withClassName: (NSString *)className originalClassName: (NSString *)origClassName { if ((self = [super init]) != nil) { [self setTemplate: object]; [self setClassName: className]; [self setOriginalClassName: origClassName]; } return self; } /** * This class method keeps track of whether or not we are operating within IB/Gorm. * When unarchiving in IB/Gorm some behavior may need to be surpressed for some objects * or it */ + (void) setIsInInterfaceBuilder: (BOOL)flag { _isInInterfaceBuilder = flag; } /** * returns YES, if we are currently in IB/Gorm. */ + (BOOL) isInInterfaceBuilder { return _isInInterfaceBuilder; } /** * Sets the template represented by temp. */ - (void) setTemplate: (id)temp { ASSIGN(_template, temp); } /** * Returns the template. */ - (id) template { return _template; } /** * Sets the class name. */ - (void) setClassName: (NSString *)className { ASSIGNCOPY(_className, className); } /** * Returns the class name. */ - (NSString *)className { return _className; } /** * Sets the original class name. */ - (void) setOriginalClassName: (NSString *)className { ASSIGNCOPY(_originalClassName, className); } /** * Returns the original class name. */ - (NSString *)originalClassName { return _originalClassName; } /** * Instantiates the real object using className. */ - (void) instantiateRealObject: (NSCoder *)coder withClassName: (NSString *)className { Class newClass = nil; id object = nil; NSKeyedUnarchiver *decoder = (NSKeyedUnarchiver *)coder; if([NSClassSwapper isInInterfaceBuilder] == YES) { newClass = [decoder replacementClassForClassName: _originalClassName]; } else { newClass = [decoder replacementClassForClassName: className]; } // swap the class... object = [newClass allocWithZone: NSDefaultMallocZone()]; [decoder setDelegate: self]; // set the delegate... [decoder replaceObject: self withObject: object]; [self setTemplate: [object initWithCoder: decoder]]; if (object != _template) { [decoder replaceObject: object withObject: _template]; } [decoder setDelegate: nil]; // unset the delegate... } /** * This delegate method makes the proper substitution for cellClass * when the object needs to have it's own cell. An example of this * is NSSecureTextField/NSSecureTextFieldCell. */ - (id) unarchiver: (NSKeyedUnarchiver *)coder didDecodeObject: (id)obj { Class newClass = nil; id result = obj; // if we are in an interface builder, then return the original object. if ([NSClassSwapper isInInterfaceBuilder] == YES) { newClass = [coder replacementClassForClassName: _originalClassName]; } else { newClass = [coder replacementClassForClassName: _className]; } // if this is a class which uses cells, override with the new cellClass, if the // subclass responds to cellClass. if ([obj isKindOfClass: [NSCell class]] && [newClass respondsToSelector: @selector(cellClass)] && [_className isEqualToString: _originalClassName] == NO) { Class newCellClass = [newClass cellClass]; if(newCellClass != [NSCell class]) { result = [[newCellClass alloc] initWithCoder: coder]; } } return result; } /** * Decode NSClassSwapper. */ - (id) initWithCoder: (NSCoder *)coder { if ([coder allowsKeyedCoding]) { ASSIGN(_className, [coder decodeObjectForKey: @"NSClassName"]); ASSIGN(_originalClassName, [coder decodeObjectForKey: @"NSOriginalClassName"]); // build the real object... if ([NSClassSwapper isInInterfaceBuilder] == YES) { [self instantiateRealObject: coder withClassName: _originalClassName]; } else { [self instantiateRealObject: coder withClassName: _className]; } RELEASE(self); } else { [NSException raise: NSInvalidArgumentException format: @"Can't decode %@ with %@.",NSStringFromClass([self class]), NSStringFromClass([coder class])]; } return _template; } /** * Encode NSClassSwapper. */ - (void) encodeWithCoder: (NSCoder *)coder { if ([coder allowsKeyedCoding]) { [coder encodeObject: _originalClassName forKey: @"NSOriginalClassName"]; [coder encodeObject: _className forKey: @"NSClassName"]; [_template encodeWithCoder: coder]; // encode the actual object; } else { [NSException raise: NSInvalidArgumentException format: @"Can't encode %@ with %@.",NSStringFromClass([self class]), NSStringFromClass([coder class])]; } } /** * Deallocate NSClassSwapper instance. */ - (void) dealloc { RELEASE(_className); RELEASE(_originalClassName); RELEASE(_template); [super dealloc]; } @end @implementation NSNibConnector (NibCompatibility) /** * This method causes the connection to instantiate the objects in it's source * and destination. The instantiator is the object which holds any custom * class information which might be needed to do the proprer substitution of * objects based on the contents of the maps. */ - (void) instantiateWithInstantiator: (id)instantiator { [self setSource: [instantiator instantiateObject: _src]]; [self setDestination: [instantiator instantiateObject: _dst]]; } @end @implementation NSNibControlConnector (NibCompatibility) /** * This method overrides the default implementation of instantiate with * instantiator. It also corrects a common issue in some nib files * by adding a colon to the end if none was given. It then calls the * superclass with the corrected label. */ - (void) instantiateWithInstantiator: (id)instantiator { NSRange colonRange = [_tag rangeOfString: @":"]; unsigned int location = colonRange.location; if (location == NSNotFound) { NSString *newTag = [NSString stringWithFormat: @"%@:",_tag]; [self setLabel: (id)newTag]; } [super instantiateWithInstantiator: instantiator]; } @end /** * NSIBObjectData * * This class is the container for all of the nib data. It contains several maps. * The maps are the following: * * name -> object (name table) * object -> name (name table reverse lookup) * classes -> object (for custom class storage) * oids -> object (for relating the oid to each object) * accessibilityOids -> object * * The maps are stored in the nib itself as a set of synchronized * arrays one array containing the keys and the other the values. This is why, in the * initWithCoder: and encodeWithCoder: methods they are saved as arrays and then * loaded into NSMapTables. */ @implementation NSIBObjectData /** * Get the values from the map in the same order as the keys. */ - (NSArray *) _valuesForKeys: (NSArray *)keys inMap: (NSMapTable *)map { NSMutableArray *result = [NSMutableArray array]; NSEnumerator *en = [keys objectEnumerator]; id key = nil; while ((key = [en nextObject]) != nil) { id value = (id)NSMapGet(map,key); [result addObject: value]; } return result; } /** * Build a map with two arrays of keys and values. */ - (void) _buildMap: (NSMapTable *)mapTable withKeys: (NSArray *)keys andValues: (NSArray *)values { NSEnumerator *ken = [keys objectEnumerator]; NSEnumerator *ven = [values objectEnumerator]; id key = nil; id value = nil; while ((key = [ken nextObject]) != nil && (value = [ven nextObject]) != nil) { NSMapInsert(mapTable, key, value); if(value == nil) { NSLog(@"==> WARNING: Value for key %@ is %@",key , value); } } } /** * Encode the NSIBObjectData container */ - (void) encodeWithCoder: (NSCoder *)coder { if ([coder allowsKeyedCoding]) { NSArray *accessibilityOidsKeys = (NSArray *)NSAllMapTableKeys(_accessibilityOids); NSArray *accessibilityOidsValues = [self _valuesForKeys: accessibilityOidsKeys inMap: _accessibilityOids]; NSArray *classKeys = (NSArray *)NSAllMapTableKeys(_classes); NSArray *classValues = [self _valuesForKeys: classKeys inMap: _classes]; NSArray *nameKeys = (NSArray *)NSAllMapTableKeys(_names); NSArray *nameValues = [self _valuesForKeys: nameKeys inMap: _names]; NSArray *objectsKeys = (NSArray *)NSAllMapTableKeys(_objects); NSArray *objectsValues = [self _valuesForKeys: objectsKeys inMap: _objects]; NSArray *oidsKeys = (NSArray *)NSAllMapTableKeys(_oids); NSArray *oidsValues = [self _valuesForKeys: oidsKeys inMap: _oids]; [(NSKeyedArchiver *)coder setClassName: @"_NSCornerView" forClass: NSClassFromString(@"GSTableCornerView")]; [coder encodeObject: (id)_accessibilityConnectors forKey: @"NSAccessibilityConnectors"]; [coder encodeObject: (id) accessibilityOidsKeys forKey: @"NSAccessibilityOidsKeys"]; [coder encodeObject: (id) accessibilityOidsValues forKey: @"NSAccessibilityOidsValues"]; [coder encodeObject: (id) classKeys forKey: @"NSClassesKeys"]; [coder encodeObject: (id) classValues forKey: @"NSClassesValues"]; [coder encodeObject: (id) nameKeys forKey: @"NSNamesKeys"]; [coder encodeObject: (id) nameValues forKey: @"NSNamesValues"]; [coder encodeObject: (id) objectsKeys forKey: @"NSObjectsKeys"]; [coder encodeObject: (id) objectsValues forKey: @"NSObjectsValues"]; [coder encodeObject: (id) oidsKeys forKey: @"NSOidsKeys"]; [coder encodeObject: (id) oidsValues forKey: @"NSOidsValues"]; [coder encodeObject: (id) _connections forKey: @"NSConnections"]; [coder encodeObject: (id) _fontManager forKey: @"NSFontManager"]; [coder encodeObject: (id) _framework forKey: @"NSFramework"]; [coder encodeObject: (id) _visibleWindows forKey: @"NSVisibleWindows"]; [coder encodeInt: _nextOid forKey: @"NSNextOid"]; [coder encodeConditionalObject: (id) _root forKey: @"NSRoot"]; } else { [NSException raise: NSInvalidArgumentException format: @"Can't encode %@ with %@.",NSStringFromClass([self class]), NSStringFromClass([coder class])]; } } /** * Decode the NSIBObjectData container. */ - (id) initWithCoder: (NSCoder *)coder { if ([coder allowsKeyedCoding]) { NSArray *nameKeys = nil; NSArray *nameValues = nil; NSArray *classKeys = nil; NSArray *classValues = nil; NSArray *objectsKeys = nil; NSArray *objectsValues = nil; NSArray *oidsKeys = nil; NSArray *oidsValues = nil; NSArray *accessibilityOidsKeys = nil; NSArray *accessibilityOidsValues = nil; // // Get root, font, framwork and oid. // Retain objects since NSKeyedUnarchiver autoreleases unarchived objects. // ASSIGN(_root, [coder decodeObjectForKey: @"NSRoot"]); ASSIGN(_fontManager, [coder decodeObjectForKey: @"NSFontManager"]); ASSIGN(_framework, [coder decodeObjectForKey: @"NSFramework"]); _nextOid = [coder decodeIntForKey: @"NSNextOid"]; // get connections. ASSIGN(_connections, (NSMutableArray *) [coder decodeObjectForKey: @"NSConnections"]); ASSIGN(_accessibilityConnectors, (NSMutableArray *) [coder decodeObjectForKey: @"NSAccessibilityConnectors"]); // get visible windows ASSIGN(_visibleWindows, (NSMutableArray *) [coder decodeObjectForKey: @"NSVisibleWindows"]); // instantiate the maps.. _classes = NSCreateMapTable(NSObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 2); _names = NSCreateMapTable(NSObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 2); _objects = NSCreateMapTable(NSObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 2); // // Get the maps. There is no need to retain these, // since they are going to be placed into the NSMapTable // structures anyway. // nameKeys = (NSArray *) [coder decodeObjectForKey: @"NSNamesKeys"]; nameValues = (NSArray *) [coder decodeObjectForKey: @"NSNamesValues"]; classKeys = (NSArray *) [coder decodeObjectForKey: @"NSClassesKeys"]; classValues = (NSArray *) [coder decodeObjectForKey: @"NSClassesValues"]; objectsKeys = (NSArray *) [coder decodeObjectForKey: @"NSObjectsKeys"]; objectsValues = (NSArray *) [coder decodeObjectForKey: @"NSObjectsValues"]; // Fill in the maps... [self _buildMap: _classes withKeys: classKeys andValues: classValues]; [self _buildMap: _names withKeys: nameKeys andValues: nameValues]; [self _buildMap: _objects withKeys: objectsKeys andValues: objectsValues]; // // Only get these maps when in the editor. They // aren't useful outside of it and only waste memory if // unarchived in the live application. // if([NSClassSwapper isInInterfaceBuilder]) { // Only get these when in the editor... oidsKeys = (NSArray *) [coder decodeObjectForKey: @"NSOidsKeys"]; oidsValues = (NSArray *) [coder decodeObjectForKey: @"NSOidsValues"]; accessibilityOidsKeys = (NSArray *) [coder decodeObjectForKey: @"NSAccessibilityOidsKeys"]; accessibilityOidsValues = (NSArray *) [coder decodeObjectForKey: @"NSAccessibilityOidsValues"]; _accessibilityOids = NSCreateMapTable(NSObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 2); _oids = NSCreateMapTable(NSObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 2); [self _buildMap: _accessibilityOids withKeys: accessibilityOidsKeys andValues: accessibilityOidsValues]; [self _buildMap: _oids withKeys: oidsKeys andValues: oidsValues]; } // instantiate... _topLevelObjects = [[NSMutableSet alloc] init]; } else { [NSException raise: NSInvalidArgumentException format: @"Can't decode %@ with %@.",NSStringFromClass([self class]), NSStringFromClass([coder class])]; } return self; } /** * Initialize a new NSIBObjectData. */ - (id) init { if ((self = [super init]) != nil) { // instantiate the maps.. _objects = NSCreateMapTable(NSObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 2); _names = NSCreateMapTable(NSObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 2); _oids = NSCreateMapTable(NSObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 2); _classes = NSCreateMapTable(NSObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 2); _accessibilityOids = NSCreateMapTable(NSObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 2); // initialize the objects... _accessibilityConnectors = [[NSMutableArray alloc] init]; _connections = [[NSMutableArray alloc] init]; _visibleWindows = [[NSMutableArray alloc] init]; _framework = nil; _fontManager = nil; _root = nil; _nextOid = 0; } return self; } /** * Deallocate NSIBObjectData. */ - (void) dealloc { // free the maps. NSFreeMapTable(_objects); NSFreeMapTable(_names); NSFreeMapTable(_classes); // these are not allocated when not in interface builder. if([NSClassSwapper isInInterfaceBuilder]) { NSFreeMapTable(_oids); NSFreeMapTable(_accessibilityOids); } // free other objects. RELEASE(_accessibilityConnectors); RELEASE(_connections); RELEASE(_fontManager); RELEASE(_framework); RELEASE(_visibleWindows); RELEASE(_root); RELEASE(_topLevelObjects); [super dealloc]; } /** * Call nibInstantiate on an object, if it responds to the nibInstantiate selector. */ - (id)instantiateObject: (id)obj { id newObject = obj; if ([obj respondsToSelector: @selector(nibInstantiate)]) { newObject = [obj nibInstantiate]; } return newObject; } /** * Instantiate all of the objects in the nib file. */ - (void) nibInstantiateWithOwner: (id)owner topLevelObjects: (NSMutableArray *)topLevelObjects { NSEnumerator *en = [_connections objectEnumerator]; NSArray *objs = NSAllMapTableKeys([self names]); id obj = nil; id menu = nil; // set the new root object. [_root setRealObject: owner]; // iterate over connections, instantiate, and then establish them. while ((obj = [en nextObject]) != nil) { if ([obj respondsToSelector: @selector(instantiateWithInstantiator:)]) { [obj instantiateWithInstantiator: self]; [obj establishConnection]; } } // iterate over all objects instantiate windows, awaken objects and fill // in top level array. en = [objs objectEnumerator]; while ((obj = [en nextObject]) != nil) { // instantiate all windows and fill in the top level array. if ([obj isKindOfClass: [NSWindowTemplate class]]) { if ([obj realObject] == nil) { obj = [self instantiateObject: obj]; [topLevelObjects addObject: obj]; } } else { id v = NSMapGet(_objects, obj); if (v == nil || v == owner) { [topLevelObjects addObject: obj]; } } // awaken the object. if ([obj respondsToSelector: @selector(awakeFromNib)]) { [obj awakeFromNib]; } } // bring visible windows to front... en = [_visibleWindows objectEnumerator]; while ((obj = [en nextObject]) != nil) { id w = [obj realObject]; [w orderFront: self]; } // add the menu... menu = [self objectForName: @"MainMenu"]; if (menu != nil) { menu = [self instantiateObject: menu]; [NSApp _setMainMenu: menu]; } } /** * Awake after loading the nib and extract the top level and owner for nib instantiation, * then call nibInstantateWithOwner:topLevelObjects: */ - (void) awakeWithContext: (NSDictionary *)context { NSMutableArray *tlo = [context objectForKey: @"NSTopLevelObjects"]; id owner = [context objectForKey: @"NSOwner"]; // get using the alternate names. if(tlo == nil) { tlo = [context objectForKey: @"NSNibTopLevelObjects"]; } if(owner == nil) { owner = [context objectForKey: @"NSNibOwner"]; } // instantiate... [self nibInstantiateWithOwner: owner topLevelObjects: tlo]; } /** * Retrieve an object by name from the map. */ - (id) objectForName: (NSString *)name { NSArray *nameKeys = (NSArray *)NSAllMapTableKeys(_names); NSArray *nameValues = (NSArray *)NSAllMapTableValues(_names); int i = [nameValues indexOfObject: name]; id result = nil; if (i != NSNotFound) { result = [nameKeys objectAtIndex: i]; } return result; } /** * Get the name for an object. */ - (NSString *) nameForObject: (id)obj { NSArray *nameKeys = (NSArray *)NSAllMapTableKeys(_names); NSArray *nameValues = (NSArray *)NSAllMapTableValues(_names); int i = [nameKeys indexOfObject: obj]; NSString *result = [nameValues objectAtIndex: i]; return result; } /** * Set the root object. */ - (void) setRoot: (id) root { ASSIGN(_root, root); } /** * Return the root object. */ - (id) root { return _root; } /** * Set the value of the next available oid. */ - (void) setNextOid: (int)noid { _nextOid = noid; } /** * Get the value of the next available oid. */ - (int) nextOid { return _nextOid; } /** * Connections between objects. */ - (NSMutableArray *) connections { return _connections; } /** * Set of top level objects. */ - (NSMutableSet *) topLevelObjects { return _topLevelObjects; } /** * Names to objects */ - (NSMutableDictionary *) nameTable { return nil; } /** * Set of all visible windows. */ - (NSMutableArray *) visibleWindows { return _visibleWindows; } /** * Objects to names table. */ - (NSMapTable *) objects { return _objects; } /** * Names to objects table. */ - (NSMapTable *) names { return _names; } /** * Classes to objects table. */ - (NSMapTable *) classes { return _classes; } /** * Oids to objects table. */ - (NSMapTable *) oids { return _oids; } @end /** * NSButtonImageSource * * This class is used by buttons to pull the correct image based on a given state. */ @implementation NSButtonImageSource - (id) initWithCoder: (NSCoder *)coder { if ([coder allowsKeyedCoding]) { ASSIGN(imageName, [coder decodeObjectForKey: @"NSImageName"]); } else { [NSException raise: NSInvalidArgumentException format: @"Can't decode %@ with %@.",NSStringFromClass([self class]), NSStringFromClass([coder class])]; } RELEASE(self); return RETAIN([NSImage imageNamed: imageName]); } - (void) encodeWithCoder: (NSCoder *)coder { if ([coder allowsKeyedCoding]) { [coder encodeObject: imageName forKey: @"NSImageName"]; } else { [NSException raise: NSInvalidArgumentException format: @"Can't encode %@ with %@.",NSStringFromClass([self class]), NSStringFromClass([coder class])]; } } /** * Initializes with image name. */ - (id) initWithImageNamed: (NSString *)name { if ((self = [super init]) != nil) { ASSIGN(imageName,name); } return self; } /** * Returns imageName. */ - (NSString *)imageName { return imageName; } - (void) dealloc { RELEASE(imageName); [super dealloc]; } @end @implementation NSIBHelpConnector - (id) init { if ((self = [super init]) != nil) { _file = nil; _marker = @"NSToolTipHelpKey"; } return self; } - (id) initWithCoder: (NSCoder *)coder { if ((self = [super initWithCoder: coder]) != nil) { if ([coder allowsKeyedCoding]) { if ([coder containsValueForKey: @"NSFile"]) { _file = RETAIN([coder decodeObjectForKey: @"NSFile"]); } if ([coder containsValueForKey: @"NSMarker"]) { _marker = RETAIN([coder decodeObjectForKey: @"NSMarker"]); } } else { _file = RETAIN([coder decodeObject]); _marker = RETAIN([coder decodeObject]); } } return self; } - (void) encodeWithCoder: (NSCoder *)coder { [super encodeWithCoder: coder]; if ([coder allowsKeyedCoding]) { if (_file != nil) { [coder encodeObject: _file forKey: @"NSFile"]; } if (_marker != nil) { [coder encodeObject: _file forKey: @"NSMarker"]; } } else { [coder encodeObject: _file]; [coder encodeObject: _marker]; } } - (void) establishConnection { if([_dst respondsToSelector: @selector(setToolTip:)]) { [_dst setToolTip: _marker]; } } - (void) setFile: (id)file { ASSIGN(_file, file); } - (id) file { return _file; } - (void) setMarker: (id)marker { ASSIGN(_marker, marker); } - (id) marker { return _marker; } @end @implementation NSDecimalNumberPlaceholder - (id) initWithCoder: (NSCoder *)coder { NSDecimalNumber *dn = nil; if ([coder allowsKeyedCoding]) { unsigned int len = 0; short exponent = (short)[coder decodeIntForKey: @"NS.exponent"]; NSByteOrder bo = [coder decodeIntForKey: @"NS.mantissa.bo"]; BOOL negative = [coder decodeBoolForKey: @"NS.negative"]; void *mantissaBytes = (void *)[coder decodeBytesForKey: @"NS.mantissa" returnedLength: &len]; unsigned long long unswapped = 0; unsigned long long mantissa = 0; // BOOL compact = [coder decodeBoolForKey: @"NS.compact"]; // int length = [coder decodeIntForKey: @"NS.length"]; memcpy((void *)&unswapped, (void *)mantissaBytes, sizeof(unsigned long long)); switch(bo) { case NS_BigEndian: mantissa = NSSwapBigLongLongToHost(unswapped); break; case NS_LittleEndian: mantissa = NSSwapLittleLongLongToHost(unswapped); break; default: break; } dn = [[NSDecimalNumber alloc] initWithMantissa: mantissa exponent: exponent isNegative: negative]; } // FIXME: Needs to release self return dn; } @end /** * NSCornerView * * Overridden in NSTableView to be GSTableCornerView, * but the class needs to be present to be overridden. * * Currently this is a place-holder class. */ @implementation _NSCornerView @end /** * NSPSMatrix. * * This class is needed for nib encoding/decoding by transforms. * Currently it's only referenced in the NSProgressIndicator, * as far as I can tell. * * Place holder class. */ @implementation NSPSMatrix - (void) encodeWithCoder: (NSCoder *)coder { // do nothing... just encoding the presence of the class. } - (id) initWithCoder: (NSCoder *)coder { // NSLog(@"NSPSMatrix = %@",[(NSKeyedUnarchiver *)coder keyMap]); return self; } @end