This is FindPanel.m in view mode; [Download] [Up]
// FindPanel.m // // Subclass of Object which implements find panel functionality. // Works on Text objects automatically; pretty easily can be // made to work on any text container which responds to a given protocol. // // You may freely copy, distribute, and reuse the code in this example. // NeXT disclaims any warranty of any kind, expressed or implied, as to its // fitness for any particular use. #import <appkit/appkit.h> #import <libc.h> #import <strings.h> #import "FindPanel.h" @implementation FindPanel // Allocate and initialize the object. If we already created an instance, return that one... + sharedInstance { static id sharedFindObject = nil; NXZone *zone = NXApp ? [NXApp zone] : NXDefaultMallocZone(); if (sharedFindObject) { return sharedFindObject; } self = [[super allocFromZone:zone] init]; if (![NXApp loadNibSection:"FindPanel.nib" owner:self withNames:NO fromZone:zone]) { NXLogError ("Can't find FindPanel.nib!"); [self free]; return nil; } else { sharedFindObject = self; [[findText window] setFrameAutosaveName:"Find"]; return self; } } + new { return [self sharedInstance]; } // Because find panel is shared, only one instance is created, and it should be created // with new rather than alloc/init. - allocFromZone:(NXZone *)zone { return [self notImplemented:_cmd]; } - free { return self; } - (const char *)findString { return [findText stringValue]; } - (void)setFindString:(const char *)string { [findText setStringValue:string]; [findText selectText:nil]; } - (void)findIn:(Text *)textObject direction:(FindDirection)dir { if (!textObject || ![textObject findText:[self findString] ignoreCase:[ignoreCaseButton state] backwards:(dir == FindBackward) wrap:YES]) { NXBeep (); return; } } - firstResponderText { id obj = [[NXApp mainWindow] firstResponder]; return (obj && [obj isKindOf:[Text class]]) ? obj : nil; } - (void)findDirection:(FindDirection)dir { [self findIn:[self firstResponderText] direction:dir]; } - findNextReturn:sender { [findNextButton performClick:sender]; [self orderOut:sender]; return self; } - makeKeyAndOrderFront:sender { id retval = [[findText window] makeKeyAndOrderFront:sender]; [findText selectText:nil]; return retval; } - orderOut:sender { return [[findText window] orderOut:sender]; } // Called to find the next occurrence of the search string. - findNext:sender { [self findDirection:FindForward]; return self; } // Called to find the previous occurrence of the search string. - findPrevious:sender { [self findDirection:FindBackward]; return self; } // In case the selection is shorter than this amount, we use a local buffer // (on the stack) rather than bothering with allocating it. #define LOCALBUFFERLEN 100 - enterSelection:sender { id obj = [self firstResponderText]; if (!obj) { NXBeep(); } else { char localBuffer[LOCALBUFFERLEN+1], *str; NXSelPt from, to; int bufLen; [obj getSel:&from :&to]; bufLen = to.cp - from.cp; str = (bufLen <= LOCALBUFFERLEN) ? localBuffer : NXZoneMalloc(NXDefaultMallocZone(), bufLen+1); [obj getSubstring:str start:from.cp length:bufLen]; str[bufLen] = '\0'; [self setFindString:str]; if (str != localBuffer) free(str); } return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.