home *** CD-ROM | disk | FTP | other *** search
- //************************************************************************
- //
- // HLDelegate.m.
- //
- // NXBrowser delegate of the Hot list and HotList controller
- //
- // 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 "GKdefs.h"
- #import "HLDelegate.h"
- #import "HLRecord.h"
- #import "Coordinator.h"
- #import <appkit/appkit.h>
- #import <dbkit/DBImageView.h>
-
- #import <sys/types.h>
- #import <sys/dir.h> /* POSIX applications #include <dirent.h> */
-
-
- @implementation HLDelegate
-
- //************************************************************************
- //
- // sent to us after nib objects are unarchived and init'd
- //
- //************************************************************************
-
- - awakeFromNib
- {
- char *sC;
- NXRect spVRect; // sizeof splitview
- NXSize maxSize = {300.0, 600.0}; // max hotlist win size
-
- [[HLImageView setEditable:NO] setStyle:DB_ImageNoFrame];
-
- // theSplitView -- IB connected to be top view
- [theSplitView getFrame: &spVRect];
- spVRect.size.width -= 20;
- sC = NXCopyStringBuffer(NXGetDefaultValue([NXApp appName],BROWSERHT));
- // if not def and val is less than splitview's height
- if(atof(sC) > 600.0 || atof(sC) < 0.0)
- spVRect.size.height *= 2.0/3.0; // def, make top view 2/3 of splitview
- else
- spVRect.size.height = atof(sC); // per saved
- free(sC);
-
- HLBrowser = [[NXBrowser alloc] initFrame:&spVRect];
- [[[[[[[[HLBrowser setTitled:NO] // create and configure nxbrowser
- setHorizontalScrollButtonsEnabled:NO]
- setDelegate:self]
- setTarget:self]
- setAction:@selector(browserHit:)]
- setDoubleAction:@selector(browserDoubleClick:)]
- setMinColumnWidth:200]
- setMaxVisibleColumns:1];
-
- [theSplitView addSubview:HLBrowser];
- sC = NXCopyStringBuffer(NXGetDefaultValue([NXApp appName], ADDRESSHT));
- if(atof(sC) > 600.0 || atof(sC) < 0.0)
- spVRect.size.height /= 2.0; // make bottom view 1/3 of splitview
- else
- spVRect.size.height = atof(sC); // per saved
- free(sC);
- [addressView setFrame:&spVRect];
- [theSplitView addSubview:addressView];
- [theSplitView display];
-
- if(![[NXBundle mainBundle]getPath:oPath forResource:"options" ofType:NULL])
- oPath[0] = '\0';
- [self initHotListPath];
- // set each view in the heirarchy to resize its subviews
- [hotList setMaxSize:&maxSize];
- [hotList setFrameUsingName:[hotList title]]; // remem
- [hotList setFrameAutosaveName:[hotList title]];
-
- return self;
- }
- //*****************************************************************************
- //
- // initialize the hotlist and reinit if path to it is changed
- //
- //*****************************************************************************
-
- - initHotListPath
- {
- char *sC;
- // cell selection in hotList should persist between sessions
- // so recall previous selection
- sC = NXCopyStringBuffer(NXGetDefaultValue([NXApp appName],SELCELL));
- selCell = atoi(sC);
- free(sC);
-
- [HLBrowser loadColumnZero]; // NXBrowser s/load cols from its delegate
- if(hotListDirValid) // if hotList path is valid
- {
- mat = [HLBrowser matrixInColumn:0];
- [HLBrowser useScrollButtons:NO];
- if(!(selCell < [dirList count]))
- selCell = 0;
- if(selCell < [dirList count])
- {
- [mat selectCellAt:selCell :0];
- if(!(image = [[dirList objectAt:selCell] gateIcon]))
- image = [NXImage findImageNamed: "Blank"]; // else use blank
- [mat scrollCellToVisible:selCell :0];
- }
- else
- image = [NXImage findImageNamed: "Blank"]; // else use blank
- [HLImageView setImage:image];
- [HLProviderField setStringValue:
- [[[HLBrowser matrixInColumn:0] selectedCell] stringValue]];
- }
-
- return self;
- }
- //*****************************************************************************
- //
- // 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 ((dp = opendir(NXGetDefaultValue([NXApp appName], "HotList"))) != NULL)
- {
- if(!namHashTable) // alloc hashtable w/str keys, obj vals
- namHashTable = [[HashTable alloc] initKeyDesc:"*" valueDesc:"@"];
- else
- {
- tmpHashTable = [namHashTable copyFromZone:[self zone]];
- [namHashTable empty];
- }
- if(dirList)
- [dirList empty]; // empty list
- else
- dirList = [[List alloc] init]; // produce an array of objects
- if ([tmpHashTable isKey:"AppDefault"] == NO)
- { // create a HotList record for app default
- if (oPath[0] != '\0') // if options file exists in app wrapper
- {
- obj = [[HLRecord alloc] init];
- [obj setRecordPath:oPath];
- [namHashTable insertKey:"AppDefault" value:obj];
- }
- } // if record exists in hash
- else // use existing record
- [namHashTable insertKey:"AppDefault"
- value:[tmpHashTable valueForKey:"AppDefault"]];
- while (dirp = readdir(dp)) // read dir and find all
- { // entries with ext .Gate
- 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 HotList record
- obj = [[HLRecord alloc] init];
- [obj setGateDocName:dirp->d_name];
- [namHashTable insertKey:dirp->d_name value:obj];
- } // if record exists in hash
- else // use existing record
- [namHashTable insertKey:dirp->d_name
- value:[tmpHashTable valueForKey:dirp->d_name]];
- }
- }
- };
- [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];
- }
- };
- [m addRow]; // add row to HotList matrx
- t = [m cellAt:i :0]; // ret cell in NXBrowser
- [dirList addObject:obj];
- [t setStringValueNoCopy:[obj gateDocName]];
- [t setLoaded:YES];
- [t setLeaf:YES];
- obj = nil;
- }
- hotListDirValid = YES; // hotList dir was opened
- }
- else
- {
- [[NXApp delegate] showAlert:"Error opening HotList directory."];
- hotListDirValid = NO; // hotList dir is invalid
- }
-
- 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 HotList 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 HotList 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 hotList
- //
- //*****************************************************************************
-
- - 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 hotList
- //
- //*****************************************************************************
-
- - 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 hotlist
- //
- //*****************************************************************************
-
- - setDispPerCellAt:(int)selectedCell
- {
- if((strcmp([[[NXApp mainMenu] findCellWithTag:2] title],
- [[NXApp delegate] localString:"Connect"]) == 0) &&
- [[[NXApp mainMenu] findCellWithTag:2] isEnabled])
- { // item enabled
- [HLProviderField setStringValue:
- [[[HLBrowser matrixInColumn:0] selectedCell] stringValue]];
- if(!(image = [[dirList objectAt:selectedCell] gateIcon])) // if imge
- image = [NXImage findImageNamed: "Blank"]; // else use blank
- [HLImageView setImage:image];
- if(toolBarView)
- [toolBarView setImage:image];
- }
- if(prefBMat)
- {
- [prefBMat selectCellAt:selCell :0];
- [prefBMat scrollCellToVisible:selCell :0];
- }
-
- return self;
- }
- //*****************************************************************************
- //
- // link based on selected file
- //
- //*****************************************************************************
-
- - playLink
- {
- if([dirList count] >= 1) // open sel'td HotList file
- [[NXApp delegate]linkWithFile:[[dirList objectAt:selCell]gateDocPath]];
- 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];
- NXRect hlVRect;
-
- sprintf(tmpStr, "%d", selCell);
- // write an entry to defaults database
- if(!NXWriteDefault([NXApp appName], SELCELL, tmpStr))
- [[NXApp delegate] showAlert:"ddbWriteError"];
-
- [HLBrowser getFrame: &hlVRect];
- sprintf(tmpStr,"%f", hlVRect.size.height);
- // write an entry to defaults database
- if(!NXWriteDefault([NXApp appName], BROWSERHT, tmpStr))
- [[NXApp delegate] showAlert:"ddbWriteError"];
- [addressView getFrame: &hlVRect];
- sprintf(tmpStr,"%f", hlVRect.size.height);
- // write an entry to defaults database
- if(!NXWriteDefault([NXApp appName], ADDRESSHT, tmpStr))
- [[NXApp delegate] showAlert:"ddbWriteError"];
-
- return self;
- }
- //************************************************************************
- //
- // free simply gets rid of everything we created
- // This is how nice objects clean up.
- //
- //************************************************************************
-
- - free
- {
- if(dirList)
- {
- [dirList freeObjects]; // free list's objects
- [dirList free]; // free list object
- }
- if(namHashTable)
- [namHashTable free];
-
- return [super free];
- }
- //*****************************************************************************
- //
- // splitview delegate method, invoked after divider is moved by user
- //
- //*****************************************************************************
-
- - splitViewDidResizeSubviews:sender
- {
- NXRect graphRect; // sizeof scroll's content view
-
- [HLBrowser getFrame: &graphRect];
-
- return self;
- }
- //*****************************************************************************
- //
- // tell the Browser to load col 0
- //
- //*****************************************************************************
-
- - loadBrowser
- {
- [HLBrowser loadColumnZero]; // NXBrowser s/load cols from its delegate
- if(hotListDirValid) // if hotList path is valid
- {
- mat = [HLBrowser matrixInColumn:0];
- [mat selectCellAt:selCell :0];
- [mat scrollCellToVisible:selCell :0];
- [HLBrowser display];
- [hotList makeKeyAndOrderFront:self];
- }
-
- return self;
- }
- //*****************************************************************************
- //
- // send images back to this object
- //
- //*****************************************************************************
-
- - setToolBar:aView
- {
- toolBarView = aView;
- [toolBarView setImage:image];
-
- return self;
- }
- //*****************************************************************************
- //
- // send selected cell back to this object
- //
- //*****************************************************************************
-
- - setPreferencesBMat:aMatrix
- {
- prefBMat = aMatrix;
-
- return self;
- }
- //*****************************************************************************
- //
- // return the selectedCell
- //
- //*****************************************************************************
-
- - (int)hLSelectedCell
- {
- return selCell;
- }
- //*****************************************************************************
- //
- // return the statusWindow
- //
- //*****************************************************************************
-
- - statusWindow
- {
- return hotList;
- }
- //*****************************************************************************
- //
- // 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;
- }
- //******************* status Window delegate methods **************************
- //*****************************************************************************
- //
- // called whenever the user minituriazes our status window.
- //
- //*****************************************************************************
-
- - windowWillMiniaturize:sender toMiniwindow:miniwindow
- {
- return [sender setMiniwindowIcon:"miniWinIcon"];
- }
- //*****************************************************************************
- //
- // called whenever the user closes our status window.
- //
- //*****************************************************************************
-
- - windowWillClose:sender
- {
- if(!NXWriteDefault([NXApp appName], DISPLAYS, "NO"))
- [[NXApp delegate] showAlert:"ddbWriteError"];
-
- return self;
- }
-
- @end
-