This is FindObject.m in view mode; [Download] [Up]
/*
* FindObject.m
*
* Purpose:
* This object controls the searching for strings in a matrix or in a text object.
*
* 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.
*
* Written by: Mary McNabb
* Created: Apr 91
*
*/
#import "FindObject.h"
#import <libc.h>
#import <strings.h>
#import <appkit/publicWraps.h>
#import <streams/streams.h>
#import <appkit/Form.h>
#import <appkit/Button.h>
#import <appkit/Matrix.h>
#import <appkit/Text.h>
#import <appkit/Window.h>
#import <appkit/Application.h>
#import "cUtils.h"
@implementation FindObject
/* initialize FindObject */
- init
{
[super init];
[NXApp loadNibSection:"FindPanel.nib" owner:self];
return self;
}
/*
* This method sets the local variable searchMe.
* searchMe must be either a text object or a
* matrix of text fields.
*/
- setSearchMe:object
{
searchMe = object;
return self;
}
/*
* Order the findPanel front and select the search string.
*/
- findPanel:sender
{
[findPanel makeKeyAndOrderFront:NULL];
[findForm selectTextAt:0];
return self;
}
/*
* This method is called when the user types carriage
* return in the textfield in the find panel.
*/
- findNextReturn:sender
{
[findNextButton performClick:NULL];
[findPanel orderOut:NULL];
return self;
}
/*
* This method is called when the user pushes the next
* button on the find panel. It decides if the searchMe
* is of type matrix or text and calls subsequent methods
* accordingly.
*/
- findNext:sender
{
const char *findStr = [findForm stringValueAt:0];
if (!strlen(findStr) || !searchMe) {
NXBeep();
return self;
}
ignoreCase = [ignoreCaseButton state];
if ([searchMe isKindOf:[Matrix class]]) {
[self findInMatrix:FORWARD :findStr];
} else {
[self findInText:FORWARD];
}
return self;
}
/*
* This method is called when the user pushes the previous
* button on the find panel. It decides if the searchMe is of type
* matrix or text and calls subsequent methods accordingly.
*/
- findPrevious:sender
{
const char *findStr = [findForm stringValueAt:0];
if (!strlen(findStr) || !searchMe) {
NXBeep();
return self;
}
if ([searchMe isKindOf:[Matrix class]]) {
[self findInMatrix:BACKWARD :findStr];
} else {
[self findInText:BACKWARD];
}
return self;
}
/*
* Searches through a text object (also wraps around if necessary).
*/
- findInText:(int)direction
{
char *text, *textStart, *match;
NXSelPt start, end;
int count, newStart;
NXStream *stream;
text = (char *)[findForm stringValueAt:0];
[searchMe getSel:&start :&end];
if (start.cp == end.cp) start.cp = end.cp = 0;
/* We need to set up a stream for the search */
stream = [searchMe stream];
if (!stream) {
NXBeep();
return self;
}
/* find out how long the text is, and position ourselves either from the beginning or from
* the selection position */
NXSeek(stream, 0, NX_FROMEND);
count = NXTell(stream);
NXSeek(stream, 0, NX_FROMSTART);
textStart = (char *)malloc(count + 1);
NXRead(stream, textStart, count);
*(textStart + count) = '\0';
if (direction == FORWARD)
match = textInString(text, textStart + end.cp, ignoreCase);
else
match = textInStringReverse(text, textStart + start.cp + strlen(text) - 1,
textStart, ignoreCase);
/* wraparound if necessary */
if (!match) {
if (direction == FORWARD)
match = textInString(text, textStart, ignoreCase);
else
match = textInStringReverse(text, textStart + strlen(textStart), textStart, ignoreCase);
}
/* did we find anything? */
newStart = match - textStart;
free(textStart);
if (!match || (newStart == start.cp && (end.cp - start.cp) == strlen(text))) {
NXBeep();
return self;
}
[[searchMe setSel:newStart :newStart + strlen(text)]
scrollSelToVisible];
return self;
}
- (BOOL)searchMatrixStrings:(int)start:(int)stop:(int)dir:(const char *)findStr
{
int i;
for (i = start; dir == FORWARD? i <= stop: i >= stop; i += dir)
{
id myCell = [searchMe cellAt:i :0];
char *myContents = (char *) [myCell stringValue];
if (textInString((char *)findStr, myContents, ignoreCase))
{ /* then we've got a match */
[searchMe selectCellAt: i :0];
return YES;
}
}
return NO;
}
- findInMatrix:(int) direction :(const char*) findStr
{
int stop, temp, start;
if (direction == FORWARD) {
[searchMe getNumRows:&stop numCols:&temp];
stop--;
start = [searchMe selectedRow] + 1;
} else {
stop = 0;
start = [searchMe selectedRow] - 1;
}
if (![self searchMatrixStrings:start :stop :direction :findStr])
{ /* implements wrap-around search */
if (direction == FORWARD) {
start = 0;
stop = [searchMe selectedRow];
} else {
[searchMe getNumRows:&start numCols:&temp];
start -= 1;
stop = [searchMe selectedRow] + 1;
}
if (![self searchMatrixStrings:start :stop :direction :findStr])
{
NXBeep();
return self;
}
}
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.