This is Thinspector.m in view mode; [Download] [Up]
// Thinspector.m // // contains more routines for the Thinker class, mostly related to // BackSpace's inspectors. // // You may freely copy, distribute, and reuse the code in this example. // NeXT disclaims any warranty of any kind, expressed or implied, as to its // fitness for any particular use. #import "Thinker.h" #import "BackWindow.h" #import "BackView.h" #import "SpaceView.h" #import "MySlider.h" #import "Password.h" #import "psfuncts.h" #import "ModuleList.h" #import <appkit/appkit.h> #import <objc/NXBundle.h> #import <sys/dir.h> /* for opendir(), etc. */ @implementation Thinker(inspector) - commonImageInspector { return commonImageInspector; } - nullInspector { return nullInspector; } - spaceInspector { return spaceInspector; } - boinkInspector { return boinkInspector; } - revertToDefaultImage:sender { [self setImageFromName: "defaultImage"]; NXRemoveDefault([NXApp appName], "imageFile"); return self; } - (BOOL)browser:sender columnIsValid:(int)column { return browserValid; } - addCellWithString:(const char *)str at:(int)row toMatrix:matrix { id theCell; [matrix insertRowAt:row]; theCell = [matrix cellAt:row :0]; [theCell setStringValue:str]; [theCell setLoaded:YES]; [theCell setLeaf:YES]; return self; } - (int)browser:sender fillMatrix:matrix inColumn:(int)column { const char *ptr; int i; // this shouldn't happen... if (browserValid) return [matrix cellCount]; [self addCellWithString:NXLocalString("All", 0, 0) at:0 toMatrix:matrix]; for (i = 0; i < [moduleList count]; i++) [self addCellWithString:NXLocalString([moduleList nameAt: i], 0, 0) at:(i+1) toMatrix:matrix]; realViewIndex = 0; ptr = NXGetDefaultValue("BackSpace", "viewType"); if (ptr) { for (i = 0; i < [moduleList count]; i++) if (strcmp(ptr, [moduleList nameAt: i]) == 0) { realViewIndex = i+1; break; } } browserValid = YES; return [matrix cellCount]; } // Dynamically load all object files found in the specified directory // if we find a module in several places, we save the additional paths // in case they point to modules for different architectures - loadViewsFrom: (const char *) dirname { DIR *dir; struct direct *de; char path[MAXPATHLEN]; char name[60]; char *iptr; ModuleInfo *m; BOOL validName, filePackage; dir = opendir(dirname); if (dir == NULL) { //perror(dirname); return self; } while ((de = readdir(dir)) != NULL) { int i, numstrings; // Ignore '.'-files (not really necessary, I guess) if (de->d_name[0] == '.') continue; filePackage = validName = NO; if (de->d_namlen > 10 && !strcmp(&de->d_name[de->d_namlen-10], "View.BackO")) { validName = YES; filePackage = NO; } else if (de->d_namlen > 15 && !strcmp(&de->d_name[de->d_namlen-15], "View.BackModule")) { validName = YES; filePackage = YES; } if (!validName) continue; // refuse to load if the name matches a module already loaded numstrings = [moduleList count]; strcpy(name, de->d_name); // Smash out the 'V' in "FooView.BackO" if (iptr = rindex(name, 'V')) *iptr = '\0'; for (i=0; i< numstrings; i++) { if (!strcmp(name, [moduleList nameAt:i])) { // we already have a module with this name, but will save the path anyway validName = NO; if (filePackage) sprintf(path,"%s/%sView.BackModule",dirname,name); else strcpy(path, dirname); [[moduleList objectAt:i] appendPath:path]; break; } } if (!validName) continue; // I used to load the class at this time; this got horribly // inefficient. I now wait until I'm about to instantiate // a view before doing this (thanx bbum!) if (filePackage) sprintf(path,"%s/%sView.BackModule",dirname,name); else strcpy(path, dirname); m = [[ModuleInfo alloc] initWithView:NULL name:name path:path]; [moduleList addObject: m]; } closedir(dir); return self; } - (BOOL)appAcceptsAnotherFile:sender { // return openAnother; // if I just return openAnother, I fail to open the module if // I get launched to do it. Punt until I think of a better solution. return YES; } - (int)app:sender openFile:(const char *)filename type:(const char *)aType { // Here we have caught BackSpace off guard; Speaker says open a file, // but BackSpace is already locked on a view because it doesn't unlock // focus or bail out of the event loop unless there's an event. // This is good for performance but it means it handles openfile badly; // it must post an event telling it to bail out of the event loop and // open the file later; multi file opens are therefore broken, and // the return value here is bogus... char path[MAXPATHLEN]; NXEvent anEvent; char *iptr; if (fileToOpen) { free(fileToOpen); fileToOpen = NULL; } strcpy(path,filename); if (!strcmp(aType,"BackModule")) { iptr = rindex(filename, '/'); strcat(path,iptr); // /xxx/fooView.BackModule/fooView.BackModule iptr = rindex(path, 'M'); strcat(iptr,"O"); // /xxx/fooView.BackModule/fooView.BackO } fileToOpen = NXCopyStringBuffer(path); openAnother = NO; anEvent.type = NX_APPDEFINED; anEvent.data.compound.subtype = BSOPENFILE; anEvent.ctxt = [NXApp context]; DPSPostEvent(&anEvent,0); return YES; } - doDelayedOpenFile { int i, numstrings; int ret = YES; char path[MAXPATHLEN]; id theMatrix; char *name; char *iptr; ModuleInfo *m; numstrings = [moduleList count]; strcpy(path, fileToOpen); if ((name = rindex(path, '/')) != NULL) *name = '\0'; name++; // Smash out the 'V' in "FooView.BackO" if ((iptr = rindex(name, 'V')) != NULL) *iptr = '\0'; for (i=0; i< numstrings; i++) { if (!strcmp(name, [moduleList nameAt:i])) { ret = NO; break; } } if (ret) { m = [[ModuleInfo alloc] initWithView:NULL name:name path:path]; [moduleList addObject: m]; browserValid = NO; [moduleList sort]; [viewSelectionBrowser loadColumnZero]; } theMatrix = [viewSelectionBrowser matrixInColumn:0]; numstrings = [moduleList count]; for (i=0; i< numstrings; i++) { if (!strcmp(name, [moduleList nameAt:i])) break; } realViewIndex = i+1; [theMatrix selectCellAt:realViewIndex :0]; [theMatrix scrollCellToVisible:realViewIndex :0]; [viewSelectionBrowser display]; [self setVirtualViewIndexAndIncrement:NO]; free(fileToOpen); fileToOpen = NULL; openAnother = YES; return self; } extern const char *appDirectory(); - (const char *) appDirectory { return appDirectory(); } - (const char *) moduleDirectory:(const char *)name { int i, numstrings; numstrings = [moduleList count]; for (i=0; i< numstrings; i++) { if (!strcmp(name, [moduleList nameAt:i])) return [[moduleList objectAt:i] path]; } return NULL; } - (struct mach_header *) headerForModule:(const char *)name { int i, numstrings; numstrings = [moduleList count]; for (i=0; i< numstrings; i++) { if (!strcmp(name, [moduleList nameAt:i])) return [[moduleList objectAt:i] header]; } return NULL; } static char *launchDir = NULL; /* if this is NULL, it will be calculated */ /** ** which-dir -- find the path for the named exectuable file ** Returns malloc'd string if it finds it, or NULL if it can't ** ** borrowed from Lennart, munged by sam **/ const char *which_dir(const char *file) { char buf[MAXPATHLEN]; char *paths, *p, *q; char *ret; int dirlen; paths = getenv("PATH"); if (paths == NULL) return NULL; for (p = q = paths; *q != '\0'; p = q + 1) { q = index(p, ':'); if (q == NULL) q = p + strlen(p); dirlen = q - p; sprintf(buf, "%.*s/%s", dirlen, p, file); if (access(buf, X_OK) != 0) continue; buf[dirlen] = '\0'; ret = malloc((dirlen+1)*sizeof(char)); strcpy(ret,buf); return ret; } return NULL; } const char *appDirectory() { char buf[MAXPATHLEN]; char *suffix, *path; if (launchDir) return launchDir; strcpy (buf,NXArgv[0]); suffix = rindex(buf,'/'); if (suffix != NULL) // explicit path { *suffix = '\0'; // remove executable name } else { path = (char *)which_dir([NXApp appName]); if (path != NULL) { launchDir = path; return launchDir; } else { // Don't know where we came from -- arbitrarily // presume "." and continue (it's better than breaking) strcpy(buf, "."); } } launchDir = malloc((strlen(buf)+1)*sizeof(char)); strcpy(launchDir,buf); return launchDir; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.