home *** CD-ROM | disk | FTP | other *** search
- /* Generated by Interface Builder */
-
- #import "FindManager.h"
- #import <objc/Object.h>
- #import <appkit/Application.h>
- #import <appkit/Panel.h>
- #import <appkit/Form.h>
- #import <appkit/Text.h>
- #import <appkit/Control.h>
- #import <appkit/Button.h>
- #import <streams/streams.h>
-
- #import <string.h>
- #import <stdlib.h>
- #import <ctype.h>
- #import "regex.h"
-
- static id instance = nil;
-
- static char upcase[0400] =
- {000, 001, 002, 003, 004, 005, 006, 007,
- 010, 011, 012, 013, 014, 015, 016, 017,
- 020, 021, 022, 023, 024, 025, 026, 027,
- 030, 031, 032, 033, 034, 035, 036, 037,
- 040, 041, 042, 043, 044, 045, 046, 047,
- 050, 051, 052, 053, 054, 055, 056, 057,
- 060, 061, 062, 063, 064, 065, 066, 067,
- 070, 071, 072, 073, 074, 075, 076, 077,
- 0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
- 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
- 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
- 0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
- 0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
- 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
- 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
- 0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
- 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
- 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
- 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
- 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
- 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
- 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
- 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
- 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
- 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
- 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
- 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
- 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
- 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
- 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
- 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
- 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377
- };
-
- int search(const char *match, char *text, int start, int most, int matchCase);
-
- @implementation FindManager
-
- + new
- {
- if((instance != nil) && [instance isKindOf:[FindManager class]])
- return instance;
- else
- return (instance = [[FindManager alloc] init]);
- }
-
- - init
- {
- if(instance != nil)
- return nil;
- self = [super init];
- instance = self;
- [NXApp loadNibSection:"FindManager.nib" owner:self withNames:NO];
-
- countType = line;
- extent = all;
- regex = NO;
- matchCase = NO;
- re_set_syntax(RE_NO_BK_PARENS | RE_NO_BK_VBAR | RE_CONTEXT_INDEP_OPS);
- return self;
- }
-
- - textDidEnd:textObject endChar:(unsigned short)whyEnd
- {
- free(currentText);
- currentText = NXCopyStringBuffer([findView stringValue]);
-
- return self;
- }
-
- - (char *)currentText
- {
- return currentText;
- }
-
- - checkResponder
- {
- id fr = [[NXApp mainWindow] firstResponder];
-
- if([fr isKindOf:[Text class]])
- return fr;
- else
- return nil;
- }
-
- - orderFrontFindPanel:sender
- {
- [findPanel makeKeyAndOrderFront:self];
- [findView setStringValue:currentText];
- [findView selectTextAt:0];
- return self;
- }
-
- - orderFrontCountPanel:sender
- {
- id text;
- [countPanel makeKeyAndOrderFront:self];
-
- if((text =[self checkResponder]) == nil)
- return self;
- else
- {
- NXSelPt start, end;
- char buf[20];
-
- [text getSel:&start :&end];
-
- switch(countType)
- {
- case line :
- {
- sprintf(buf, "%d", [text lineFromPosition:start.c1st]);
- if(start.c1st != end.c1st)
- {
- sprintf((buf + strlen(buf)), ":%d",
- [text lineFromPosition:end.c1st]);
- }
- break;
- }
- case character :
- {
- sprintf(buf, "%d", start.cp);
- if(start.cp != end.cp)
- {
- sprintf((buf + strlen(buf)), ":%d", end.cp);
- }
- break;
- }
- }
- [countView setStringValue:buf];
- [countView selectText:self];
- }
-
- return self;
- }
-
- - enterSelection:sender
- {
- id text;
- NXSelPt start, end;
-
- if((text = [self checkResponder]) == nil)
- return self;
-
- [text getSel:&start :&end];
- if(start.cp != end.cp)
- {
- currentText = (char *)realloc(currentText, end.cp - start.cp + 1);
- [text getSubstring:currentText start:start.cp length:end.cp - start.cp];
- *(currentText + end.cp - start.cp) = '\0';
- [findView setStringValue:currentText];
- }
- [findView selectText:self];
-
- return self;
- }
-
- - replace:sender
- {
- return [self find:replace];
- }
-
- - replaceAll:sender
- {
- return [self find:rall];
- }
-
- - setOptions:sender
- {
- switch([sender selectedTag])
- {
- case 0 :
- matchCase = ![sender state];
- break;
- case 1:
- regex = [sender state];
- break;
- default:
- break;
- }
- return self;
- }
-
- - findNext:sender
- {
- return [self find:next];
- }
-
- - jumpToSelection:sender
- {
- id text;
- if((text =[self checkResponder]) == nil)
- return self;
- [text scrollSelToVisible];
- return self;
- }
-
- - findPrevious:sender
- {
- return [self find:previous];
- }
-
- - replaceAndFind:sender
- {
- return [self find:(replace | next)];
- }
-
- - find:(find_type)findTag
- {
- id textO;
- NXStream *stream;
-
- if((textO =[self checkResponder]) == nil)
- return self;
- else
- {
-
- const char *replaceBuf;
- NXSelPt start, end;
- int len;
- struct re_pattern_buffer buf;
- char fastmap[(1 << BYTEWIDTH)];
-
-
- currentText = (char *)[findView stringValueAt:0];
- replaceBuf = [findView stringValueAt:1];
-
- if(findTag & replace)
- {
- [textO replaceSel:replaceBuf];
- }
- if(!(findTag & ~replace))
- return self;
-
- if(regex)
- {
- buf.allocated = 40;
- buf.buffer = (char *)malloc(buf.allocated);
- buf.fastmap = fastmap;
- if(!matchCase)
- buf.translate = upcase;
- else buf.translate = NULL;
- re_compile_pattern(currentText, strlen(currentText), &buf);
- re_compile_fastmap(&buf);
- }
-
- len = [textO textLength];
- if(len == 0)
- return self;
- [textO getSel:&start :&end];
- stream = [textO stream];
-
-
-
- if(findTag & (next|previous))
- {
- int i, flen, wrapped = NO, found = NO;
- int begin;
- int most;
- textStart = (char *)realloc(textStart, len);
- NXRead(stream, textStart, len);
- if(findTag & next)
- {
- begin = end.cp;
- most = len - end.cp;
- }
- else
- {
- begin = start.cp - 1;
- most = -start.cp + 1;
- if(begin < 0)
- {
- begin = len - 1;
- most = start.cp - len + 1;
- wrapped = YES;
- }
- }
-
- do
- {
- if(regex)
- {
- i = re_search(&buf, textStart, len, begin, most, 0, &flen);
- }
- else
- {
- i = search(currentText, textStart, begin, most, matchCase);
- flen = strlen(currentText);
- }
- if(i < 0)
- {
- if(!wrapped)
- {
- wrapped = YES;
- if(findTag & next)
- {
- begin = 0;
- most = end.cp;
- }
- else
- {
- begin = len - 1;
- most = start.cp - len + 1;
- }
- }
- else
- {
- if(!found)
- {
- [warningText setStringValue:"Not\nFound"];
- }
- return self;
- }
- }
- else
- {
- if(!found)
- [warningText setStringValue:""];
- found = YES;
- [textO setSel:i:i + flen];
- [textO scrollSelToVisible];
- }
- } while(!found);
-
- }
-
- if(findTag & rall)
- {
- int begin = 0, most, i, flen, found = NO, offset;
- int rlen = strlen(replaceBuf);
-
- if(extent != all)
- {
- offset = start.cp;
- most = end.cp - start.cp - 1;
- len = most;
- }
- else
- {
- offset = 0;
- most = len;
- }
- if(most < 1)
- return self;
-
- NXSeek(stream, offset, NX_FROMSTART);
- textStart = (char *)realloc(textStart, most);
- NXRead(stream, textStart, most);
-
- flen = strlen(currentText);
- for(;;)
- {
- if(regex)
- {
- i = re_search(&buf, textStart, len, begin, most, 0, &flen);
- }
- else
- {
- i = search(currentText, textStart, begin, most, matchCase);
- }
- if((i < 0) || (i + flen) > len)
- {
- if(!found)
- [warningText setStringValue:"Not\nFound"];
- return self;
- }
- else
- {
- if(!found)
- {
- [warningText setStringValue:""];
- found = YES;
- }
- [textO setSel:i + offset :i + offset + flen];
- [textO replaceSel:replaceBuf];
-
- offset += rlen - flen;
- begin = i + flen;
- most = len - begin;
- if(most < 0)
- {
- if(!found)
- [warningText setStringValue:"Not\nFound"];
- return self;
- }
- }
- }
- }
-
- return self;
- }
- }
-
- - jumpToCount:sender
- {
- id text;
-
- if((text =[self checkResponder]) == nil)
- return self;
- else
- {
- char *test;
- int end;
- const char *buf = [countView stringValue];
- int start = atoi(buf);
- if((test = strchr(buf, ':')) != NULL)
- end = atoi(test + 1);
- else
- end = start;
-
- switch(countType)
- {
-
- case line :
- {
- [text setSel:[text positionFromLine:start]
- :[text positionFromLine:end + 1]];
- break;
- }
- case character :
- {
- [text setSel:start :end];
- break;
- }
- }
- }
- [countPanel orderOut:self];
- [text scrollSelToVisible];
-
- return self;
- }
-
- - setCountType:sender
- {
- countType = [sender selectedTag];
- return self;
- }
-
- - setSearchExtent:sender
- {
- extent = [sender selectedTag];
- return self;
- }
-
- int search(const char *match, char *text, int start, int most, int matchCase)
- {
- int len, offset = 0;
- int c, dir;
- len = strlen(match);
- if(most < 0)
- {
- c = len - 1;
- dir = -1;
- }
- else
- {
- c = 0;
- dir = 1;
- }
- offset = 0;
-
- if(abs(offset) > abs(most))
- return -1;
-
- if(matchCase)
- {
- for(;;)
- {
- while(*(text + start + offset) != *(match + c))
- {
- offset += dir;
- if(abs(offset) > abs(most))
- return -1;
- }
- if(!strncmp(text + start + offset - c, match, abs(len)))
- {
- return start + offset - c;
- }
- offset += dir;
- }
- }
- else
- {
- for(;;)
- {
- while(tolower(*(text + start + offset)) != tolower(*(match + c)))
- {
- offset += dir;
- if(abs(offset) > abs(most))
- return -1;
- }
- if(!strncasecmp(text + start + offset - c, match, abs(len)))
- {
- return start + offset - c;
- }
- offset += dir;
- }
- }
- return -1;
- }
-
- @end
-