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.