home *** CD-ROM | disk | FTP | other *** search
- #import "BrowserMatrix.h"
- #import <objc/List.h>
- #import <appkit/SelectionCell.h>
- #import <sys/types.h>
- #import <sys/stat.h>
- #import <sys/file.h>
- #import <math.h>
-
- static int slaveRow;
-
- extern int strcmp(), strlen(), stat();
- extern char *strcat(), *rindex();
-
- @implementation BrowserMatrix
-
- + newFrame:(NXRect *)r
- {
- NXSize r1;
- float height;
-
- self = [super newFrame:r
- mode:NX_RADIOMODE
- cellClass:[SelectionCell class]
- numRows:0
- numCols:1];
- slaves = [List new];
- master = nil;
- alphabetize = YES;
- height = r->size.height;
- visEntries = (int) floor ((double)height / TEXTHEIGHT);
- cellSize.height = height / (float) visEntries;
- cellSize.width = r->size.width;
- intercell.width = intercell.height = 0.0;
- mFlags.allowEmptySel = YES;
- topRow = 0;
- return self;
- }
-
- - mouseDown:(NXEvent *)event
- {
- int i, count;
-
- if (master != nil) return self;
- if ((count = [slaves count]) == 0) {
- [super mouseDown:event];
- return self;
- }
- [window disableFlushWindow];
- [super mouseDown:event];
- for (i = 0; i < count; i++) {
- [[slaves objectAt:i] selectEntryAt:selectedRow];
- }
- [window reenableFlushWindow];
- [window flushWindow];
- return self;
- }
-
- - selectEntryAt:(int)row
- {
- if (row < numRows) {
- if (master == nil) [window disableFlushWindow];
- [self selectCellAt:row :0];
- [self sendAction];
- [slaves makeObjectsPerform:@selector(selectEntryAt:)
- with:(id)row];
- if (master == nil) {
- [window reenableFlushWindow];
- [window flushWindow];
- }
- }
- return self;
- }
-
- - clear
- {
- int row, count;
-
- count = numRows;
- for (row = 0; row < count; row++) [self removeRowAt:0 andFree:YES];
- topRow = 0;
- [slaves makeObjectsPerform:@selector(clear)];
- return self;
- }
-
- - display
- {
- [self sizeToCells];
- if ([slaves count] == 0) {
- [super display];
- return self;
- }
- [window disableFlushWindow];
- [super display];
- [slaves makeObjectsPerform:@selector(display)];
- [window reenableFlushWindow];
- [window flushWindow];
- return self;
- }
-
- - (BOOL)atTop
- {
- return topRow == 0;
- }
-
- - (BOOL)atBottom
- {
- return (topRow + visEntries) >= numRows;
- }
-
- - scrollDown:sender
- {
- int bottomRow;
-
- if ((master != nil) && ([sender class] != [BrowserMatrix class]))
- return self;
- if ((bottomRow = ++topRow + visEntries - 1) >= numRows) {
- --topRow;
- --bottomRow;
- return self;
- }
- [self scrollCellToVisible:bottomRow :0];
- [self scrollCellToVisible:topRow :0];
- [slaves makeObjectsPerform:@selector(scrollDown:) with:self];
- return self;
- }
-
- - scrollUp:sender
- {
- if ((master != nil) && ([sender class] != [BrowserMatrix class]))
- return self;
- if (--topRow < 0) {
- topRow = 0;
- return self;
- }
- [self scrollCellToVisible:topRow :0];
- [slaves makeObjectsPerform:@selector(scrollUp:) with:self];
- return self;
- }
-
- - addEntry:(const char *)text leaf:(BOOL)yn
- {
- int row, count, i, selectable;
- id newCell, cells, slave;
- const char *name;
-
- if (master == nil) {
- if (alphabetize) {
- for (row = 0; row < numRows; row++) {
- name = [[cellList objectAt:row] stringValue];
- if (strcmp (name, text) >= 0) break;
- }
- }
- else row = numRows;
- [self insertRowAt:row];
- slaveRow = row;
- count = [slaves count];
- for (i = 0; i < count; i++) {
- slave = [slaves objectAt:i];
- [slave addEntry:"" leaf:YES];
- }
- selectable = YES;
- }
- else {
- row = slaveRow;
- [self insertRowAt:row];
- selectable = NO;
- }
- newCell = [self cellAt:row :0];
- [newCell setSelectable:selectable];
- [newCell setEditable:NO];
- [newCell setLeaf:yn];
- [newCell setStringValue:text];
- [self selectEntryAt:row];
- return self;
- }
-
- - removeEntry:aCell
- {
- int row, col;
-
- if (master == nil)
- [self getRow:&row andCol:&col ofCell:aCell];
- else row = (int)aCell;
- [self removeRowAt:row andFree:YES];
- [slaves makeObjectsPerform:@selector(removeEntry:) with:(id)row];
- if (master == nil) [self display];
- return self;
- }
-
- - listFiles:(const char *)dir suffix:(const char *)sfx
- {
- char command[128], *fgets(), *pt;
- FILE *pipe, *popen();
- void pclose();
- struct stat statbuf;
- BOOL oldalpha;
-
- oldalpha = alphabetize;
- alphabetize = NO;
- sprintf (command, "/bin/ls -1d 2>/dev/null %s/*", dir);
- if (sfx != NULL) {
- strcat (command, ".");
- strcat (command, sfx);
- }
- pipe = popen (command, "r");
- while (fgets (command, 128, pipe) != NULL) {
- command[strlen (command) - 1] = '\0';
- stat (command, &statbuf);
- if ((pt = rindex (command, '/')) != NULL) pt++;
- else pt = command;
- [self addEntry:pt leaf:!(statbuf.st_mode & S_IFDIR)];
- }
- pclose (pipe);
- alphabetize = oldalpha;
- return self;
- }
-
- - setMaster:anObject
- {
- master = anObject;
- return self;
- }
-
- - addSlave:aBrowserMatrix
- {
- if (master == nil) {
- [slaves addObjectIfAbsent:aBrowserMatrix];
- [aBrowserMatrix setMaster:self];
- }
- return self;
- }
-
- - setAlphabetize:(BOOL)yn
- {
- alphabetize = yn;
- return self;
- }
-
- - free
- {
- [slaves free];
- [super free];
- return self;
- }
-
- @end
-
-