From 6d89487694a4222a9273e065d923b902c65e59f5 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Sat, 4 Nov 2000 06:58:29 +0000 Subject: [PATCH] Adding modifications for NSSecureTextField. This is a partial implementation which works at the same level as OPENSTEP 4.2. The methods necessary to echo bullets to the screen will be added later. (GJC) git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@8021 72102866-910b-0410-8b05-ffd578937521 --- Source/NSSecureTextField.m | 249 +++++++++++++++++++++++++------------ 1 file changed, 170 insertions(+), 79 deletions(-) diff --git a/Source/NSSecureTextField.m b/Source/NSSecureTextField.m index 570330a73..0c47bfdc4 100644 --- a/Source/NSSecureTextField.m +++ b/Source/NSSecureTextField.m @@ -5,9 +5,12 @@ Copyright (C) 1999 Free Software Foundation, Inc. - Author: Lyndon Tremblay + Original Author: Lyndon Tremblay Date: 1999 + Rewrite by: Gregory John Casamento + Date: 2000 + This file is part of the GNUstep GUI Library. This library is free software; you can redistribute it and/or @@ -17,7 +20,7 @@ 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public @@ -34,10 +37,25 @@ // #include - #include #include #include +#include +#include +#include +#include +#include "GSSimpleLayoutManager.h" + +/* Other secure subclasses */ +@interface NSSecureTextView : NSTextView +{ +} +@end + +@interface GSSimpleSecureLayoutManager : GSSimpleLayoutManager +{ +} +@end @implementation NSSecureTextField @@ -46,42 +64,73 @@ +initialize ============== */ -+ (void)initialize ++ (void) initialize { if (self == [NSSecureTextField class]) { [self setVersion:1]; - [self setCellClass: [NSSecureTextFieldCell class]]; } } +/* +============ ++ cellClass +============ +*/ ++ (Class) cellClass +{ + // Hard code here to make sure no other class can be used. + return [NSSecureTextFieldCell class]; +} + +/* +============ ++ setCellClass +============ +*/ ++ (void) setCellClass: (Class)factoryId +{ + // Ward off interlopers with a stern message. + [NSException raise: NSInvalidArgumentException + format: @"NSSecureTextField can only use NSSecureTextFieldCells in order to ensure security."]; +} + /* ============== -initWithFrame: ============== */ -- (id)initWithFrame:(NSRect)frameRect +- (id) initWithFrame:(NSRect)frameRect { [super initWithFrame: frameRect]; - [_cell setEchosBullets:YES]; + [_cell setEchosBullets: YES]; return self; } /* ============== --isSelectable: +-initWithCoder: ============== */ -- (BOOL)isSelectable +- (id) initWithCoder:(NSCoder *)decoder { - return NO; + BOOL echosBullets = YES; + + [super initWithCoder: decoder]; + [decoder decodeValueOfObjCType: @encode(BOOL) at: &echosBullets]; + [_cell setEchosBullets: echosBullets]; + + return self; } - +- (void) textDidEndEditing: (NSNotification *)aNotification +{ + [_text_object setText: [[aNotification object] text]]; + [super textDidEndEditing: aNotification]; +} @end /* NSSecureTextField */ @implementation NSSecureTextFieldCell - /* ============== +initialize @@ -94,17 +143,22 @@ } /* -============== --copyWithZone: -============== +================================== ++_sharedSecureFieldEditorInstance +================================== */ -- (id)copyWithZone:(NSZone *)zone ++ (id)_sharedSecureFieldEditorInstance { - //Prevent the cell's text value from being copied. - NSSecureTextFieldCell *c = [super copyWithZone:zone]; - [c setStringValue:@""]; - [c setEchosBullets:i_echosBullets]; - return c; + static NSSecureTextView *secureView = nil; + + if( secureView == nil ) + { + secureView = [[NSSecureTextView alloc] init]; + [secureView setFieldEditor: YES]; + [secureView setText: @""]; + } + + return secureView; } /* @@ -127,25 +181,6 @@ i_echosBullets = flag; } -/* -=============== --setSelectable: -=============== -*/ -- (void)setSelectable:(BOOL)flag -{ - _cell.is_selectable = NO; -} - -/* -============= --selectText: -============= -*/ -- (void)selectText:(id)sender -{ -} - /* =============== -drawInteriorWithFrame: @@ -153,45 +188,101 @@ */ - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView { - NSString *string = [self stringValue]; - unsigned length = [string length]; - - - - [self setType:NSNullCellType]; - [super drawInteriorWithFrame:cellFrame inView:controlView]; - [self setType:NSTextCellType]; - - if (length && i_echosBullets) { - NSImage *image = [NSImage imageNamed:@"common_Diamond"]; - NSSize size = [image size]; - NSPoint position; - float stringWidth; - - - stringWidth = [[self font] widthOfString:string]; - switch ([self alignment]) { - case NSRightTextAlignment: - position.x = (NSWidth(cellFrame) - (stringWidth)) - 1; - break; - case NSCenterTextAlignment: - position.x = NSMidX(cellFrame) - (stringWidth/2); - break; - default: - position.x = 1; - break; - } - - position.y = MAX(NSMidY(cellFrame) - (size.height/2), 0); - if ([controlView isFlipped]) - position.y += size.height; - - while (--length) { - [image compositeToPoint:position operation:NSCompositeCopy]; - position.x += size.width+1; - } - } - //[self _drawText:stars inFrame:cellFrame]; + // do nothing.... } +/* + * Editing Text + */ +- (void) editWithFrame: (NSRect)aRect + inView: (NSView*)controlView + editor: (NSText*)textObject + delegate: (id)anObject + event: (NSEvent*)theEvent +{ + id l_editor = [NSSecureTextFieldCell _sharedSecureFieldEditorInstance]; + + [l_editor setText: [textObject text]]; + [super editWithFrame: aRect + inView: controlView + editor: l_editor + delegate: anObject + event: theEvent]; +} + +- (void) selectWithFrame: (NSRect)aRect + inView: (NSView*)controlView + editor: (NSText*)textObject + delegate: (id)anObject + start: (int)selStart + length: (int)selLength +{ + id l_editor = [NSSecureTextFieldCell _sharedSecureFieldEditorInstance]; + + [l_editor setText: [textObject text]]; + [super selectWithFrame: aRect + inView: controlView + editor: l_editor + delegate: anObject + start: selStart + length: selLength]; +} +@end + +@implementation GSSimpleSecureLayoutManager +- (void) drawGlyphsForGlyphRange: (NSRange)glyphRange + atPoint: (NSPoint)containerOrigin +{ + // do nothing... +} +@end + +@implementation NSSecureTextView +/* Class methods */ ++ (void) initialize +{ + if ([self class] == [NSSecureTextView class]) + { + [self setVersion: 1]; + [self registerForServices]; + } +} + +- (id) initWithFrame: (NSRect)frameRect +{ + NSTextContainer *aTextContainer = + [[NSTextContainer alloc] initWithContainerSize: frameRect.size]; + GSSimpleSecureLayoutManager *layoutManager = [[GSSimpleSecureLayoutManager alloc] init]; + + [super initWithFrame: frameRect]; + [layoutManager addTextContainer: aTextContainer]; + RELEASE(aTextContainer); + + _textStorage = [[NSTextStorage alloc] init]; + [_textStorage addLayoutManager: layoutManager]; + RELEASE(layoutManager); + + return [self initWithFrame: frameRect textContainer: aTextContainer]; +} + +- (void) copy: (id)sender +{ + // Do nothing since copying from a NSSecureTextView is *not* permitted. +} + +- (BOOL) writeSelectionToPasteboard: (NSPasteboard*)pboard + types: (NSArray*)types +{ + /* Returns NO since the selection should never be + written to the pasteboard */ + return NO; +} + +- (id) validRequestorForSendType: (NSString*) sendType + returnType: (NSString*) returnType +{ + /* return "nil" to indicate that no type can be sent to the pasteboard for + an object of this class */ + return nil; +} @end