1/* GormPrivate.m
2 *
3 * Copyright (C) 1999, 2003 Free Software Foundation, Inc.
4 *
5 * Author:	Richard Frith-Macdonald <richard@brainstrom.co.uk>
6 * Author:	Gregory John Casamento <greg_casamento@yahoo.com>
7 * Date:	1999, 2003, 2004
8 *
9 * This file is part of GNUstep.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
24 */
25
26#include "GormPrivate.h"
27#include "GormFontViewController.h"
28#include "GormSetNameController.h"
29#include "GNUstepGUI/GSNibLoading.h"
30#include "GNUstepBase/GSObjCRuntime.h"
31
32// for templates...
33#include <AppKit/NSControl.h>
34#include <AppKit/NSButton.h>
35
36NSString *GormToggleGuidelineNotification = @"GormToggleGuidelineNotification";
37NSString *GormDidModifyClassNotification = @"GormDidModifyClassNotification";
38NSString *GormDidAddClassNotification = @"GormDidAddClassNotification";
39NSString *GormDidDeleteClassNotification = @"GormDidDeleteClassNotification";
40NSString *GormWillDetachObjectFromDocumentNotification = @"GormWillDetachObjectFromDocumentNotification";
41NSString *GormResizeCellNotification = @"GormResizeCellNotification";
42
43// Private, and soon to be deprecated, notification string...
44NSString *GSInternalNibItemAddedNotification = @"_GSInternalNibItemAddedNotification";
45
46// Define this as "NO" initially.   We only want to turn this on while loading or testing.
47static BOOL _isInInterfaceBuilder = NO;
48
49@class	InfoPanel;
50
51// we had this include for grouping/ungrouping selectors
52#include "GormViewWithContentViewEditor.h"
53
54@implementation GSNibItem (GormAdditions)
55- (id) initWithClassName: (NSString*)className frame: (NSRect)frame
56{
57  if((self = [super init]) != nil)
58    {
59      theClass = [className copy];
60      theFrame = frame;
61    }
62  return self;
63}
64
65- (id) initWithClassName: (NSString*)className
66{
67  return [self initWithClassName: className
68	       frame: NSMakeRect(0,0,0,0)];
69}
70
71- (NSString*) className
72{
73  return theClass;
74}
75@end
76
77@interface NSObject (GormPrivate)
78// + (void) poseAsClass: (Class)aClassObject;
79+ (BOOL) canSubstituteForClass: (Class)origClass;
80@end
81
82@implementation NSObject (GormPrivate)
83/*
84+ (void) poseAsClass: (Class)aClassObject
85{
86  // disable poseAs: while in Gorm.
87  class_pose_as(self, aClassObject);
88  NSLog(@"WARNING: poseAs: called in Gorm.");
89}
90*/
91
92+ (BOOL) canSubstituteForClass: (Class)origClass
93{
94  if(self == origClass)
95    {
96      return YES;
97    }
98  else if([self isSubclassOfClass: origClass])
99    {
100      Class cls = self;
101      while(cls != nil && cls != origClass)
102	{
103	  if(GSGetMethod(cls, @selector(initWithCoder:), YES, NO) != NULL &&
104	     GSGetMethod(cls, @selector(encodeWithCoder:), YES, NO) != NULL)
105	    {
106	      return NO;
107	    }
108	  cls = GSObjCSuper(cls); // get super class
109	}
110      return YES;
111    }
112
113  return NO;
114}
115@end
116
117@implementation GormObjectProxy
118/*
119 * Perhaps this would be better to have a dummy initProxyWithCoder
120 * in GSNibItem class, so that we are not dependent on actual coding
121 * order of the ivars ?
122 */
123- (id) initWithCoder: (NSCoder*)aCoder
124{
125  if([aCoder allowsKeyedCoding])
126    {
127      ASSIGN(theClass, [aCoder decodeObjectForKey: @"NSClassName"]);
128      theFrame = NSZeroRect;
129      return self;
130    }
131  else
132    {
133      NSUInteger version = [aCoder versionForClassName:
134			      NSStringFromClass([GSNibItem class])];
135      NSInteger cv = [aCoder versionForClassName:
136			 NSStringFromClass([GSNibContainer class])];
137
138      if (version == NSNotFound)
139	{
140	  NSLog(@"no GSNibItem");
141	  version = [aCoder versionForClassName:
142			      NSStringFromClass([GormObjectProxy class])];
143	}
144
145      // add to the top level items during unarchiving, if the container is old.
146      if (cv == 0)
147	{
148	  NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
149	  [nc postNotificationName: GSInternalNibItemAddedNotification
150	      object: self];
151	}
152
153      if (version == 0)
154	{
155	  // do not decode super (it would try to morph into theClass ! )
156	  [aCoder decodeValueOfObjCType: @encode(id) at: &theClass];
157	  theFrame = [aCoder decodeRect];
158	  RETAIN(theClass); // release in dealloc of GSNibItem...
159
160	  return self;
161	}
162      else if (version == 1)
163	{
164	  // do not decode super (it would try to morph into theClass ! )
165	  [aCoder decodeValueOfObjCType: @encode(id) at: &theClass];
166	  theFrame = [aCoder decodeRect];
167	  [aCoder decodeValueOfObjCType: @encode(unsigned int)
168		  at: &autoresizingMask];
169	  RETAIN(theClass); // release in dealloc of GSNibItem...
170
171	  return self;
172	}
173      else
174	{
175	  NSLog(@"no initWithCoder for version %d", (int)version);
176	  RELEASE(self);
177	  return nil;
178	}
179    }
180  return nil;
181}
182
183- (void) encodeWithCoder: (NSCoder *)coder
184{
185  if([coder allowsKeyedCoding])
186    {
187      [coder encodeObject: theClass
188	     forKey: @"NSClassName"];
189    }
190  else
191    {
192      [super encodeWithCoder: coder];
193    }
194}
195
196- (NSString*) inspectorClassName
197{
198  return @"GormNotApplicableInspector";
199}
200
201- (NSString*) classInspectorClassName
202{
203  return @"GormNotApplicableInspector";
204}
205
206- (void) setClassName: (NSString *)className
207{
208  ASSIGNCOPY(theClass, className);
209}
210
211- (NSImage *) imageForViewer
212{
213  NSImage *image = [super imageForViewer];
214  if([theClass isEqual: @"NSFontManager"])
215    {
216      NSBundle	*bundle = [NSBundle mainBundle];
217      NSString *path = [bundle pathForImageResource: @"GormFontManager"];
218      image = [[NSImage alloc] initWithContentsOfFile: path];
219    }
220  return image;
221}
222
223@end
224
225// define the class proxy...
226@implementation GormClassProxy
227- (id) initWithClassName: (NSString *)n
228{
229  self = [super init];
230  if (self != nil)
231    {
232      if([n isKindOfClass: [NSString class]])
233	{
234	  // create a copy.
235	  ASSIGNCOPY(name, n);
236	}
237      else
238	{
239	  NSLog(@"Attempt to add a class proxy with className = %@",n);
240	}
241    }
242  return self;
243}
244
245- (void) dealloc
246{
247  RELEASE(name);
248  [super dealloc];
249}
250
251- (NSString*) className
252{
253  return name;
254}
255
256- (NSString*) inspectorClassName
257{
258  return @"GormClassInspector";
259}
260
261- (NSString*) classInspectorClassName
262{
263  return @"GormNotApplicableInspector";
264}
265
266- (NSString*) connectInspectorClassName
267{
268  return @"GormNotApplicableInspector";
269}
270
271- (NSString*) sizeInspectorClassName
272{
273  return @"GormNotApplicableInspector";
274}
275@end
276
277// custom class additions...
278@implementation GSClassSwapper (GormCustomClassAdditions)
279+ (void) setIsInInterfaceBuilder: (BOOL)flag
280{
281  _isInInterfaceBuilder = flag;
282}
283
284- (BOOL) isInInterfaceBuilder
285{
286  return _isInInterfaceBuilder;
287}
288@end
289
290@implementation IBResourceManager (GormAdditions)
291+ (void) registerForAllPboardTypes: (id)editor
292			inDocument: (id)doc
293{
294  NSArray *allTypes = [doc allManagedPboardTypes];
295  [editor registerForDraggedTypes: allTypes];
296}
297@end
298
299
300