This is Help.m in view mode; [Download] [Up]
/* Generated by Interface Builder */ #import "Help.h" #import "Dispatcher.h" #import <appkit/Button.h> #import <appkit/Cell.h> #import <appkit/Matrix.h> #import <appkit/MenuCell.h> #import <appkit/NXBrowser.h> #import <appkit/NXBrowserCell.h> #import <appkit/ScrollView.h> #import <appkit/Text.h> #import <dpsclient/wraps.h> #import <sys/dir.h> //for getdirentries() #import <libc.h> #import <strings.h> @implementation Help - init { if (!strlen([NXApp appDirectory])) [NXApp init]; sprintf(helpDir, "%s/%s", [NXApp appDirectory], "Help"); printf("helpDir = %s\n", helpDir); sprintf(noHelpFile, "%s/%s", helpDir, "No Help.rtf"); helpPanel = [NXApp loadNibSection:"help.nib" owner:self]; return self; } - setHelpBrowser:anObject { helpBrowser = anObject; [helpBrowser setDelegate:self]; [helpBrowser loadColumnZero]; return self; } - generalHelp:sender { [self showHelpFile:"Overview"]; return self; } - browserHit:sender { [self showHelpFile:[[[sender matrixInColumn:0] selectedCell] stringValue]]; return self; } - print:sender { [[helpScroll docView] printPSCode:sender]; return self; } - showHelpFile:(const char *)filename { NXStream *stream; char helpFile[MAXPATHLEN]; static NXPoint origin = {0.0,0.0}; if (![self browser:helpBrowser selectCell:filename inColumn:0]) [self browser:helpBrowser selectCell:"No Help" inColumn:0]; sprintf(helpFile,"%s/%s.rtf",helpDir,filename); if ((stream = NXMapFile(helpFile,NX_READONLY)) == NULL) stream = NXMapFile(noHelpFile,NX_READONLY); if (stream != NULL) { [helpPanel disableFlushWindow]; [[helpScroll docView] readRichText:stream]; [[helpScroll docView] scrollPoint:&origin]; [[helpPanel reenableFlushWindow] flushWindow]; NXCloseMemory(stream,NX_FREEBUFFER); } [helpPanel orderFront:self]; return self; } #define CHUNK 127 static char **addFile(const char *file, int length, char **list, int count) { char *suffix; if (!list) list = (char**)malloc(CHUNK*sizeof(char *)); if (suffix = rindex(file,'.')) *suffix = '\0'; list[count] = (char *)malloc((length + 1)*sizeof(char)); strcpy(list[count], file); count++; if (!(count % CHUNK)) { list = (char **)realloc(list, (((count/CHUNK)+1)*CHUNK)*sizeof(char *)); } list[count] = NULL; return list; } static void freeList(char **list) { char **strings; if (list) { strings = list; while (*strings) free(*strings++); free(list); } } static BOOL isOk(const char *s) /* checks to make sure the filename is not NULL and to verify that it is * not a "dot"--hidden file. */ { return (!s[0] || s[0] == '.') ? NO : YES; } static int caseInsensitiveCompare(void *arg1, void *arg2) /* Compares the two arguments without regard for case using strcasecmp(). */ { char *string1, *string2; string1 = *((char **)arg1); string2 = *((char **)arg2); return strcasecmp(string1,string2); } static char **fileList; - (int)browser:sender fillMatrix:matrix inColumn:(int)column /* This delegate method goes out to the help directory and gets a list * of all the files in that directory. It creates a list of file names * for the static variable fileList, and will load the filenames into the * browser on demand (lazy loading). */ { long basep; char *buf; struct direct *dp; char **list = NULL; int cc, fd, fileCount = 0; char dirbuf[8192]; if ((fd = open(helpDir, O_RDONLY, 0644)) > 0) { cc = getdirentries(fd, (buf = dirbuf), 8192, &basep); while (cc) { dp = (struct direct *)buf; if (isOk(dp->d_name)) { list = addFile(dp->d_name, dp->d_namlen, list, fileCount++); } buf += dp->d_reclen; if (buf >= dirbuf + cc) { cc = getdirentries(fd, (buf = dirbuf), 8192, &basep); } } close(fd); if (list) qsort(list,fileCount,sizeof(char *),caseInsensitiveCompare); } freeList(fileList); fileList = list; return fileCount; } - browser:sender loadCell:cell atRow:(int)row inColumn:(int)column /* This delegate method loads the cell for a given row. The stringValue * for that row comes from the fileList. */ { if (fileList) { [cell setStringValueNoCopy:fileList[row]]; [cell setLeaf:YES]; } return self; } - (BOOL)browser:sender selectCell:(const char *)title inColumn:(int)column /* This delegate method selects the cell with the given title. If it finds * a cell with that title, it verifies that it has a file entry in the * fileList, forces the loading of the cell, selects it (highlights) and * scrolls the browser so the cell is visible. It returns a boolean value * which indicates whether the cell was found. */ { int row; id matrix; if (title) { matrix = [sender matrixInColumn:column]; if (!fileList) return NO; for (row = [matrix cellCount]-1; row >= 0; row--) { if (fileList[row] && !strcmp(title, fileList[row])) { [sender getLoadedCellAtRow:row inColumn:column]; [matrix selectCellAt:row :0]; [matrix scrollCellToVisible:row :0]; return YES; } } } return NO; } /* WINDOW DELEGATE METHODS */ - windowWillResize:sender toSize:(NXSize *)frameSize; /* This method constrains the Help Panel to a reasonable minimum size * when the user resizes the panel. */ { frameSize->width = MAX(frameSize->width,400.0); frameSize->height = MAX(frameSize->height,350.0); return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.