1/** <title>NSActionCell</title>
2
3   <abstract>Abstract cell for target/action paradigm</abstract>
4
5   Copyright (C) 1996-1999 Free Software Foundation, Inc.
6
7   Author:  Scott Christley <scottc@net-community.com>
8   Date: 1996
9
10   This file is part of the GNUstep GUI Library.
11
12   This library is free software; you can redistribute it and/or
13   modify it under the terms of the GNU Lesser General Public
14   License as published by the Free Software Foundation; either
15   version 2 of the License, or (at your option) any later version.
16
17   This library is distributed in the hope that it will be useful,
18   but WITHOUT ANY WARRANTY; without even the implied warranty of
19   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
20   Lesser General Public License for more details.
21
22   You should have received a copy of the GNU Lesser General Public
23   License along with this library; see the file COPYING.LIB.
24   If not, see <http://www.gnu.org/licenses/> or write to the
25   Free Software Foundation, 51 Franklin Street, Fifth Floor,
26   Boston, MA 02110-1301, USA.
27*/
28
29#import "config.h"
30#import <Foundation/NSCoder.h>
31
32#import "AppKit/NSActionCell.h"
33#import "AppKit/NSControl.h"
34
35@implementation NSActionCell
36
37static Class controlClass;
38
39/*
40 * Class methods
41 */
42+ (void) initialize
43{
44  if (self == [NSActionCell class])
45    {
46      controlClass = [NSControl class];
47      [self setVersion: 1];
48    }
49}
50
51/*
52 * Instance methods
53 */
54
55/*
56 * Configuring an NSActionCell
57 */
58
59/**
60 * Sets the alignment of text within the receiver.
61 */
62- (void) setAlignment: (NSTextAlignment)mode
63{
64  [super setAlignment: mode];
65  if (_control_view)
66    if ([_control_view isKindOfClass: controlClass])
67      [(NSControl *)_control_view updateCell: self];
68}
69
70/**
71 * If <code>YES</code> then the receiver is drawn with a bezeled border.
72 */
73- (void) setBezeled: (BOOL)flag
74{
75  _cell.is_bezeled = flag;
76  if (_cell.is_bezeled)
77    _cell.is_bordered = NO;
78  if (_control_view)
79    if ([_control_view isKindOfClass: controlClass])
80      [(NSControl *)_control_view updateCell: self];
81}
82
83/**
84 * If <code>YES</code> then receiver is drawn with a border.
85 */
86- (void) setBordered: (BOOL)flag
87{
88  _cell.is_bordered = flag;
89  if (_cell.is_bordered)
90    _cell.is_bezeled = NO;
91  if (_control_view)
92    if ([_control_view isKindOfClass: controlClass])
93      [(NSControl *)_control_view updateCell: self];
94}
95
96/**
97 * If <code>YES</code> then the receiver is capable of accepting input.
98 */
99- (void) setEnabled: (BOOL)flag
100{
101  _cell.is_disabled = !flag;
102  if (_control_view)
103    if ([_control_view isKindOfClass: controlClass])
104      [(NSControl *)_control_view updateCell: self];
105}
106
107- (void) setFloatingPointFormat: (BOOL)autoRange
108			   left: (NSUInteger)leftDigits
109			  right: (NSUInteger)rightDigits
110{
111  [super setFloatingPointFormat: autoRange
112	 left: leftDigits
113	 right: rightDigits];
114  if (_control_view)
115    if ([_control_view isKindOfClass: controlClass])
116      [(NSControl *)_control_view updateCell: self];
117}
118
119/**
120 * Sets the font to be used in the receiver.
121 */
122- (void) setFont: (NSFont*)fontObject
123{
124  [super setFont: fontObject];
125  if (_control_view)
126    if ([_control_view isKindOfClass: controlClass])
127      [(NSControl *)_control_view updateCell: self];
128  // TODO: This should also set the font of the text object, when selected
129}
130
131/**
132 * Sets the image to be displayed in the receiver.
133 */
134- (void) setImage: (NSImage*)image
135{
136  [super setImage: image];
137  if (_control_view)
138    if ([_control_view isKindOfClass: controlClass])
139      [(NSControl *)_control_view updateCell: self];
140}
141
142/*
143 * Manipulating NSActionCell Values
144 */
145
146/**
147 * Retrieve the value of the receiver
148 */
149- (id) objectValue
150{
151  if (_cell.in_editing && _control_view)
152    if ([_control_view isKindOfClass: controlClass])
153      [(NSControl *)_control_view validateEditing];
154  return [super objectValue];
155}
156
157/**
158 * Retrieve the value of the receiver as an NSAttributedString.
159 */
160- (NSAttributedString*) attributedStringValue
161{
162  if (_cell.in_editing && _control_view)
163    if ([_control_view isKindOfClass: controlClass])
164      [(NSControl *)_control_view validateEditing];
165  return [super attributedStringValue];
166}
167
168/**
169 * Retrieve the value of the receiver as an NSString.
170 */
171- (NSString *) stringValue
172{
173  if (_cell.in_editing && _control_view)
174    if ([_control_view isKindOfClass: controlClass])
175      [(NSControl *)_control_view validateEditing];
176  return [super stringValue];
177}
178
179/**
180 * Retrieve the value of the receiver as a double.
181 */
182- (double) doubleValue
183{
184  if (_cell.in_editing && _control_view)
185    if ([_control_view isKindOfClass: controlClass])
186      [(NSControl *)_control_view validateEditing];
187  return [super doubleValue];
188}
189
190/**
191 * Retrieve the value of the receiver as a float.
192 */
193- (float) floatValue
194{
195  if (_cell.in_editing && _control_view)
196    if ([_control_view isKindOfClass: controlClass])
197      [(NSControl *)_control_view validateEditing];
198  return [super floatValue];
199}
200
201/**
202 * Retrieve the value of the receiver as an int.
203 */
204- (int) intValue
205{
206  if (_cell.in_editing && _control_view)
207    if ([_control_view isKindOfClass: controlClass])
208      [(NSControl *)_control_view validateEditing];
209  return [super intValue];
210}
211
212/**
213 * Retrieve the value of the receiver as an NSInteger.
214 */
215- (NSInteger) integerValue
216{
217  if (_cell.in_editing && _control_view)
218    if ([_control_view isKindOfClass: controlClass])
219      [(NSControl *)_control_view validateEditing];
220  return [super integerValue];
221}
222
223/**
224 * Set the value of the receiver from anObject.
225 */
226- (void) setObjectValue: (id)anObject
227{
228  [super setObjectValue: anObject];
229  if (_control_view)
230    {
231	if ([_control_view isKindOfClass: controlClass])
232	{
233	  if (_cell.in_editing)
234	    {
235	      [self _updateFieldEditor:
236		      [(NSControl *)_control_view currentEditor]];
237	    }
238          else
239            {
240              [(NSControl *)_control_view updateCell: self];
241            }
242	}
243    }
244}
245
246/**
247 * Set the value of the receiver from aString.
248 */
249// This method is currently needed, as NSCells implementation
250// sometimes does not call setObjectValue:
251- (void) setStringValue: (NSString*)aString
252{
253  [super setStringValue: aString];
254  if (_control_view)
255    {
256      if ([_control_view isKindOfClass: controlClass])
257	{
258	  if (_cell.in_editing)
259	    {
260	      [self _updateFieldEditor:
261		      [(NSControl *)_control_view currentEditor]];
262	    }
263          else
264            {
265              [(NSControl *)_control_view updateCell: self];
266            }
267	}
268    }
269}
270
271- (void) setAttributedStringValue: (NSAttributedString*)attribStr
272{
273  [super setAttributedStringValue: attribStr];
274  if (_control_view)
275    {
276      if ([_control_view isKindOfClass: controlClass])
277	{
278	  if (_cell.in_editing)
279	    {
280	      [self _updateFieldEditor:
281		      [(NSControl *)_control_view currentEditor]];
282	    }
283          else
284            {
285              [(NSControl *)_control_view updateCell: self];
286            }
287	}
288    }
289}
290
291/*
292 * Target and Action
293 */
294
295/**
296 * Retrieve the action from the receiver.
297 */
298- (SEL) action
299{
300  return _action;
301}
302
303/**
304 * Set the action in the receiver as the selector aSelector.
305 */
306- (void) setAction: (SEL)aSelector
307{
308  _action = aSelector;
309}
310
311/**
312 * Set the target in the receiver as anObject.  NSActionCell does not retain its target!
313 */
314- (void) setTarget: (id)anObject
315{
316  _target = anObject;
317}
318
319/**
320 * Return the target of the receiver.
321 */
322- (id) target
323{
324  return _target;
325}
326
327/**
328 * Assigning a Tag.
329 */
330- (void) setTag: (NSInteger)anInt
331{
332  _tag = anInt;
333}
334
335/**
336 * Return the tag.
337 */
338- (NSInteger) tag
339{
340  return _tag;
341}
342
343/**
344 * Returns the control view of the receiver.
345 */
346-(NSView *) controlView
347{
348  return _control_view;
349}
350
351/**
352 * Set the control view of the receiver.
353 */
354- (void) setControlView: (NSView*)view
355{
356  _control_view = view;
357}
358
359- (void) drawWithFrame: (NSRect)cellFrame inView: (NSView*)controlView
360{
361  if (_control_view != controlView)
362    _control_view = controlView;
363
364  [super drawWithFrame: cellFrame
365	 inView: controlView];
366}
367
368/*
369 * NSCoding protocol
370 */
371- (void) encodeWithCoder: (NSCoder*)aCoder
372{
373  [super encodeWithCoder: aCoder];
374  if ([aCoder allowsKeyedCoding])
375    {
376      [aCoder encodeInteger: [self tag] forKey: @"NSTag"];
377      if ([self target] != nil)
378	{
379	  [aCoder encodeObject: [self target] forKey: @"NSTarget"];
380	}
381      if ([self action] != NULL)
382	{
383	  [aCoder encodeObject: NSStringFromSelector([self action]) forKey: @"NSAction"];
384	}
385      [aCoder encodeObject: _control_view forKey: @"NSControlView"];
386    }
387  else
388    {
389      [aCoder encodeValueOfObjCType: @encode(NSInteger) at: &_tag];
390      [aCoder encodeConditionalObject: _target];
391      [aCoder encodeValueOfObjCType: @encode(SEL) at: &_action];
392      // This is only encoded for backward compatibility and won't be decoded.
393      [aCoder encodeConditionalObject: nil];
394    }
395}
396
397- (id) initWithCoder: (NSCoder*)aDecoder
398{
399  self = [super initWithCoder: aDecoder];
400  if (!self)
401    return nil;
402
403  if ([aDecoder allowsKeyedCoding])
404    {
405      if ([aDecoder containsValueForKey: @"NSTag"])
406        {
407	  [self setTag: [aDecoder decodeIntegerForKey: @"NSTag"]];
408	}
409      if ([aDecoder containsValueForKey: @"NSTarget"])
410	{
411	  [self setTarget: [aDecoder decodeObjectForKey: @"NSTarget"]];
412	}
413      if ([aDecoder containsValueForKey: @"NSAction"])
414        {
415	  NSString *action = [aDecoder decodeObjectForKey: @"NSAction"];
416	  [self setAction: NSSelectorFromString(action)];
417	}
418    }
419  else
420    {
421      id dummy;
422
423      [aDecoder decodeValueOfObjCType: @encode(NSInteger) at: &_tag];
424      _target = [aDecoder decodeObject];
425      [aDecoder decodeValueOfObjCType: @encode(SEL) at: &_action];
426      // Don't decode _control_view, as this may no longer be valid.
427      dummy = [aDecoder decodeObject];
428    }
429
430  return self;
431}
432
433@end
434