home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-02-08 | 30.2 KB | 1,116 lines |
- //=============================================================================
- //
- // Copyright (C) 1995,1996 by Paul S. McCarthy and Eric Sunshine.
- // Written by Paul S. McCarthy and Eric Sunshine.
- // All Rights Reserved.
- //
- // This notice may not be removed from this source code.
- //
- // This object is included in the MiscKit by permission from the authors
- // and its use is governed by the MiscKit license, found in the file
- // "License.rtf" in the MiscKit distribution. Please refer to that file
- // for a list of all applicable permissions and restrictions.
- //
- //=============================================================================
- //-----------------------------------------------------------------------------
- // DirWindow.m
- //
- // Manages window which displays directory listing.
- //
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- // $Id$
- // $Log$
- //-----------------------------------------------------------------------------
- #import "DirWindow.h"
- #import "Defaults.h"
- #import "NameCache.h"
- #import <misckit/MiscTableScroll.h>
- #import <misckit/MiscTableCell.h>
- #import <errno.h>
- #import <appkit/NXImage.h>
- #import <appkit/workspaceRequest.h>
- #import <assert.h>
-
- #define USE_PRIVATE_ZONE 1
-
- #ifdef _POSIX_SOURCE
- # define GET_CURR_DIR(_BF_,_SZ_) getcwd(_BF_,_SZ_)
- #else
- # define GET_CURR_DIR(_BF_,_SZ_) getwd(_BF_)
- #endif
-
- #define CASCADE_MAX 10
- static int cascadeCounter = 0;
- static NXCoord cascadeOriginX;
- static NXCoord cascadeOriginY;
- static NXCoord cascadeDeltaX;
- static NXCoord cascadeDeltaY;
-
- static BOOL defaultAutoSort;
- static BOOL defaultShowHidden;
- static BOOL defaultHighlightDirs;
- static NXColor defaultColor;
- static NXSize defaultWinSize;
- static Font* defaultFont;
- static List* openDirs = 0;
- static OwnerCache* owners = 0;
- static GroupCache* groups = 0;
-
- static char const COLOR_DEF[] = "DirColor";
- static char const SIZE_DEF[] = "DirSize";
- static char const FONT_DEF[] = "DirFont";
- static char const SORT_DEF[] = "AutoSort";
- static char const HIDDEN_DEF[] = "ShowHidden";
- static char const HLIGHT_DEF[] = "HighlightDirs";
- static char const COL_SIZES_DEF[] = "ColSizes";
- static char const COL_ORDER_DEF[] = "ColOrder";
-
-
- //-----------------------------------------------------------------------------
- // normalize_path
- //-----------------------------------------------------------------------------
- static void normalize_path( char *buff, size_t sz )
- {
- char save_dir[ FILENAME_MAX + 1 ];
- char tmp[ FILENAME_MAX + 1 ];
-
- if (buff != 0 && sz > 0)
- {
- if (GET_CURR_DIR( save_dir, sizeof(save_dir) ) != 0)
- {
- if (chdir( buff ) == 0)
- {
- if (GET_CURR_DIR( tmp, sizeof(tmp) ) != 0)
- {
- int const tmp_len = strlen( tmp );
- if (tmp_len < sz)
- strcpy( buff, tmp );
- else
- {
- strncpy( buff, tmp, sz );
- buff[ sz - 1 ] = '\0';
- }
- }
- chdir( save_dir );
- }
- }
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // str_int
- //-----------------------------------------------------------------------------
- static char const* str_int( int n )
- {
- static char buff[ 32 ];
- sprintf( buff, "%d", n );
- return buff;
- }
-
-
- //-----------------------------------------------------------------------------
- // str_date
- //-----------------------------------------------------------------------------
- static char const* str_date( time_t t )
- {
- #define BUFF_SIZE 64
- static char buff[ BUFF_SIZE ];
- strftime( buff, BUFF_SIZE, "%m/%d/%y %H:%M", localtime(&t) );
- return buff;
- }
-
-
- //-----------------------------------------------------------------------------
- // str_perms
- //-----------------------------------------------------------------------------
- static char const* str_perms( unsigned int mode )
- {
- static char buff[ 16 ];
- char* s;
- int ftype;
- int c;
-
- s = buff;
-
- ftype = (mode & S_IFMT);
- switch (ftype)
- {
- case S_IFDIR: c = 'd'; break;
- case S_IFCHR: c = 'c'; break;
- case S_IFBLK: c = 'b'; break;
- case S_IFREG: c = '-'; break;
- case S_IFLNK: c = 'l'; break;
- case S_IFSOCK: c = 's'; break;
- default: c = '-'; break;
- }
- *s++ = c;
- *s++ = (mode & 0400) ? 'r' : '-';
- *s++ = (mode & 0200) ? 'w' : '-';
- *s++ = (mode & S_ISUID) ? 's' : (mode & 0100) ? 'x' : '-';
- *s++ = (mode & 0040) ? 'r' : '-';
- *s++ = (mode & 0020) ? 'w' : '-';
- *s++ = (mode & S_ISGID) ? 's' : (mode & 0010) ? 'x' : '-';
- *s++ = (mode & 0004) ? 'r' : '-';
- *s++ = (mode & 0002) ? 'w' : '-';
- *s++ = (mode & S_ISVTX) ? 't' : (mode & 0001) ? 'x' : '-';
- *s = '\0';
-
- return buff;
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_icon
- //-----------------------------------------------------------------------------
- static void fmt_icon( MiscTableScroll* ts, DirEntry const* de, id cell )
- {
- NXCoord h,w,s;
- NXSize sz;
- NXImage* img;
-
- w = [ts colSize:ICON_SLOT]; if (w == 0) w = 18;
- h = [ts uniformSizeRows]; if (h == 0) h = 18;
- s = (w < h ? w : h) - 1.0;
- sz.width = s;
- sz.height = s;
-
- img = [de->dir getImage:de];
- [img setSize: &sz];
- [cell setImage: img];
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_name
- //-----------------------------------------------------------------------------
- static void fmt_name( MiscTableScroll* ts, DirEntry const* de, id cell )
- {
- [cell setStringValueNoCopy: de->name];
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_size
- //-----------------------------------------------------------------------------
- static void fmt_size( MiscTableScroll* ts, DirEntry const* de, id cell )
- {
- [[cell setAlignment: NX_RIGHTALIGNED] setIntValue: de->st.st_size ];
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_modified
- //-----------------------------------------------------------------------------
- static void fmt_modified( MiscTableScroll* ts, DirEntry const* de, id cell )
- {
- int const t = (int) de->st.st_mtime;
- [cell setStringValue: str_date( t )];
- [cell setTag: t];
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_perms
- //-----------------------------------------------------------------------------
- static void fmt_perms( MiscTableScroll* ts, DirEntry const* de, id cell )
- {
- unsigned int const mode = de->st.st_mode;
- [cell setStringValue: str_perms(mode)];
- [cell setTag: mode];
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_owner
- //-----------------------------------------------------------------------------
- static void fmt_owner( MiscTableScroll* ts, DirEntry const* de, id cell )
- {
- [cell setStringValueNoCopy: [owners lookup:de->st.st_uid] ];
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_group
- //-----------------------------------------------------------------------------
- static void fmt_group( MiscTableScroll* ts, DirEntry const* de, id cell )
- {
- [cell setStringValueNoCopy: [groups lookup:de->st.st_gid] ];
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_hardlinks
- //-----------------------------------------------------------------------------
- static void fmt_hardlinks( MiscTableScroll* ts, DirEntry const* de, id cell )
- {
- [cell setIntValue: de->st.st_nlink];
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_softlink
- //-----------------------------------------------------------------------------
- static void fmt_softlink( MiscTableScroll* ts, DirEntry const* de, id cell )
- {
- char const* s = de->soft_link;
- [cell setStringValue: s ? s : "" ];
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_message
- //-----------------------------------------------------------------------------
- static void fmt_message( MiscTableScroll* ts, DirEntry const* de, id cell )
- {
- [cell setStringValue: strerror(de->err) ];
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_blank
- //-----------------------------------------------------------------------------
- static void fmt_blank( MiscTableScroll* ts, DirEntry const* de, id cell )
- {
- [cell setStringValueNoCopy:""];
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_unknown
- //-----------------------------------------------------------------------------
- static void fmt_unknown( MiscTableScroll* ts, DirEntry const* de, id cell )
- {
- [cell setStringValueNoCopy:"?"];
- }
-
-
-
- //-----------------------------------------------------------------------------
- // FORMAT_FUNC
- //-----------------------------------------------------------------------------
-
- typedef void (*FormatFunc)( MiscTableScroll* ts, DirEntry const* de, id cell );
-
- static FormatFunc FORMAT_FUNC[ MAX_SLOT ] =
- {
- fmt_icon, // ICON_SLOT,
- fmt_name, // NAME_SLOT,
- fmt_size, // SIZE_SLOT,
- fmt_modified, // MODIFIED_SLOT,
- fmt_perms, // PERMS_SLOT,
- fmt_owner, // OWNER_SLOT,
- fmt_group, // GROUP_SLOT,
- fmt_hardlinks, // HARDLINKS_SLOT,
- fmt_softlink, // SOFTLINK_SLOT,
- fmt_blank, // MESSAGE_SLOT
- };
-
- static FormatFunc FORMAT_ERR_FUNC[ MAX_SLOT ] =
- {
- fmt_icon, // ICON_SLOT,
- fmt_name, // NAME_SLOT,
- fmt_unknown, // SIZE_SLOT,
- fmt_unknown, // MODIFIED_SLOT,
- fmt_unknown, // PERMS_SLOT,
- fmt_unknown, // OWNER_SLOT,
- fmt_unknown, // GROUP_SLOT,
- fmt_unknown, // HARDLINKS_SLOT,
- fmt_softlink, // SOFTLINK_SLOT,
- fmt_message, // MESSAGE_SLOT
- };
-
-
- //-----------------------------------------------------------------------------
- // format_cell
- //-----------------------------------------------------------------------------
- static inline void format_cell(
- MiscTableScroll* ts,
- DirEntry const* de,
- id cell,
- unsigned int col )
- {
- if (de->err == 0)
- (*(FORMAT_FUNC[col]))( ts, de, cell );
- else
- (*(FORMAT_ERR_FUNC[col]))( ts, de, cell );
- }
-
-
- //=============================================================================
- // IMPLEMENTATION
- //=============================================================================
- @implementation DirWindow
-
- //-----------------------------------------------------------------------------
- // + initCascader
- //-----------------------------------------------------------------------------
- + (void) initCascader
- {
- NXSize screenSize;
- [NXApp getScreenSize: &screenSize];
- cascadeOriginX = screenSize.width / 4;
- cascadeOriginY = screenSize.height - 20;
- cascadeDeltaX = 20;
- cascadeDeltaY = 20;
- }
-
-
- //-----------------------------------------------------------------------------
- // + initialize
- //-----------------------------------------------------------------------------
- + initialize
- {
- if (self == [DirWindow class])
- {
- [self initCascader];
- openDirs = [[List alloc] init];
- defaultColor = [Defaults getColor:COLOR_DEF fallback:NX_COLORLTGRAY];
- defaultAutoSort = [Defaults getBool:SORT_DEF fallback:NO];
- defaultShowHidden = [Defaults getBool:HIDDEN_DEF fallback:NO];
- defaultHighlightDirs = [Defaults getBool:HLIGHT_DEF fallback:NO];
- owners = [OwnerCache commonInstance];
- groups = [GroupCache commonInstance];
- }
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - cascade
- //-----------------------------------------------------------------------------
- - (void) cascade
- {
- NXCoord top,left;
- left = cascadeOriginX + (cascadeDeltaX * cascadeCounter);
- top = cascadeOriginY - (cascadeDeltaY * cascadeCounter);
- [window moveTopLeftTo: left : top ];
- if (++cascadeCounter >= CASCADE_MAX)
- cascadeCounter = 0;
- }
-
-
- //-----------------------------------------------------------------------------
- // - updateButtons
- //-----------------------------------------------------------------------------
- - (void) updateButtons
- {
- BOOL enable = NO;
- if ([scroll numSelectedRows] == 1)
- {
- MiscCoord_P const row = [scroll selectedRow];
- enable = [dir_array isDirAt:row];
- }
- if (enable != [cdButton isEnabled])
- [cdButton setEnabled: enable];
- }
-
-
- //-----------------------------------------------------------------------------
- // - tableScroll:cellAt::
- //-----------------------------------------------------------------------------
- - tableScroll:(MiscTableScroll*)ts cellAt: (int)row : (int)col
- {
- id cell = lazy_row[col];
- DirEntry const* const de = [dir_array entryAt:row];
- format_cell( ts, de, cell, col );
- if ([cell respondsTo:@selector(setBackgroundColor:)])
- {
- if (highlightDirs && [dir_array isDir:de])
- [cell setBackgroundColor:NX_COLORCYAN];
- else
- [cell setBackgroundColor:[ts backgroundColor]];
- }
- return cell;
- }
-
-
- //-----------------------------------------------------------------------------
- // - tableScroll:stringValueAt::
- //-----------------------------------------------------------------------------
- - (char const*) tableScroll:(MiscTableScroll*)ts stringValueAt:(int)r :(int)c
- {
- char const* rc = 0;
- if (r < [dir_array count])
- {
- DirEntry const* const de = [dir_array entryAt:r];
- if (de->err == 0)
- {
- switch (c)
- {
- case SIZE_SLOT: rc = str_int(de->st.st_size); break;
- case MODIFIED_SLOT: rc = str_date(de->st.st_mtime); break;
- case PERMS_SLOT: rc = str_perms(de->st.st_mode); break;
- case OWNER_SLOT: rc = [owners lookup:de->st.st_uid]; break;
- case GROUP_SLOT: rc = [groups lookup:de->st.st_gid]; break;
- case HARDLINKS_SLOT:rc = str_int(de->st.st_nlink); break;
- case NAME_SLOT: rc = de->name; break;
- case SOFTLINK_SLOT: rc = de->soft_link; break;
- case MESSAGE_SLOT:
- case ICON_SLOT:
- default: rc = ""; break;
- }
- }
- else
- {
- switch (c)
- {
- case NAME_SLOT: rc = de->name; break;
- case SOFTLINK_SLOT: rc = de->soft_link; break;
- case MESSAGE_SLOT: rc = strerror(de->err); break;
- case SIZE_SLOT:
- case MODIFIED_SLOT:
- case PERMS_SLOT:
- case OWNER_SLOT:
- case GROUP_SLOT:
- case HARDLINKS_SLOT:
- case ICON_SLOT:
- default: rc = "?"; break;
- }
- }
- }
- return (rc ? rc : "");
- }
-
-
- //-----------------------------------------------------------------------------
- // -intValueAt::
- //-----------------------------------------------------------------------------
- - (int) intValueAt:(int)r :(int)c
- {
- int rc = 0;
- if (r < [dir_array count])
- {
- DirEntry const* const de = [dir_array entryAt:r];
- if (de->err == 0)
- {
- switch (c)
- {
- case SIZE_SLOT: rc = de->st.st_size; break;
- case MODIFIED_SLOT: rc = de->st.st_mtime; break;
- case PERMS_SLOT: rc = de->st.st_mode; break;
- case OWNER_SLOT: rc = de->st.st_uid; break;
- case GROUP_SLOT: rc = de->st.st_gid; break;
- case HARDLINKS_SLOT: rc = de->st.st_nlink; break;
- case ICON_SLOT:
- case NAME_SLOT:
- case SOFTLINK_SLOT:
- case MESSAGE_SLOT:
- default: break;
- }
- }
- }
- return rc;
- }
-
- //-----------------------------------------------------------------------------
- // - tableScroll:intValueAt::
- //-----------------------------------------------------------------------------
- - (int) tableScroll:(MiscTableScroll*)ts intValueAt:(int)r :(int)c
- {
- return [self intValueAt:r:c];
- }
-
-
- //-----------------------------------------------------------------------------
- // - tableScroll:tagAt::
- //-----------------------------------------------------------------------------
- - (int) tableScroll:(MiscTableScroll*)ts tagAt:(int)r :(int)c
- {
- return [self intValueAt:r:c];
- }
-
-
- //-----------------------------------------------------------------------------
- // - tableScroll:fontChangedFrom:to:
- //-----------------------------------------------------------------------------
- - tableScroll:(MiscTableScroll*)ts
- fontChangedFrom:(Font*)oldFont
- to:(Font*)newFont
- {
- int col;
- for (col = 0; col < MAX_SLOT; col++)
- [lazy_row[col] setFont:newFont];
-
- defaultFont = newFont;
- [Defaults set:FONT_DEF font:defaultFont];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - tableScroll:border:slotResized:
- //-----------------------------------------------------------------------------
- - tableScroll:(MiscTableScroll*)ts
- border:(MiscBorderType)b
- slotResized:(int)n
- {
- char* s;
- assert( b == MISC_COL_BORDER );
- s = [ts colSizesAsString:0 size:0 canExpand:YES];
- [Defaults set:COL_SIZES_DEF str:s];
- free( s );
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - tableScroll:border:slotDraggedFrom:to:
- //-----------------------------------------------------------------------------
- - tableScroll:(MiscTableScroll*)ts
- border:(MiscBorderType)b
- slotDraggedFrom:(int)fromPos
- to:(int)toPos;
- {
- char* s;
- assert( b == MISC_COL_BORDER );
- s = [ts colOrderAsString:0 size:0 canExpand:YES];
- [Defaults set:COL_ORDER_DEF str:s];
- free( s );
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - fillScroll
- //-----------------------------------------------------------------------------
- - (void) fillScroll
- {
- char buff[ 128 ];
-
- [window disableDisplay];
-
- [scroll renewRows: [dir_array count]];
-
- if ([scroll autoSortRows])
- [scroll sortRows];
-
- sprintf( buff, "%d files %d bytes",
- [dir_array count], [dir_array totalBytes] );
- [countField setStringValue:buff];
-
- [self updateButtons];
- [[window reenableDisplay] display];
- }
-
-
- //-----------------------------------------------------------------------------
- // - setPath:
- //-----------------------------------------------------------------------------
- - (void) setPath:(char const*)dirname
- {
- NXZone* const z = [self zone];
- int dirlen;
- if (path != 0) NXZoneFree( z, path );
- if (dirname == 0) dirname = NXHomeDirectory();
- if (dirname == 0) dirname = "/";
- dirlen = strlen( dirname ) + 1;
- path = (char*) NXZoneMalloc( z, dirlen );
- memcpy( path, dirname, dirlen );
- [window setTitle: path];
- }
-
-
- //-----------------------------------------------------------------------------
- // - loadDirectory:
- //-----------------------------------------------------------------------------
- - (void) loadDirectory:(char const*)dirname
- {
- int rc = [dir_array loadPath:dirname showHidden:showHidden];
- if (rc != 0)
- {
- NXRunAlertPanel( "Can't Open",
- "Cannot open directory, %s\n%d:%s", "OK",0,0,
- path, rc, strerror(rc) );
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // - reload
- //-----------------------------------------------------------------------------
- - (void) reload
- {
- [self loadDirectory:path];
- [self fillScroll];
- }
-
-
- //-----------------------------------------------------------------------------
- // - load:
- //-----------------------------------------------------------------------------
- - (void) load:(char const*)dirname
- {
- [self setPath:dirname];
- [self reload];
- }
-
-
- //-----------------------------------------------------------------------------
- // - open:
- //-----------------------------------------------------------------------------
- - open:sender
- {
- if ([scroll hasRowSelection])
- {
- int i;
- int path_len;
- char buff[ FILENAME_MAX + 1 ];
- MiscIntList* list = [[MiscIntList allocFromZone:[self zone]] init];
-
- strcpy( buff, path );
- path_len = strlen( buff );
- if (path_len == 0 || buff[path_len - 1] != '/')
- {
- buff[ path_len++ ] = '/';
- buff[ path_len ] = '\0';
- }
-
- [scroll selectedRows: list];
- for (i = [list count]; i-- > 0; )
- {
- int row = [list intAt:i];
- DirEntry const* de = [dir_array entryAt:row];
-
- strcpy( buff + path_len, de->name );
- if ([dir_array isDir:de])
- [[self class] launchDir: buff];
- else
- [[Application workspace] openFile: buff];
- }
- [list free];
- }
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - destroy:
- //-----------------------------------------------------------------------------
- - destroy:sender
- {
- if ([scroll hasRowSelection])
- {
- size_t total_len = 0;
- char* file_list;
- int i;
- NXZone* const z = [self zone];
- MiscIntList* list = [[MiscIntList allocFromZone:z] init];
-
- [scroll selectedRows: list];
-
- for (i = [list count]; i-- > 0; )
- {
- DirEntry const* de = [dir_array entryAt:[list intAt:i]];
- if (de->name != 0)
- total_len += strlen( de->name ) + 1;
- }
-
- file_list = (char*) NXZoneMalloc( z, total_len + 1 );
-
- total_len = 0;
- for (i = [list count]; i-- > 0; )
- {
- DirEntry const* de = [dir_array entryAt:[list intAt:i]];
- char const* const s = de->name;
- if (s != 0)
- {
- int const len = strlen( s );
- strcpy( file_list + total_len, s );
- total_len += len;
- file_list[ total_len++ ] = '\t';
- }
- }
- file_list[ total_len ] = '\0';
-
- [[Application workspace]
- performFileOperation: WSM_DESTROY_OPERATION
- source: path
- destination: ""
- files: file_list
- options: ""];
-
- NXZoneFree( z, file_list );
- [list free];
- [self reload];
- }
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - updatePressed:
- //-----------------------------------------------------------------------------
- - updatePressed:sender
- {
- [self reload];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - cdPressed:
- //-----------------------------------------------------------------------------
- - cdPressed:sender
- {
- if ([scroll numSelectedRows] == 1)
- {
- DirEntry const* const de = [dir_array entryAt:[scroll selectedRow]];
- if ([dir_array isDir:de])
- {
- char buff[ FILENAME_MAX * 2 + 1 ];
- strcat( strcat( strcpy( buff, path ), "/" ), de->name );
- normalize_path( buff, sizeof(buff) );
- [self load:buff];
- }
- }
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - autoSortClick:
- //-----------------------------------------------------------------------------
- - autoSortClick:sender
- {
- BOOL const switchState = [autoSortSwitch state];
- if (autoSort != switchState)
- {
- defaultAutoSort = autoSort = switchState;
- [Defaults set:SORT_DEF bool:defaultAutoSort];
- [scroll setAutoSortRows:switchState];
- if (switchState)
- [scroll sortRows];
- }
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - hiddenFilesClick:
- //
- // FIXME: Should not have to rescan the whole directory just to show/hide
- // hidden files. A more careful implementation would not be this sloppy.
- //-----------------------------------------------------------------------------
- - hiddenFilesClick:sender
- {
- BOOL const switchState = [hiddenFilesSwitch state];
- if (showHidden != switchState)
- {
- defaultShowHidden = showHidden = switchState;
- [Defaults set:HIDDEN_DEF bool:defaultShowHidden];
- [self reload];
- }
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - highlightClick:
- //-----------------------------------------------------------------------------
- - highlightClick:sender
- {
- BOOL const switchState = [highlightSwitch state];
- if (highlightDirs != switchState)
- {
- defaultHighlightDirs = highlightDirs = switchState;
- [Defaults set:HLIGHT_DEF bool:defaultHighlightDirs];
- [scroll display];
- }
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - didClick:
- //-----------------------------------------------------------------------------
- - didClick:sender
- {
- [self updateButtons];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - didDoubleClick:
- //-----------------------------------------------------------------------------
- - didDoubleClick:sender
- {
- [self open:sender];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - makeKeyAndOrderFront:
- //-----------------------------------------------------------------------------
- - makeKeyAndOrderFront:sender
- {
- [window makeKeyAndOrderFront:sender];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - windowWillClose:
- //-----------------------------------------------------------------------------
- - windowWillClose:sender
- {
- [openDirs removeObject:self];
- [NXApp delayedFree: self];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - windowDidResize:
- //-----------------------------------------------------------------------------
- - windowDidResize:sender
- {
- NXRect r; [sender getFrame:&r];
- if (r.size.width != defaultWinSize.width ||
- r.size.height != defaultWinSize.height)
- {
- defaultWinSize = r.size;
- [Defaults set:SIZE_DEF size:defaultWinSize];
- }
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - setDefaultColor
- //-----------------------------------------------------------------------------
- - (void) setDefaultColor: (NXColor)c
- {
- defaultColor = c;
- [Defaults set:COLOR_DEF color:c];
- }
-
-
- //-----------------------------------------------------------------------------
- // - setDaColors:
- //-----------------------------------------------------------------------------
- - (void) setDaColors: (NXColor)c
- {
- [window disableDisplay];
- [window setBackgroundColor:c];
- [scroll setColor:c];
- [window reenableDisplay];
- }
-
-
- //-----------------------------------------------------------------------------
- // - draggingEntered:
- //-----------------------------------------------------------------------------
- - (NXDragOperation) draggingEntered:(id<NXDraggingInfo>)sender
- {
- return ([sender draggingSourceOperationMask] & NX_DragOperationGeneric);
- }
-
-
- //-----------------------------------------------------------------------------
- // - performDragOperation:
- //-----------------------------------------------------------------------------
- - (BOOL) performDragOperation:(id<NXDraggingInfo>)sender
- {
- [self setDefaultColor:
- NXReadColorFromPasteboard( [sender draggingPasteboard] )];
- [self setDaColors: defaultColor];
- [window display];
- return YES;
- }
-
-
- //-----------------------------------------------------------------------------
- // - initLazyRow
- //-----------------------------------------------------------------------------
- - (void) initLazyRow
- {
- Font* font = [scroll font];
- NXZone* const z = [self zone];
- int i;
- for (i = 0; i < MAX_SLOT; i++)
- {
- id cell = [[scroll colCellPrototype:i] copyFromZone:z];
- if ([cell respondsTo:@selector(setFont:)])
- [cell setFont:font];
- lazy_row[i] = cell;
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // - initDefaults
- //-----------------------------------------------------------------------------
- - (void) initDefaults
- {
- static BOOL initialized = NO;
- if (!initialized)
- {
- NXRect r; [window getFrame:&r];
- defaultWinSize = r.size;
-
- defaultFont = [Defaults getFont:FONT_DEF fallback:[scroll font]];
-
- initialized = YES;
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // - loadDefaults
- //-----------------------------------------------------------------------------
- - (void) loadDefaults
- {
- NXRect r;
- char const* s;
-
- [window getFrame:&r];
- r.size = [Defaults getSize:SIZE_DEF fallback:defaultWinSize];
- [window placeWindow:&r];
-
- autoSort = defaultAutoSort;
- showHidden = defaultShowHidden;
- highlightDirs = defaultHighlightDirs;
-
- [autoSortSwitch setState:autoSort];
- [hiddenFilesSwitch setState:showHidden];
- [highlightSwitch setState:highlightDirs];
-
- [scroll setAutoSortRows:autoSort];
- [scroll setFont:defaultFont];
- [self setDaColors:defaultColor];
-
- s = [Defaults getStr:COL_SIZES_DEF fallback:0];
- if (s)
- [scroll setColSizesFromString:s];
-
- s = [Defaults getStr:COL_ORDER_DEF fallback:0];
- if (s)
- [scroll setColOrderFromString:s];
- }
-
-
- //-----------------------------------------------------------------------------
- // - initDir:
- //-----------------------------------------------------------------------------
- - initDir:(char const*)dirname
- {
- char buff[ FILENAME_MAX + 1 ];
- NXZone* const z = [self zone];
-
- [super init];
- [[NXBundle bundleForClass:[self class]]
- getPath:buff forResource:[[self class] name] ofType:"nib"];
- [NXApp loadNibFile:buff owner:self withNames:NO fromZone:z];
- [window registerForDraggedTypes:&NXColorPboardType count:1];
- path = 0;
- [scroll setDoubleAction: @selector(didDoubleClick:)];
- dir_array = [[DirArray allocFromZone:z] init];
- [self initDefaults];
- [self loadDefaults];
- [self initLazyRow];
- [self load:dirname];
- [openDirs addObject:self];
- [self cascade];
- [window makeKeyAndOrderFront:self];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - init
- //-----------------------------------------------------------------------------
- - init
- {
- return [self initDir: NXHomeDirectory()];
- }
-
-
- //-----------------------------------------------------------------------------
- // - free
- //-----------------------------------------------------------------------------
- - free
- {
- int i;
- #if(USE_PRIVATE_ZONE)
- NXZone* const z = [self zone];
- #endif
- [window close];
- [window free];
- if (path != 0)
- free( path );
- [dir_array free];
- for (i = 0; i < MAX_SLOT; i++)
- [lazy_row[i] free];
- [super free];
- #if(USE_PRIVATE_ZONE)
- NXDestroyZone( z );
- #endif
- return 0;
- }
-
-
- //-----------------------------------------------------------------------------
- // - path
- //-----------------------------------------------------------------------------
- - (char const*) path
- {
- return path;
- }
-
-
- //-----------------------------------------------------------------------------
- // + findDir:
- //-----------------------------------------------------------------------------
- + (DirWindow*) findDir:(char const*) normalized_path
- {
- DirWindow* p = 0;
- if (normalized_path != 0)
- {
- char const* s;
- unsigned int i;
- unsigned int const lim = [openDirs count];
- for (i = 0; i < lim; i++)
- {
- p = (DirWindow*) [openDirs objectAt:i];
- s = [p path];
- if (s != 0 && strcmp( s, normalized_path ) == 0)
- return p;
- }
- }
- return 0;
- }
-
-
- //-----------------------------------------------------------------------------
- // + launchDir:
- //-----------------------------------------------------------------------------
- + launchDir: (char const*) dirname
- {
- DirWindow* p = 0;
- char buff[ FILENAME_MAX + 1 ];
- if (dirname == 0) dirname = NXHomeDirectory();
- if (dirname == 0) dirname = "/";
- strncpy( buff, dirname, sizeof(buff) );
- buff[ sizeof(buff) - 1 ] = '\0';
- normalize_path( buff, sizeof(buff) );
- if ((p = [self findDir:buff]) != 0)
- [p makeKeyAndOrderFront:self];
- else
- {
- #if(USE_PRIVATE_ZONE)
- NXZone* z = NXCreateZone( vm_page_size, vm_page_size, YES );
- p = [[self allocFromZone:z] initDir:buff];
- #else
- p = [[self alloc] initDir:buff];
- #endif
- }
- return p;
- }
-
-
- @end
-