This is DLDelegate.m in view mode; [Download] [Up]
//***************************************************************************** // // DLDelegate.m. // // Document List controller and NXBrowser delegate // // by Felipe A. Rodriguez // // This code is supplied "as is" the author makes no warranty as to its // suitability for any purpose. This code is free and may be distributed // in accordance with the terms of the: // // GNU GENERAL PUBLIC LICENSE // Version 2, June 1991 // copyright (C) 1989, 1991 Free Software Foundation, Inc. // 675 Mass Ave, Cambridge, MA 02139, USA // //***************************************************************************** #import <sys/types.h> #import <sys/dir.h> /* POSIX applications #include <dirent.h> */ #import <appkit/appkit.h> #import <dbkit/DBImageView.h> #import "GKdefs.h" #import "Coordinator.h" #import "DLDelegate.h" #import "DLRecord.h" #import "AlphaDBImageView.h" #import "GateDocEditor.h" @implementation DLDelegate //***************************************************************************** // // sent to us by controller from appDidInit // //***************************************************************************** - awake { [super awake]; [self testForDataDirectory]; // test existence of Gate doc directory [[SDImageView setEditable:NO] setStyle:DB_ImageNoFrame]; if(![[NXBundle mainBundle]getPath:oPath forResource:"options" ofType:NULL]) oPath[0] = '\0'; [self browser:nil fillMatrix:nil inColumn:0]; // load db [self initDList]; return self; } //***************************************************************************** // // initialize the doc directory and reinit if path to it is changed // //***************************************************************************** - initDList { char *sC; // cell selection in doc dir should persist between sessions // so recall previous selection sC = NXCopyStringBuffer(NXGetDefaultValue([NXApp appName], SELCELL)); selCell = atoi(sC); free(sC); if([dirList count] > 0) // if doc dir path is valid { if(!(selCell < [dirList count])) selCell = 0; if(!(image = [[dirList objectAt:selCell] gateIcon])) image = [NXImage findImageNamed: "Blank"]; // else use blank } else image = [NXImage findImageNamed: "Blank"]; // else use blank [SDImageView setImage:image]; [ISPField setStringValue:[self extractName: [[dirList objectAt:selCell] gateDocName]]]; return self; } //***************************************************************************** // // return dir List object // //***************************************************************************** - DList { return dirList; } //***************************************************************************** // // provide to listBrowser(NXBrowser) it's data to be displayed // do this because we are its delegate // //***************************************************************************** - (int)browser:b fillMatrix:m inColumn:(int)c { int i = 0, strSize; id t, obj = nil; char *ptr; NXHashState state; const void *key; void *value; struct direct *dirp; static DIR *dp = NULL, *dpOLD = NULL; if(dp) dpOLD = dp; if(dirList) [dirList empty]; // empty list else dirList = [[List alloc] init]; // produce an array of objects if ((dp = opendir(NXGetDefaultValue([NXApp appName], LIBPATH))) != NULL) { if(!namHashTable) // alloc hashtable w/str keys, obj vals namHashTable = [[HashTable alloc] initKeyDesc:"*" valueDesc:"@"]; else { tmpHashTable = [namHashTable copyFromZone:[self zone]]; [namHashTable empty]; } while (dirp = readdir(dp)) // read dir and find all { // entries with ext .Gate // if(dirp->d_namlen > 5) // future use if((strSize = strlen(dirp->d_name)) > 5) { ptr = dirp->d_name + strSize; // point to end of name str ptr -= 5; if(strcmp(ptr, ".Gate") == 0) // if extension is .Gate { // if str not in hash table if ([tmpHashTable isKey:dirp->d_name] == NO) { // create a doc dir record obj = [[DLRecord alloc] init]; [obj setGateDocName:dirp->d_name]; } // if record exists in hash else // use existing record obj = [tmpHashTable valueForKey:dirp->d_name]; [namHashTable insertKey:[obj gateDocName] value:obj]; } } }; [tmpHashTable free]; if(dpOLD) closedir(dpOLD); // sort and display dir in NXBrowser for(i = 0; i < [namHashTable count]; i++) { // Return NXHashState structure required // when iterating through the HashTable state = [namHashTable initState]; while ([namHashTable nextState:&state key:&key value:&value]) { // iterate thru the hashtable and perform if ([dirList indexOf:value] == NX_NOT_IN_LIST) { if(!obj) obj = value; // an ascending sort if(strcasecmp(key, [obj gateDocName]) < 0) obj = [namHashTable valueForKey:key]; } }; if(m) { [m addRow]; // add row to doc dir matrx t = [m cellAt:i :0]; // ret cell in NXBrowser [t setStringValueNoCopy:[obj gateDocName]]; [t setLoaded:YES]; [t setLeaf:YES]; } [dirList addObject:obj]; obj = nil; } } else // doc dir dir is invalid [[NXApp delegate] showAlert:"Error opening document directory."]; return i; } //***************************************************************************** // // target/action for a single click in the browser. // //***************************************************************************** - browserHit:sender { selCell = [[sender matrixInColumn:0] selectedRow]; [self setDispPerCellAt:selCell]; // display traits of sel'd cell return self; } //***************************************************************************** // // target/action method for a double click in the browser. // //***************************************************************************** - browserDoubleClick:sender { selCell = [[sender matrixInColumn:0] selectedRow]; [self setDispPerCellAt:selCell]; // display traits of sel'd cell if([dirList count] >= 1) // open sel'td doc dir file [[NXApp delegate] app:self openFile: [[dirList objectAt:selCell] gateDocPath] type:NULL]; else [[NXApp delegate] showAlert:"noSelectedDoc"]; return self; } //***************************************************************************** // // target/action for a single click in the preferences browser. // //***************************************************************************** - pBrowserHit:sender { selCell = [[sender matrixInColumn:0] selectedRow]; // [mat selectCellAt:selCell :0]; [self setDispPerCellAt:selCell]; // display traits of sel'd cell // [mat scrollCellToVisible:selCell :0]; return self; } //***************************************************************************** // // target/action method for a double click in the preferences browser. // //***************************************************************************** - pBrowserDoubleClick:sender { selCell = [[sender matrixInColumn:0] selectedRow]; // [mat selectCellAt:selCell :0]; [self setDispPerCellAt:selCell]; // display traits of sel'd cell // [mat scrollCellToVisible:selCell :0]; if([dirList count] >= 1) // open sel'td doc dir file [[NXApp delegate] app:self openFile: [[dirList objectAt:selCell] gateDocPath] type:NULL]; else [[NXApp delegate] showAlert:"noSelectedDoc"]; return self; } //***************************************************************************** // // go to next gate doc in doc dir // //***************************************************************************** - nextItem:sender { [sender setState:0]; if(selCell < ([dirList count] - 1)) selCell++; else selCell = 0; // [mat selectCellAt:selCell :0]; [self setDispPerCellAt:selCell]; // display traits of sel'd cell // [mat scrollCellToVisible:selCell :0]; return self; } //***************************************************************************** // // go to previous gate doc in doc dir // //***************************************************************************** - prevItem:sender { [sender setState:0]; if(selCell > 0) selCell--; else selCell = [dirList count] - 1; // [mat selectCellAt:selCell :0]; [self setDispPerCellAt:selCell]; // display traits of sel'd cell // [mat scrollCellToVisible:selCell :0]; return self; } //***************************************************************************** // // set views per selected cell in doc directory // //***************************************************************************** - setDispPerCellAt:(int)selectedCell { [ISPField setStringValue:[self extractName: [[dirList objectAt:selCell] gateDocName]]]; if(!(image = [[dirList objectAt:selectedCell] gateIcon])) // if imge image = [NXImage findImageNamed: "Blank"]; // else use blank [SDImageView setImage:image]; if(toolBarView) [toolBarView setImage:image]; return self; } //***************************************************************************** // // link based on selected document // //***************************************************************************** - link { if([dirList count] >= 1) // open sel'td doc dir file { [[NXApp delegate]linkWithFile:[[dirList objectAt:selCell]gateDocPath]]; // [ISPField setStringValue:[self extractName: // [[dirList objectAt:selCell] gateDocName]]]; } else [[NXApp delegate] showAlert:"noSelectedDoc"]; return self; } //***************************************************************************** // // forward anything in Greek to someone who might understand // //***************************************************************************** - forward:(SEL)aSelector :(marg_list)argFrame { // if ( [toolWin respondsTo:aSelector] ) // return [toolWin performv:aSelector :argFrame]; [self doesNotRecognize:aSelector]; // error abort process return self; } //***************************************************************************** // // app will terminate so save selected cell, browser size // //***************************************************************************** - appWillTerminate { char tmpStr[16]; sprintf(tmpStr, "%d", selCell); // write an entry to defaults database if(!NXWriteDefault([NXApp appName], SELCELL, tmpStr)) [[NXApp delegate] showAlert:"ddbWriteError"]; // save current doc path to ddb if(!NXWriteDefault([NXApp appName], CDOC, [[dirList objectAt:selCell] gateDocPath])) [[NXApp delegate] showAlert:"ddbWriteError"]; return self; } //***************************************************************************** // // free gets rid of everything we created // //***************************************************************************** - free { if(dirList) { [dirList freeObjects]; // free list's objects [dirList free]; // free list object } if(namHashTable) [namHashTable free]; return [super free]; } //***************************************************************************** // // send images back to this object // //***************************************************************************** - setToolBar:aView { toolBarView = aView; [toolBarView setImage:image]; return self; } //***************************************************************************** // // return the selectedCell // //***************************************************************************** - (int)hLSelectedCell { return selCell; } //***************************************************************************** // // return the path to the selected gate docs options file // //***************************************************************************** - (const char *)selGateDocOptionsPath { if([dirList count] >= 1) // path of selected doc { strncpy(oPath,[[dirList objectAt:selCell] gateDocPath], MAXPATHLEN); strncat(oPath, OPTION, MAXPATHLEN - strlen(oPath)); return oPath; } else [[NXApp delegate] showAlert:"noSelectedDoc"]; return NULL; } //***************************************************************************** // // test for existence of library directory, create if necessary // //***************************************************************************** - testForDataDirectory { static char *libSearch[] = {NULL, "~/Library/", "~/LocalLibrary/", "/Library/", "/LocalLibrary/", NULL}; int i = 0; static BOOL init = YES; int ret = -1; libSearch[0] = // chk preference setting first NXCopyStringBuffer(NXGetDefaultValue([NXApp appName], LIBPATH)); while((ret == -1) && libSearch[i] != NULL) // search for dir { if(*libSearch[i] == '~') // if rel path { // prepend home dir strncpy(Path, NXHomeDirectory(), MAXPATHLEN); if(Path[0] == '/') // if home is root dir strncpy(Path, libSearch[i++], MAXPATHLEN); else strncat(Path, libSearch[i++], MAXPATHLEN - strlen(Path)); } else // else absolute path strncpy(Path, libSearch[i++], MAXPATHLEN - strlen(Path)); if(i > 1) // append app name to def lib search entries strncat(Path, [NXApp appName], MAXPATHLEN - strlen(Path)); if((ret = access(Path, F_OK)) != -1) // test for existence of file { // save doc dir path to ddb if(!NXWriteDefault([NXApp appName], LIBPATH, Path)) [[NXApp delegate] showAlert:"ddbWriteError"]; } if(!init) // only first invocation while(libSearch[i++] != NULL); // searchs all paths } if(ret == -1) { // not found, so create doc dir strncpy(Path, NXHomeDirectory(), MAXPATHLEN); if(Path[0] == '/') // if home is root dir strncpy(Path, libSearch[3], MAXPATHLEN); else strncat(Path, libSearch[3], MAXPATHLEN - strlen(Path)); strncat(Path, [NXApp appName], MAXPATHLEN - strlen(Path)); mkdir(Path, (_S_IRUSR | _S_IWUSR | _S_IXUSR)); // owner rws if((ret = access(Path, F_OK)) != -1) // test for existence of file { // save doc dir path to ddb if(!NXWriteDefault([NXApp appName], LIBPATH, Path)) [[NXApp delegate] showAlert:"ddbWriteError"]; } else [[NXApp delegate] showAlert:"Error accessing library directory."]; chown(Path, getuid(), getgid()); // set owner to real user // create example doc in ddir strncat(Path, "/MyISP.Gate", MAXPATHLEN - strlen(Path)); if(mkdir(Path, (_S_IRUSR | _S_IWUSR | _S_IXUSR)) == -1) [[NXApp delegate] showAlert:"Error creating Gate doc."]; else { chown(Path, getuid(), getgid()); [theGateDocEditor addDefaultFiles:Path]; [theGateDocEditor editGateDoc:Path]; } } free(libSearch[0]); init = NO; // subsequent invocations will only search // preference set path return self; } //***************************************************************************** // // extracts the Gate doc name from its path // //***************************************************************************** - (const char *)extractName:(const char *)aPath { static char pathBuf[MAXPATHLEN]; char *ptr; strcpy(pathBuf, aPath); ptr = pathBuf + strlen(pathBuf) - 1; while(*ptr != '.' && *ptr) ptr--; *ptr-- = '\0'; while(*ptr != '/' && *ptr) ptr--; ++ptr; return ptr; } //******************* status Window delegate methods ************************** //***************************************************************************** // // called whenever the user closes our status window. // //***************************************************************************** - windowWillClose:sender { if(!NXWriteDefault([NXApp appName], DISPLAYS, "NO")) [[NXApp delegate] showAlert:"ddbWriteError"]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.