ftp.nice.ch/pub/next/graphics/viewer/EnhancedYap.NIHS.bs.tar.gz#/EnhancedYap/Source/FindPanel.m

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.