This is WoodDoc_SearchableText.m in view mode; [Download] [Up]
#import "wooddoc.h" @implementation WoodDoc (SearchableText) - (oneway void)makeSelectionVisible { NXRect scrollRect; if(lastSelectedNode){ [window disableFlushWindow]; [lastSelectedNode getBounds:&scrollRect]; [treeView scrollRectToVisible:&scrollRect]; [window reenableFlushWindow]; [window flushWindow]; } } - (int)replaceAll:(const char *)pattern with:(const char *)replacement mode:(SearchMode)mode regexpr:(BOOL)regexpr cases:(BOOL)cases { id searchTree, searchEndTree; int result; switch(mode){ case SelStartToSelEnd: if(lastSelectedNode){ searchTree = lastSelectedNode; searchEndTree = [lastSelectedNode lastInDepth]; } else { searchTree = tree; searchEndTree = [tree lastInDepth]; } break; case TextEdgeToTextEdge: searchTree = tree; searchEndTree = [tree lastInDepth]; break; default: return SEARCH_INVALID_ARGUMENT; } result = 0; [searchTree replaceTreeFor:pattern with:replacement untilNode:searchEndTree regexpr:regexpr cases:cases result:&result]; if(result > 0) [self updateViewsDirty:YES rect:NULL flag:(UPDATE_TREEVIEW | CHECK_RESIZE)]; return result; } - (oneway void)replaceSelection:(const char *)replacement { if(lastSelectedNode){ if([lastSelectedNode replaceLabelSelectionWith:replacement pos:findPos size:findSize]) [self updateViewsDirty:YES rect:NULL flag:(UPDATE_TREEVIEW | CHECK_RESIZE)]; } return; } - (int)searchFor:(const char *)pattern mode:(SearchMode)mode reverse:(BOOL)rev regexpr:(BOOL)regexpr cases:(BOOL)cases position:(out int *)pos size:(out int *)size { id searchTree, searchEndTree; findSelectedNode = nil; findPos = 0; findSize = 0; switch(mode){ case SelStartToSelEnd: if(lastSelectedNode){ searchTree = [lastSelectedNode previousInDepth]; searchEndTree = [lastSelectedNode nextInDepth]; } else { searchTree = [tree previousInDepth]; searchEndTree = tree; } break; case SelEndToSelStart: if(!lastSelectedNode){ searchTree = tree; searchEndTree = [tree lastInDepth]; } else { searchTree = [lastSelectedNode nextInDepth]; searchEndTree = [lastSelectedNode previousInDepth]; } break; default: return SEARCH_INVALID_ARGUMENT; } findSelectedNode = [searchTree searchTreeFor:pattern untilNode:searchEndTree reverse:rev regexpr:regexpr cases:cases position:pos size:size]; if(findSelectedNode){ findPos = *pos; findSize = *size; } return (findSelectedNode == nil ? 0 : 1); } - (oneway void)selectTextFrom:(int)start to:(int)end { if(findSelectedNode){ [self declareSelection:findSelectedNode]; [self updateViewsDirty:NO rect:NULL flag:UPDATE_TREEVIEW]; findSelectedNode = nil; } } - (void)writeSelectionToPasteboard:(in Pasteboard *)pboard asType:(in NXAtom)type; { int len; if(lastSelectedNode){ len = strlen([lastSelectedNode label]); if(len){ [pboard declareTypes:&type num:1 owner:NULL]; [pboard writeType:type data:[lastSelectedNode label] length:len]; } } } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.