/**
Returns whether the NSTextField is editable. By default a NSTextField is not editable.
See Also: -setEditable: [NSCell-isEditable]
*/ - (BOOL) isEditable { return [_cell isEditable]; } /**Returns whether the NSTextField is selectable.
See Also: -setSelectable: [NSCell-isSelectable]
*/ - (BOOL) isSelectable { return [_cell isSelectable]; } /**Sets whether the NSTextField's cell and the NSText object is editable. By default a NSTextField is not editable.
See Also: -isEditable [NSCell-setEditable:] [NSText-setEditable:]
*/ - (void) setEditable: (BOOL)flag { [_cell setEditable: flag]; if (_text_object) [_text_object setEditable: flag]; } /**Sets whether the NSTextField's cell and the NSText object is selectable.
See Also: -isSelectable [NSTextFieldCell-setSelectable:] [NSText-setSelectable:]
*/ - (void) setSelectable: (BOOL)flag { [_cell setSelectable: flag]; if (_text_object) [_text_object setSelectable: flag]; } /**Selects all the text of the NSTextField if it's selectable.
*/ - (void) selectText: (id)sender { if ([self isSelectable] && (_super_view != nil)) { if (_text_object) [_text_object selectAll: self]; else { NSText *text = [_window fieldEditor: YES forObject: self]; int length; if ([text superview] != nil) if ([text resignFirstResponder] == NO) return; // [NSCursor hide]; /* [self stringValue] generates a call to validateEditing so we need to call it before setting up the _text_object */ length = [[self stringValue] length]; _text_object = [_cell setUpFieldEditorAttributes: text]; [_cell selectWithFrame: _bounds inView: self editor: _text_object delegate: self start: 0 length: length]; } } } /**Returns the object selected when the user presses the TAB key.
See Also: -setNextText: [NSView-nextKeyView]
*/ - (id) nextText { return [self nextKeyView]; } /**Returns the object selected when the user presses the Shift-TAB key.
See Also: -setPreviousText: [NSView-previousKeyView]
*/ - (id) previousText { return [self previousKeyView]; } /**Sets the object selected when the user presses the TAB key to anObject.
See Also: -nextText [NSView-setNextKeyView:]
*/ - (void) setNextText: (id)anObject { [self setNextKeyView: anObject]; } /**Sets the object selected when the user presses the shift-TAB key to anObject.
See Also: -previousText [NSView-setPreviousKeyView:]
*/ - (void) setPreviousText: (id)anObject { [self setPreviousKeyView: anObject]; } /**Sets the delegate to anObject.
See Also: -delegate
*/ - (void) setDelegate: (id)anObject { if (_delegate) [nc removeObserver: _delegate name: nil object: self]; _delegate = anObject; #define SET_DELEGATE_NOTIFICATION(notif_name) \ if ([_delegate respondsToSelector: @selector(controlText##notif_name:)]) \ [nc addObserver: _delegate \ selector: @selector(controlText##notif_name:) \ name: NSControlText##notif_name##Notification object: self] SET_DELEGATE_NOTIFICATION(DidBeginEditing); SET_DELEGATE_NOTIFICATION(DidEndEditing); SET_DELEGATE_NOTIFICATION(DidChange); } /**Returns the delegate object.
See Also: -setDelegate:
*/ - (id) delegate { return _delegate; } /**Sets the color used to draw the background to aColor.
See Also: -backgroundColor -setDrawsBackground: -drawsBackground [NSTextFieldCell-setBackgroundColor:]
*/ - (void) setBackgroundColor: (NSColor *)aColor { [_cell setBackgroundColor: aColor]; } /**Returns the color used to draw the background.
See Also: -setBackgroundColor: setDrawsBackground: -drawsBackground [NSTextFieldCell-backgroundColor]
*/ - (NSColor *) backgroundColor { return [_cell backgroundColor]; } /**Returns whether the NSTextField draws the background. By default NO.
See Also: -setDrawsBackground: [NSTextFieldCell-drawsBackground]
*/ - (BOOL) drawsBackground { return [_cell drawsBackground]; } /**Returns whether the NSTextField's cell has bezeled border.
See Also: -setBezeled: [NSTextFieldCell-isBezeled]
*/ - (BOOL) isBezeled { return [_cell isBezeled]; } /**Returns whether the NSTextField's cell has border.
See Also: -setBordered: [NSTextFieldCell-isBordered]
*/ - (BOOL) isBordered { return [_cell isBordered]; } /**Sets whether the NSTextField's cell has bezeled border.
See Also: -isBezeled [NSTextFieldCell-setBezeled:]
*/ - (void) setBezeled: (BOOL)flag { [_cell setBezeled: flag]; } /**Sets whether the NSTextField's cell has border.
See Also: -isBordered [NSTextFieldCell-setBordered:]
*/ - (void) setBordered: (BOOL)flag { [_cell setBordered: flag]; } /**Sets whether the NSTextField draws the background. By default NO.
See Also: -drawsBackground [NSTextFieldCell-setDrawsBackground:]
*/ - (void) setDrawsBackground: (BOOL)flag { [_cell setDrawsBackground: flag]; } /**Sets the color with which the text will be draw to aColor.
See Also: -textColor [NSTextFieldCell-setTextColor:]
*/ - (void) setTextColor: (NSColor *)aColor { [_cell setTextColor: aColor]; } /**Returns the colour used to draw the text.
See Also: -setTextColor: [NSTextFieldCell-textColor]
*/ - (NSColor *) textColor { return [_cell textColor]; } // // Target and Action // - (SEL) errorAction { return _error_action; } - (void) setErrorAction: (SEL)aSelector { _error_action = aSelector; } // // Handling Events // - (void) mouseDown: (NSEvent*)theEvent { if ([self isSelectable] == NO) { [super mouseDown: theEvent]; return; } /* NB: If we're receiving this click from the NSWindow, we expect _text_object to never be nil here, since NSWindow makes the NSTextField the first responder (which invokes its -becomeFirstResponder:, which invokes its -selectText:, which, if it is selectable, sets up the _text_object, then makes the _text_object first responder!) before calling its -mouseDown:. Only the first click should go via here; further clicks will be sent directly by the NSWindow to the _text_object. */ if (_text_object) { [_text_object mouseDown: theEvent]; return; } else { /* I suppose you could get here in subclasses which override * -becomeFirstResponder not to select the text. In that case, * we set up the _text_object manually to start editing here. */ /* Make sure we have first responder status when we start edit. * This does nothing if we are already first responder; but * (important!) it implicitly should free the fieldEditor if it * was in use by another control. */ if ([_window makeFirstResponder: self]) { NSText *t = [_window fieldEditor: YES forObject: self]; if ([t superview] != nil) { /* Can't take the field editor ... give up. */ return; } _text_object = [_cell setUpFieldEditorAttributes: t]; [_cell editWithFrame: _bounds inView: self editor: _text_object delegate: self event: theEvent]; } } } - (BOOL) acceptsFirstMouse: (NSEvent *)aEvent { return [self isEditable]; } /**Returns whether the NSTextField accepts to be the first responder. This method returns YES if the NSTextField is selectable and if there is no NSText object
See Also: -becomeFirstResponder -isSelectable [NSView-acceptsFirstResponder]
*/ - (BOOL) acceptsFirstResponder { // we do not accept first responder if there is already a // _text_object, else it would make the _text_object resign // and end editing return (_text_object == nil) && [self isSelectable]; } - (BOOL) becomeFirstResponder { if ([self acceptsFirstResponder]) { [self selectText: self]; return YES; } else { return NO; } } -(BOOL) needsPanelToBecomeKey { return [self isEditable]; } - (BOOL) abortEditing { if (_text_object) { [_cell endEditing: _text_object]; _text_object = nil; return YES; } else return NO; } - (NSText *) currentEditor { if (_text_object && ([_window firstResponder] == _text_object)) return _text_object; else return nil; } - (void) validateEditing { if (_text_object) { NSFormatter *formatter; NSString *string; formatter = [_cell formatter]; string = AUTORELEASE ([[_text_object text] copy]); if (formatter == nil) { [_cell setStringValue: string]; } else { id newObjectValue; NSString *error; if ([formatter getObjectValue: &newObjectValue forString: string errorDescription: &error] == YES) { [_cell setObjectValue: newObjectValue]; } else { if ([_delegate control: self didFailToFormatString: string errorDescription: error] == YES) { [_cell setStringValue: string]; } } } } } /**Posts a NSControlTextDidBeginEditingNotification notification with object self and a NSDictionary containing the NSFieldEditor for key as user Info
*/ - (void) textDidBeginEditing: (NSNotification *)aNotification { NSDictionary *notifDict; notifDict = [NSDictionary dictionaryWithObject:[aNotification object] forKey: @"NSFieldEditor"]; [nc postNotificationName: NSControlTextDidBeginEditingNotification object: self userInfo: notifDict]; } - (void) textDidChange: (NSNotification *)aNotification { NSDictionary *d; NSFormatter *formatter; d = [NSDictionary dictionaryWithObject: [aNotification object] forKey: @"NSFieldEditor"]; [nc postNotificationName: NSControlTextDidChangeNotification object: self userInfo: d]; formatter = [_cell formatter]; if (formatter != nil) { /* * FIXME: This part needs heavy interaction with the yet to finish * text system. * */ NSString *partialString; NSString *newString = nil; NSString *error = nil; BOOL wasAccepted; partialString = [_text_object string]; wasAccepted = [formatter isPartialStringValid: partialString newEditingString: &newString errorDescription: &error]; if (wasAccepted == NO) { [_delegate control:self didFailToValidatePartialString: partialString errorDescription: error]; } if (newString != nil) { NSLog (@"Unimplemented: should set string to %@", newString); // FIXME ! This would reset editing ! //[_text_object setString: newString]; } else { if (wasAccepted == NO) { // FIXME: Need to delete last typed character (?!) NSLog (@"Unimplemented: should delete last typed character"); } } } } - (void) textDidEndEditing: (NSNotification *)aNotification { NSDictionary *d; id textMovement; [self validateEditing]; [_cell endEditing: [aNotification object]]; _text_object = nil; d = [NSDictionary dictionaryWithObject: [aNotification object] forKey: @"NSFieldEditor"]; [nc postNotificationName: NSControlTextDidEndEditingNotification object: self userInfo: d]; textMovement = [[aNotification userInfo] objectForKey: @"NSTextMovement"]; if (textMovement) { switch ([(NSNumber *)textMovement intValue]) { case NSReturnTextMovement: if ([self sendAction: [self action] to: [self target]] == NO) { if ([self performKeyEquivalent: [_window currentEvent]] == NO) [self selectText: self]; } break; case NSTabTextMovement: [_window selectKeyViewFollowingView: self]; if ([_window firstResponder] == _window) [self selectText: self]; break; case NSBacktabTextMovement: [_window selectKeyViewPrecedingView: self]; if ([_window firstResponder] == _window) [self selectText: self]; break; } } } - (BOOL) textShouldBeginEditing: (NSText *)textObject { if ([self isEditable] == NO) return NO; if (_delegate && [_delegate respondsToSelector: @selector(control:textShouldBeginEditing:)]) return [_delegate control: self textShouldBeginEditing: textObject]; else return YES; } - (BOOL) textShouldEndEditing: (NSText*)textObject { if ([_cell isEntryAcceptable: [textObject text]] == NO) { [self sendAction: _error_action to: [self target]]; return NO; } if ([_delegate respondsToSelector: @selector(control:textShouldEndEditing:)]) { if ([_delegate control: self textShouldEndEditing: textObject] == NO) { NSBeep (); return NO; } } if ([_delegate respondsToSelector: @selector(control:isValidObject:)] == YES) { NSFormatter *formatter; id newObjectValue; formatter = [_cell formatter]; if ([formatter getObjectValue: &newObjectValue forString: [_text_object text] errorDescription: NULL] == YES) { if ([_delegate control: self isValidObject: newObjectValue] == NO) { return NO; } } } // In all other cases return YES; } - (BOOL)textView: (NSTextView*)textView doCommandBySelector: (SEL)command { if (_delegate && [_delegate respondsToSelector: @selector(control:textView:doCommandBySelector:)]) { return [_delegate control: self textView: textView doCommandBySelector: command]; } return NO; } // // Rich Text // - (void)setAllowsEditingTextAttributes:(BOOL)flag { [_cell setAllowsEditingTextAttributes: flag]; } - (BOOL)allowsEditingTextAttributes { return [_cell allowsEditingTextAttributes]; } - (void)setImportsGraphics:(BOOL)flag { [_cell setImportsGraphics: flag]; } - (BOOL)importsGraphics { return [_cell importsGraphics]; } - (void)setTitleWithMnemonic:(NSString *)aString { [_cell setTitleWithMnemonic: aString]; } // // NSCoding protocol // - (void) encodeWithCoder: (NSCoder*)aCoder { [super encodeWithCoder: aCoder]; [aCoder encodeConditionalObject: _delegate]; [aCoder encodeValueOfObjCType: @encode(SEL) at: &_error_action]; } - (id) initWithCoder: (NSCoder*)aDecoder { self = [super initWithCoder: aDecoder]; if ([aDecoder allowsKeyedCoding]) { } else { [self setDelegate: [aDecoder decodeObject]]; [aDecoder decodeValueOfObjCType: @encode(SEL) at: &_error_action]; } _text_object = nil; return self; } @end