This is MiscFindPanel.m in view mode; [Download] [Up]
/* * Copyright (c) 1993 Christopher J. Kane. All rights reserved. * * This software is subject to the terms of the MiscKit license * agreement. Refer to the license document included with the * MiscKit distribution for these terms. * * Version: 1.1.1 (14 December 1993) * * Incorporates a bug-fix by Annard Brouwer <annard@stack.urc.tue.nl>. * The nextText outlet of the findTextField was remaining set to the * replaceTextField. When the replace controls were hidden, this * caused the Tab key in the findTextField to appear to do nothing. * The text in the field is now correctly selected when the Tab key * is pressed. */ #import "MiscFindPanel.h" #import <misckit/SearchableText.h> #import "Composer.h" #import "MainWindowControl.h" #import "descriptors.h" #import <misckit/MiscAppDefaults.h> #define DURING NX_DURING #define HANDLER NX_HANDLER switch (NXLocalHandler.code) { #define ENDHANDLER default: NXLogError("Uncaught exception: %d," \ " in %s:%s.\n", NXLocalHandler.code, __FILE__, \ sel_getName(_cmd)); abort();} NX_ENDHANDLER #define IGNORE(E) case E: NXLogError("%s exception in %s:%s. " \ "Ignored.\n", #E, __FILE__, sel_getName(_cmd)); break #define LocalString(K) NXLoadLocalizedStringFromTableInBundle(NULL, \ [NXBundle bundleForClass:[self class]], K, "") static MiscFindPanel *_sharedFindPanel=nil; static Pasteboard *_findPb=nil; static Object *_firstConformer=nil; static int _pbChangeCount=0; static BOOL _replEnabled=YES; static BOOL _useFindPb=YES; static BOOL _allocationOK=NO; static BOOL _resizeOK=NO; static BOOL _fpLoaded=NO; #define GSCOPE_TEXT 0 #define GSCOPE_SUBJECT 1 #define GSCOPE_MSGID 2 #define GSCOPE_NEWSGROUPS 3 #define GSCOPE_AUTHOR 4 #define GSCOPE_REFERENCES 5 @interface otherMethods - newsgroupMatrix; - articleMatrix; - mySet; - (int)grep:(const char *)pattern regexpr:(BOOL)regexpr cases:(BOOL)cases; @end @implementation MiscFindPanel - _calcFindPanelTarget { id d,r=nil; id i=[NXApp keyWindow]; if(i==self) i=[NXApp mainWindow]; if((i==nil)||(i==self)) return nil; d=[i delegate]; if(d==nil) return nil; if([d isKindOf:[MainWindowControl class]]){ int scope=[[scopeSelection selectedCell] tag]; if(scope==GSCOPE_TEXT) r=[d articleText]; else if(scope==GSCOPE_NEWSGROUPS) r=[d newsgroupMatrix]; else r=[d articleMatrix]; } else if([d isKindOf:[Composer class]]) r=[d theText]; if([r isKindOf:[Text class]]){ NXSelPt start,end; [r getSel:&start :&end]; if(start.cp==-1) [r setSel:0 :0]; } return r; } /* id i; if (_firstConformer!=nil) return _firstConformer; if (self!=[NXApp keyWindow]) { for(i=[[NXApp keyWindow] firstResponder]; i; i = [i nextResponder]) if ([i conformsTo:@protocol(SearchableText)]) return i; i = [[NXApp keyWindow] delegate]; if ([i conformsTo:@protocol(SearchableText)]) return i; } if ([NXApp keyWindow]!=[NXApp mainWindow]) { for(i=[[NXApp mainWindow] firstResponder]; i; i = [i nextResponder]) if ([i conformsTo:@protocol(SearchableText)]) return i; i = [[NXApp mainWindow] delegate]; if ([i conformsTo:@protocol(SearchableText)]) return i; } i = NXApp; if ([i conformsTo:@protocol(SearchableText)]) return i; i = [NXApp delegate]; if ([i conformsTo:@protocol(SearchableText)]) return i; return nil; } */ - (void)_getFindPbData { if (_pbChangeCount==[_findPb changeCount]) return; DURING if ([_findPb findAvailableTypeFrom:&NXAsciiPboardType num:1]) { char *text; int len; if ([_findPb readType:NXAsciiPboardType data:&text length:&len]) { [findTextField setStringValue:text]; [_findPb deallocatePasteboardData:text length:len]; } } HANDLER IGNORE(NX_pasteboardComm); IGNORE(NX_appkitVMError); ENDHANDLER _pbChangeCount = [_findPb changeCount]; } - (void)_modifyFindPanel { NXRect r; [contentView getBounds:&r]; [self disableFlushWindow]; if (_replEnabled) { _resizeOK = YES; [super sizeWindow:NX_WIDTH(&r) :NX_HEIGHT(&r)+25.0]; _resizeOK = NO; [[[findTextField superview] superview] moveBy:0.0 :25.0]; [contentView addSubview:_replBox :NX_BELOW relativeTo:nil]; [findTextField setNextText:replaceTextField]; /* added by Annard */ } else { [_replBox removeFromSuperview]; [[[findTextField superview] superview] moveBy:0.0 :-25.0]; _resizeOK = YES; [super sizeWindow:NX_WIDTH(&r) :NX_HEIGHT(&r)-25.0]; _resizeOK = NO; [findTextField setNextText:findTextField]; /* added by Annard */ } [self display]; [[self reenableFlushWindow] flushWindowIfNeeded]; } - (void)_resetFindPanel { [messageTextField setStringValue:""]; [findTextField selectText:nil]; } - (void)_setFindPbData { const char *text; if (_pbChangeCount==[_findPb changeCount]) return; text = [findTextField stringValue]; if (*text=='\0') return; DURING _pbChangeCount = [_findPb declareTypes:&NXAsciiPboardType num:1 owner:NULL]; [_findPb writeType:NXAsciiPboardType data:text length:(int)strlen(text)]; HANDLER IGNORE(NX_pasteboardComm); ENDHANDLER } + setFindPbEnabled:(BOOL)aBool { _useFindPb = aBool; return self; } + setFirstConformer:aConformer { id formerConformer = _firstConformer; if (aConformer==nil || [aConformer conformsTo:@protocol(SearchableText)]) _firstConformer = aConformer; return formerConformer; } + setReplacementEnabled:(BOOL)aBool { if (aBool!=_replEnabled) { _replEnabled = aBool; [_sharedFindPanel _modifyFindPanel]; } return self; } + sharedInstance { if (_sharedFindPanel==nil && !_fpLoaded) { char path[MAXPATHLEN+16]; _fpLoaded = YES; _findPb = [Pasteboard newName:NXFindPboard]; _allocationOK = YES; if ([[NXBundle bundleForClass:self] getPath:path forResource:"FindPanel.nib" ofType:NULL]) _sharedFindPanel = [NXApp loadNibFile:path owner:NXApp withNames:NO]; _allocationOK = NO; if (_sharedFindPanel==nil) NXRunAlertPanel(LocalString("LOAD_ERR"), LocalString("LOAD_ERR_MSG"), NULL, NULL, NULL); else { if (!_replEnabled) [_sharedFindPanel _modifyFindPanel]; [_sharedFindPanel setExcludedFromWindowsMenu:YES]; [_sharedFindPanel useOptimizedDrawing:YES]; } } return _sharedFindPanel; } - enterSelection:sender { [[self _calcFindPanelTarget] writeSelectionToPasteboard:_findPb asType:NXAsciiPboardType]; [self _getFindPbData]; [self _resetFindPanel]; return self; } - findBackward:sender { [self _resetFindPanel]; if (*[findTextField stringValue]=='\0' && _useFindPb) [self _getFindPbData]; if (*[findTextField stringValue]=='\0') [self makeKeyAndOrderFront:nil]; else { int pos, size, result; id target = [self _calcFindPanelTarget]; if (_useFindPb) [self _setFindPbData]; result = [target searchFor:[findTextField stringValue] mode:SelStartToSelEnd reverse:YES regexpr:[regExprButton state] cases:![ignoreCaseButton state] position:&pos size:&size]; if (target==nil || result<0) { [messageTextField setStringValue:LocalString("INVALID_OP")]; NXBeep(); } else if (result==0) { [messageTextField setStringValue:LocalString("NOT_FOUND")]; NXBeep(); } else { [target selectTextFrom:pos to:pos+size]; [target makeSelectionVisible]; } } return self; } - findForward:sender { [self _resetFindPanel]; if (*[findTextField stringValue]=='\0' && _useFindPb) [self _getFindPbData]; if (*[findTextField stringValue]=='\0') [self makeKeyAndOrderFront:nil]; else { int pos, size, result; id target = [self _calcFindPanelTarget]; if (_useFindPb) [self _setFindPbData]; result = [target searchFor:[findTextField stringValue] mode:SelEndToSelStart reverse:NO regexpr:[regExprButton state] cases:![ignoreCaseButton state] position:&pos size:&size]; if (target==nil || result<0) { [messageTextField setStringValue:LocalString("INVALID_OP")]; NXBeep(); } else if (result==0) { [messageTextField setStringValue:LocalString("NOT_FOUND")]; NXBeep(); } else { [target selectTextFrom:pos to:pos+size]; [target makeSelectionVisible]; } } return self; } - jumpToSelection:sender { [[self _calcFindPanelTarget] makeSelectionVisible]; return self; } - replace:sender { [self _resetFindPanel]; [[self _calcFindPanelTarget] replaceSelection:[replaceTextField stringValue]]; return self; } - replaceAll:sender { id target; int count; [self _resetFindPanel]; if (*[findTextField stringValue]=='\0') return self; target = [self _calcFindPanelTarget]; count = [target replaceAll:[findTextField stringValue] with:[replaceTextField stringValue] mode:([scopeMatrix selectedRow]?SelStartToSelEnd:TextEdgeToTextEdge) regexpr:[regExprButton state] cases:![ignoreCaseButton state]]; if (count<0 || target==nil) { [messageTextField setStringValue:LocalString("INVALID_OP")]; NXBeep(); } else { char buffer[256]; sprintf(buffer, LocalString("N_REPLACED"), count); [messageTextField setStringValue:buffer]; [target makeSelectionVisible]; } return self; } - replaceAndFind:sender { [[self replace:sender] findForward:sender]; return self; } - grep:sender { [self _resetFindPanel]; if (*[findTextField stringValue]=='\0' && _useFindPb) [self _getFindPbData]; if (*[findTextField stringValue]=='\0') [self makeKeyAndOrderFront:nil]; else { int result; id target = [self _calcFindPanelTarget]; if (_useFindPb) [self _setFindPbData]; if((![target respondsTo:@selector(mySet)])|| (![[target mySet] respondsTo:@selector(grep:regexpr:cases:)])) target=nil; result = [[target mySet] grep:[findTextField stringValue] regexpr:[regExprButton state] cases:![ignoreCaseButton state]]; if (target==nil || result<0) { [messageTextField setStringValue:LocalString("INVALID_OP")]; NXBeep(); } else if (result==0) { [messageTextField setStringValue:LocalString("NOT_FOUND")]; NXBeep(); } } return self; } - gscopeChanged:sender { int sel=[[scopeSelection selectedCell] tag]; int newDefault=-1; switch(sel){ case GSCOPE_SUBJECT: newDefault=SUBJECT; break; case GSCOPE_MSGID: newDefault=MSG_ID; break; case GSCOPE_AUTHOR: newDefault=FROM; break; case GSCOPE_REFERENCES: newDefault=REFS; break; } if(newDefault>=0) [NXApp setDefault:"findGeneralScope" toInt:newDefault]; [replButton1 setEnabled:(sel==GSCOPE_TEXT)]; [replButton2 setEnabled:(sel==GSCOPE_TEXT)]; [replButton3 setEnabled:(sel==GSCOPE_TEXT)]; [replButton4 setEnabled:(sel!=GSCOPE_TEXT)]; return self; } - (TextField *)findTextField { return findTextField; } - (Button *)ignoreCaseButton { return ignoreCaseButton; } - (TextField *)messageTextField { return messageTextField; } - (Button *)regExprButton { return regExprButton; } - (TextField *)replaceTextField { return replaceTextField; } - (Matrix *)scopeMatrix { return scopeMatrix; } - (Matrix *)scopeSelection { return scopeSelection; } - textDidEnd:sender endChar:(unsigned short)theChar { if (theChar==NX_RETURN) [self orderOut:nil]; return self; } - (BOOL)textWillChange:sender { return NO; } - (BOOL)textWillEnd:sender { return NO; } + (BOOL)_canAlloc { return _allocationOK; } + alloc { if (!_allocationOK) return [self doesNotRecognize:_cmd]; return class_createInstanceFromZone(self, 0, NXDefaultMallocZone()); } + allocFromZone:(NXZone *)zone { if (!_allocationOK) return [self doesNotRecognize:_cmd]; if (zone!=NX_NOZONE) return class_createInstanceFromZone(self, 0, zone); return nil; } + (BOOL)instancesRespondTo:(SEL)aSel { if (aSel==@selector(copy) || aSel==@selector(copyFromZone:) || aSel==@selector(free) || aSel==@selector(init) || aSel==@selector(initContent:style:backing:buttonMask:defer:) || aSel==@selector(initContent:style:backing:buttonMask:defer:screen:) || aSel==@selector(miniaturize:) || aSel==@selector(placeWindow:) || aSel==@selector(placeWindow:screen:) || aSel==@selector(placeWindowAndDisplay:) || aSel==@selector(setDocEdited:) || aSel==@selector(sizeWindow::)) return NO; return [super instancesRespondTo:aSel]; } + new { return [self doesNotRecognize:_cmd]; } + newContent:(const NXRect *)contentRect style:(int)aStyle backing:(int)bufferingType buttonMask:(int)mask defer:(BOOL)flag { return [self doesNotRecognize:_cmd]; } + newContent:(const NXRect *)contentRect style:(int)aStyle backing:(int)bufferingType buttonMask:(int)mask defer:(BOOL)flag screen:(const NXScreen *)screen { return [self doesNotRecognize:_cmd]; } - copyFromZone:(NXZone *)zone { return self; } - free { return self; } - init { return [self doesNotRecognize:_cmd]; } - initContent:(const NXRect *)contentRect style:(int)aStyle backing:(int)bufferingType buttonMask:(int)mask defer:(BOOL)flag { if (!_allocationOK) return [self doesNotRecognize:_cmd]; return [super initContent:contentRect style:aStyle backing:bufferingType buttonMask:mask defer:flag]; } - initContent:(const NXRect *)contentRect style:(int)aStyle backing:(int)bufferingType buttonMask:(int)mask defer:(BOOL)flag screen:(const NXScreen *)screen { return [self doesNotRecognize:_cmd]; } - miniaturize:sender { return self; } - orderWindow:(int)place relativeTo:(int)otherWin { if (place!=NX_OUT) { if (_useFindPb) [self _getFindPbData]; [self _resetFindPanel]; } return [super orderWindow:place relativeTo:otherWin]; } - placeWindow:(const NXRect *)aRect { if (_resizeOK) return [super placeWindow:aRect]; return [self moveTo:NX_X(aRect) :NX_Y(aRect)]; } - placeWindow:(const NXRect *)aRect screen:(const NXScreen *)aScreen { if (_resizeOK) return [super placeWindow:aRect screen:aScreen]; return [self moveTo:NX_X(aRect) :NX_Y(aRect) screen:aScreen]; } - placeWindowAndDisplay:(const NXRect *)aRect { if (_resizeOK) return [super placeWindowAndDisplay:aRect]; return [[self moveTo:NX_X(aRect) :NX_Y(aRect)] display]; } - read:(NXTypedStream *)stream { [super read:stream]; findTextField = NXReadObject(stream); replaceTextField = NXReadObject(stream); messageTextField = NXReadObject(stream); ignoreCaseButton = NXReadObject(stream); regExprButton = NXReadObject(stream); scopeMatrix = NXReadObject(stream); _replBox = NXReadObject(stream); return self; } - (BOOL)respondsTo:(SEL)aSel { if (aSel==@selector(alloc) || aSel==@selector(allocFromZone:) || aSel==@selector(new) || aSel==@selector(newContent:style:backing:buttonMask:defer:) || aSel==@selector(newContent:style:backing:buttonMask:defer:screen:) || aSel==@selector(copy) || aSel==@selector(copyFromZone:) || aSel==@selector(free) || aSel==@selector(init) || aSel==@selector(initContent:style:backing:buttonMask:defer:) || aSel==@selector(initContent:style:backing:buttonMask:defer:screen:) || aSel==@selector(miniaturize:) || aSel==@selector(placeWindow:) || aSel==@selector(placeWindow:screen:) || aSel==@selector(placeWindowAndDisplay:) || aSel==@selector(setDocEdited:) || aSel==@selector(sizeWindow::)) return NO; return [super respondsTo:aSel]; } - setDocEdited:(BOOL)aBool { return self; } - sizeWindow:(float)x :(float)y { return self; } - write:(NXTypedStream *)stream { [super write:stream]; NXWriteObjectReference(stream, findTextField); NXWriteObjectReference(stream, replaceTextField); NXWriteObjectReference(stream, messageTextField); NXWriteObjectReference(stream, ignoreCaseButton); NXWriteObjectReference(stream, regExprButton); NXWriteObjectReference(stream, scopeMatrix); NXWriteObjectReference(stream, _replBox); return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.