This is CodeBrowser.m in view mode; [Download] [Up]
#import "CodeBrowser.h" #import "PrefsPanel.h" #import "support.h" @implementation CodeBrowser: Window { char *fileName ; id lineList ; id methodBrowser ; id methodList ; id msgTextField ; id splitView ; id codeBrowserScrollView ; id codeBrowserText ; } - awakeFromNib ; { // Do some setup work. // put views into splitview [splitView addSubview: [methodBrowser removeFromSuperview]] ; [splitView addSubview: [codeBrowserScrollView removeFromSuperview]] ; // set up the CodeBrowser text if([codeBrowserText shouldDrawColor]) { [codeBrowserText setBackgroundColor: [[[NXApp prefsPanel] textBackgroundColorWell] color]] ; } else { float g ; NXConvertColorToGray([[[NXApp prefsPanel] textBackgroundColorWell] color], &g) ; [codeBrowserText setBackgroundGray:g] ; } [codeBrowserText setSel: 0 :0] ; [codeBrowserText replaceSel: ""] ; [codeBrowserText setSel: 0 :0] ; methodList = [[List alloc] init] ; [self setDelegate: self] ; lineList = [[Storage alloc] initCount: 0 elementSize: sizeof(int) description: "i"] ; return self ; } - (int)browser:sender fillMatrix:matrix inColumn:(int)column ; { return [methodList count] ; } - browser:sender loadCell:cell atRow:(int)row inColumn:(int)column ; { [cell setStringValue: [[methodList objectAt: row] cString]]; [cell setLeaf:YES] ; return self ; } - buildDotH: sender ; { // build an ObjC interface file from the selected text NXSelPt start, end ; char *textBuf ; int textLen ; [codeBrowserText getSel:&start :&end] ; setSelectionRange(&start, &end, [codeBrowserText textLength]) ; textLen = end.cp-start.cp ; textBuf = (char *) malloc(textLen+1) ; [codeBrowserText getSubstring:textBuf start:start.cp length:textLen] ; [NXApp buildDotH:textBuf length:textLen] ; free(textBuf) ; return self ; } - clearMessage: sender ; { // Clear the message in the transcript. Normally // called via a delayed message send. [self message: ""] ; return self ; } - codeBrowserText ; { return codeBrowserText ; } - evalObjC: sender ; { // evaluate the current selection as ObjC NXSelPt start, end ; char *textBuf ; int textLen ; [codeBrowserText getSel:&start :&end] ; [codeBrowserText getSel:&start :&end] ; setSelectionRange(&start, &end, [codeBrowserText textLength]) ; textLen = end.cp-start.cp ; textBuf = (char *) malloc(textLen+1) ; [codeBrowserText getSubstring:textBuf start:start.cp length:textLen] ; [NXApp evalObjC:textBuf length:textLen] ; free(textBuf) ; return self ; } - evalPs: sender ; { // evaluate the current selection as postscript NXSelPt start, end ; char *textBuf ; int textLen ; // get the selected text [codeBrowserText getSel:&start :&end] ; [codeBrowserText getSel:&start :&end] ; setSelectionRange(&start, &end, [codeBrowserText textLength]) ; textLen = end.cp-start.cp ; textBuf = (char *) malloc(textLen+1) ; [codeBrowserText getSubstring:textBuf start:start.cp length:textLen] ; textBuf[textLen] = '\0' ; // evalute via "ps:" [self message: "Evaluating Postscript..."] ; [Eval ps: textBuf] ; [self message: ""] ; free(textBuf) ; return self ; } - (const char *) fileName ; { if(!fileName) return "UNTITLED" ; else return fileName ; } - fileName: (const char *) fname ; { // Copy fname into ivar, set our title to fname, // with the filename followed by the path. int nameLen ; if(fileName) { if(!strcmp(fileName,fname)) return self ; // fileName isn't changing else free(fileName) ; } // malloc memory and copy the fileName; nameLen = strlen(fname) + 1 ; fileName = (char *) malloc(nameLen) ; strcpy(fileName, fname) ; [self setTitleAsFilename: fileName] ; return self ; } - format: sender ; { // text formatting is done by class EvalText char pathBuf[512] ; [methodBrowser getPath: pathBuf toColumn: 1] ; [methodList freeObjects] ; [codeBrowserText format: self] ; [methodBrowser loadColumnZero] ; [methodBrowser setPath: pathBuf] ; return self ; } - goToMethod: sender ; { // find the text in the codeBrowserText NXSelPt start, end ; [codeBrowserText getSel: &start :&end] ; [codeBrowserText setSel: 0 :0] ; if(![codeBrowserText findText: [[methodList objectAt: [[sender matrixInColumn:0] selectedRow]] cString] ignoreCase: NO backwards: NO wrap: NO]) { [self message: "Method not found.\nTry hitting the Format button."] ; NXBeep() ; [self perform: @selector(clearMessage:) with: self afterDelay: 2500 cancelPrevious: YES] ; [codeBrowserText setSel: start.cp :end.cp] ; } return self ; } - lineList ; { return lineList ; } - loadObjC: sender ; { // compile and load the current selection NXSelPt start, end ; char *textBuf ; int textLen ; [codeBrowserText getSel:&start :&end] ; [codeBrowserText getSel:&start :&end] ; setSelectionRange(&start, &end, [codeBrowserText textLength]) ; textLen = end.cp-start.cp ; textBuf = (char *) malloc(textLen+1) ; [codeBrowserText getSubstring:textBuf start:start.cp length:textLen] ; [NXApp loadObjC:textBuf length:textLen] ; free(textBuf) ; [[NXApp moduleBrowser] loadColumnZero] ; return self ; } - message: (char *) aMsg ; { // show aMsg in the msg textfield [msgTextField setStringValue: aMsg] ; NXPing() ; return self ; } - methodList ; { return methodList ; } - readStream: (NXStream *) aStream { // read text from aStream into codeBrowserText [codeBrowserText readText: aStream] ; [codeBrowserText format: self] ; [self setDocEdited: NO] ; return self ; } - revert:sender ; { if(fileName && [[codeBrowserText window] isDocEdited]) { int rval = NXRunAlertPanel( "Eval","%s has been edited. Revert?", "Revert","Cancel",NULL,[self fileName]) ; if(rval) { NXStream *fileStream ; [self message: "Reading file..."] ; if((fileStream = NXMapFile(fileName,NX_READONLY)) != NULL) { [self readStream: fileStream] ; NXCloseMemory(fileStream,NX_FREEBUFFER); [self message: ""] ; } } else return nil ; } return self ; } -(BOOL) save:sender ; { if([[codeBrowserText window] isDocEdited]) { if(!fileName) // no fileName, i.e. first save: [self saveAs: sender] ; else [self saveTextToFileName] ; } return YES ; } -(BOOL) saveAs:sender ; { id savePanel = [SavePanel new] ; if([savePanel runModalForDirectory: NULL file: fileName]) { [self fileName: (char *) [savePanel filename]] ; return [self saveTextToFileName] ; } else return NO ; } - (BOOL) saveTextToFileName ; // We assume the instance variable fileName contains a valid // file pathname. If it can be opened or created, with mode // 644: text of codeBrowserText is written out to it, // and YES is returned, else returns NO. { // removeBackup should be a dwrite...some day! NXStream *aStream = NXOpenMemory(NULL,0, NX_WRITEONLY); [self message: "Saving file..."] ; [codeBrowserText writeText:aStream] ; NXSaveToFile(aStream, fileName); NXCloseMemory(aStream, NX_FREEBUFFER) ; [self message: ""] ; [[codeBrowserText window] setDocEdited: NO] ; return YES ; } - windowDidBecomeMain: sender ; { // this causes the finder to load the linenum browser // using our linenum's [[NXApp finder] reset: self] ; return self ; } - windowWillClose: sender ; { if(self == [[NXApp transcriptText] window]) // If I am the transcript, ignore this message return self ; if([self isDocEdited]) { int rval = NXRunAlertPanel("Review Unsaved", "Save changes to %s?","Cancel","Don't Save","Save", [self title]) ; if(rval == NX_ALERTOTHER) // rightmost button...save [self save: self] ; else if(rval == NX_ALERTALTERNATE) {} // middle button == don't save, i.e. do nothing else // rval == NX_ALERTDEFAULT, leftmost button == Cancel { return nil ; } } [lineList free] ; [methodList freeObjects] ; [methodList free] ; [NXApp removeWindowsItem: sender] ; return self ; } - windowWillMiniaturize: sender toMiniwindow: miniwindow ; { if(fileName) { int extension = strlen(fileName) - 2 ; if(!strcmp(&fileName[extension],".m")) return [self setMiniwindowIcon: "HackM"] ; else if(!strcmp(&fileName[extension],".h")) return [self setMiniwindowIcon: "HackH"] ; } return [self setMiniwindowIcon: "Hack"] ; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.