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.