home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-03-31 | 40.2 KB | 1,294 lines |
- //=============================================================================
- //
- // Copyright (C) 1995,1996,1997,1998 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: DirWindow.m,v 1.7 98/03/30 00:19:19 sunshine Exp $
- // $Log: DirWindow.m,v $
- // Revision 1.7 98/03/30 00:19:19 sunshine
- // v18.1: Wasn't respecting selected-text color. Problem was cell's "owner"
- // was never getting set.
- // Now uses NSColor's "system" color by default for window rather than
- // hard-wired light-gray.
- // Added -tableScrollIgnoreModifierKeysWhileDragging: returning NO.
- // Had to implement -tableScroll:draggingSourceOperationMaskForLocal: since
- // in MiscTableScroll v126.1 the default changed from "copy" to "generic".
- //
- // Revision 1.6 97/11/24 19:50:47 sunshine
- // v17.1: Fixed bug: Menu was sending -print: to first-responder even though
- // any control can be first-responder, rather than just MiscTableScroll.
- // Added row-numbers switch. Adjusted initial cascade position for NT.
- //
- // Revision 1.5 97/07/08 12:46:32 sunshine
- // v16.1: Synchronized with NEXTSTEP 3.3 LazyScrollDir v16.
- //-----------------------------------------------------------------------------
- #import "DirWindow.h"
- #import "Defaults.h"
- #import "DirArray.h"
- #import <MiscTableScroll/MiscExporter.h>
- #import <MiscTableScroll/MiscTableScroll.h>
- #import <MiscTableScroll/MiscTableCell.h>
- #import <AppKit/NSButton.h>
- #import <AppKit/NSFont.h>
- #import <AppKit/NSImage.h>
- #import <AppKit/NSNibLoading.h>
- #import <AppKit/NSPanel.h>
- #import <AppKit/NSPasteboard.h>
- #import <AppKit/NSTextField.h>
- #import <AppKit/NSWorkspace.h>
- #import <Foundation/NSFileManager.h>
- #import <sys/stat.h>
-
- // MS-Windows doesn't define these:
- #ifndef S_ISUID
- # define S_ISUID 0004000 /* Set user id on execution */
- #endif
- #ifndef S_ISGID
- # define S_ISGID 0002000 /* Set group id on execution */
- #endif
- #ifndef S_ISVTX
- # define S_ISVTX 0001000 /* Save swapped text even after use */
- #endif
-
- enum
- {
- ICON_SLOT,
- NAME_SLOT,
- LOCK_SLOT,
- SIZE_SLOT,
- MODIFIED_SLOT,
- PERMS_SLOT,
- OWNER_SLOT,
- GROUP_SLOT,
- HARDLINKS_SLOT,
- SOFTLINK_SLOT,
-
- MAX_SLOT
- };
-
- static int const CASCADE_MAX = 10;
- static int CASCADE_COUNTER = 0;
- static float CASCADE_ORIGIN_X;
- static float CASCADE_ORIGIN_Y;
- static float CASCADE_DELTA_X;
- static float CASCADE_DELTA_Y;
-
- static BOOL DEFAULT_AUTO_SORT;
- static BOOL DEFAULT_ROW_NUMBERS;
- static BOOL DEFAULT_SHOW_HIDDEN;
- static BOOL DEFAULT_HIGHLIGHT_DIRS;
- static BOOL DEFAULT_DRAG_UNSCALED;
- static NSColor* DEFAULT_COLOR;
- static NSSize DEFAULT_WIN_SIZE;
- static NSFont* DEFAULT_FONT;
- static NSMutableArray* OPEN_DIRS = 0;
- static NSImage* LOCKED_IMAGE = 0;
- static NSImage* UNLOCKED_IMAGE = 0;
-
- static NSString* const COLOR_DEF = @"DirColor";
- static NSString* const SIZE_DEF = @"DirSize";
- static NSString* const FONT_DEF = @"DirFont";
- static NSString* const SORT_DEF = @"AutoSort";
- static NSString* const HIDDEN_DEF = @"ShowHidden";
- static NSString* const HLIGHT_DEF = @"HighlightDirs";
- static NSString* const UNSCALED_DEF = @"DragUnscaled";
- static NSString* const COL_SIZES_DEF = @"ColSizes";
- static NSString* const COL_ORDER_DEF = @"ColOrder";
- static NSString* const ROW_NUMBERS_DEF = @"RowNumbers";
-
- static NSString* const LOCKED_IMAGE_S = @"Lock.secure";
- static NSString* const UNLOCKED_IMAGE_S = @"Lock.insecure";
-
-
- //-----------------------------------------------------------------------------
- // NOTE: USE_PRIVATE_ZONE
- // When set to '1', this program will place each window in a separate
- // NSZone and destroy the zone when the window is closed. When set to
- // '0' windows are placed in the NSDefaultMallocZone().
- //-----------------------------------------------------------------------------
- #define USE_PRIVATE_ZONE 1
-
- #if USE_PRIVATE_ZONE
- # define EMPLOY_ZONE() NSCreateZone( NSPageSize(), NSPageSize(), YES )
- # define RETIRE_ZONE(Z) NSRecycleZone(Z)
- #else
- # define EMPLOY_ZONE() NSDefaultMallocZone()
- # define RETIRE_ZONE(Z) (void)(Z)
- #endif
-
-
- //-----------------------------------------------------------------------------
- // normalize_path
- //-----------------------------------------------------------------------------
- static inline NSString* normalize_path( NSString* buff )
- {
- return [buff stringByStandardizingPath];
- }
-
-
- //-----------------------------------------------------------------------------
- // str_date
- //-----------------------------------------------------------------------------
- static NSString* str_date( NSDate* d )
- {
- return [d descriptionWithCalendarFormat:@"%m/%d/%y %H:%M"
- timeZone:0 locale:0];
- }
-
-
- //-----------------------------------------------------------------------------
- // str_perms
- //-----------------------------------------------------------------------------
- static NSString* str_perms( unsigned long mode, NSString* file_type )
- {
- char c;
- NSMutableString* s = [NSMutableString string];
- if ([file_type isEqualToString:NSFileTypeDirectory])
- c = 'd';
- else if ([file_type isEqualToString:NSFileTypeCharacterSpecial])
- c = 'c';
- else if ([file_type isEqualToString:NSFileTypeBlockSpecial])
- c = 'b';
- else if ([file_type isEqualToString:NSFileTypeRegular])
- c = '-';
- else if ([file_type isEqualToString:NSFileTypeSymbolicLink])
- c = 'l';
- else if ([file_type isEqualToString:NSFileTypeSocket])
- c = 's';
- else
- c = '?';
- [s appendFormat:@"%c", c];
- [s appendFormat:@"%c", (mode & 0400) ? 'r' : '-'];
- [s appendFormat:@"%c", (mode & 0200) ? 'w' : '-'];
- [s appendFormat:@"%c", (mode & S_ISUID) ? 's' : (mode & 0100) ? 'x' : '-'];
- [s appendFormat:@"%c", (mode & 0040) ? 'r' : '-'];
- [s appendFormat:@"%c", (mode & 0020) ? 'w' : '-'];
- [s appendFormat:@"%c", (mode & S_ISGID) ? 's' : (mode & 0010) ? 'x' : '-'];
- [s appendFormat:@"%c", (mode & 0004) ? 'r' : '-'];
- [s appendFormat:@"%c", (mode & 0002) ? 'w' : '-'];
- [s appendFormat:@"%c", (mode & S_ISVTX) ? 't' : (mode & 0001) ? 'x' : '-'];
-
- return s;
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_icon
- //-----------------------------------------------------------------------------
- static void fmt_icon( MiscTableScroll* ts, NSDictionary* dict, id cell )
- {
- float h,w,s;
- NSImage* i = [dict scaledImage];
-
- w = [ts columnSize:ICON_SLOT]; if (w == 0) w = 18;
- h = [ts uniformSizeRows]; if (h == 0) h = 18;
- s = (w < h ? w : h) - 1.0;
-
- [i setSize:NSMakeSize( s, s )];
- [cell setImage:i];
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_lock
- //-----------------------------------------------------------------------------
- static void fmt_lock( MiscTableScroll* ts, NSDictionary* dict, id cell )
- {
- [cell setState:![[dict objectForKey:DA_IS_LOCKED] boolValue]];
- [cell setEnabled:[[dict objectForKey:DA_CAN_TOGGLE_LOCK] boolValue]];
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_name
- //-----------------------------------------------------------------------------
- static void fmt_name( MiscTableScroll* ts, NSDictionary* dict, id cell )
- {
- [cell setStringValue:[dict objectForKey:DA_SHORT_NAME]];
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_size
- //-----------------------------------------------------------------------------
- static void fmt_size( MiscTableScroll* ts, NSDictionary* dict, id cell )
- {
- [cell setIntValue:[dict fileSize]];
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_modified
- //-----------------------------------------------------------------------------
- static void fmt_modified( MiscTableScroll* ts, NSDictionary* dict, id cell )
- {
- [cell setStringValue:str_date( [dict fileModificationDate] )];
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_perms
- //-----------------------------------------------------------------------------
- static void fmt_perms( MiscTableScroll* ts, NSDictionary* dict, id cell )
- {
- [cell setStringValue:
- str_perms( [dict filePosixPermissions], [dict fileType])];
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_owner
- //-----------------------------------------------------------------------------
- static void fmt_owner( MiscTableScroll* ts, NSDictionary* dict, id cell )
- {
- NSString* s = [dict fileOwnerAccountName];
- [cell setStringValue:(s != 0 ? s : @"")];
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_group
- //-----------------------------------------------------------------------------
- static void fmt_group( MiscTableScroll* ts, NSDictionary* dict, id cell )
- {
- NSString* s = [dict fileGroupOwnerAccountName];
- [cell setStringValue:(s != 0 ? s : @"")];
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_hardlinks
- //-----------------------------------------------------------------------------
- static void fmt_hardlinks( MiscTableScroll* ts, NSDictionary* dict, id cell )
- {
- [cell setIntValue:
- [[dict objectForKey:NSFileReferenceCount] unsignedLongValue]];
- }
-
-
- //-----------------------------------------------------------------------------
- // fmt_softlink
- //-----------------------------------------------------------------------------
- static void fmt_softlink( MiscTableScroll* ts, NSDictionary* dict, id cell )
- {
- [cell setStringValue:[dict objectForKey:DA_SOFT_LINK]];
- }
-
-
- //-----------------------------------------------------------------------------
- // FORMAT_FUNC
- //-----------------------------------------------------------------------------
-
- typedef void (*FormatFunc)( MiscTableScroll*, NSDictionary*, id );
-
- static FormatFunc FORMAT_FUNC[ MAX_SLOT ] =
- {
- fmt_icon, // ICON_SLOT,
- fmt_name, // NAME_SLOT,
- fmt_lock, // LOCK_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,
- };
-
-
- //-----------------------------------------------------------------------------
- // format_cell
- //-----------------------------------------------------------------------------
- static inline void format_cell(
- MiscTableScroll* ts,
- NSDictionary* dict,
- id cell,
- unsigned int col )
- {
- FORMAT_FUNC[ col ]( ts, dict, cell );
- }
-
-
- //=============================================================================
- // IMPLEMENTATION
- //=============================================================================
- @implementation DirWindow
-
- //-----------------------------------------------------------------------------
- // + initCascader
- //-----------------------------------------------------------------------------
- + (void)initCascader
- {
- NSSize const s = [[NSScreen mainScreen] frame].size;
- CASCADE_ORIGIN_X = s.width / 4;
- CASCADE_ORIGIN_Y = s.height - 60;
- CASCADE_DELTA_X = 20;
- CASCADE_DELTA_Y = 20;
- }
-
-
- //-----------------------------------------------------------------------------
- // + initialize
- //-----------------------------------------------------------------------------
- + (void)initialize
- {
- if (self == [DirWindow class])
- {
- [self initCascader];
- OPEN_DIRS = [[NSMutableArray alloc] init];
- LOCKED_IMAGE = [[NSImage imageNamed:LOCKED_IMAGE_S] retain];
- UNLOCKED_IMAGE = [[NSImage imageNamed:UNLOCKED_IMAGE_S] retain];
- DEFAULT_COLOR = [[Defaults getColor:COLOR_DEF
- fallback:[NSColor controlColor]] retain];
- DEFAULT_AUTO_SORT = [Defaults getBool:SORT_DEF fallback:NO];
- DEFAULT_SHOW_HIDDEN = [Defaults getBool:HIDDEN_DEF fallback:NO];
- DEFAULT_ROW_NUMBERS = [Defaults getBool:ROW_NUMBERS_DEF fallback:NO];
- DEFAULT_HIGHLIGHT_DIRS = [Defaults getBool:HLIGHT_DEF fallback:NO];
- DEFAULT_DRAG_UNSCALED = [Defaults getBool:UNSCALED_DEF fallback:YES];
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // - cascade
- //-----------------------------------------------------------------------------
- - (void)cascade
- {
- float top,left;
- left = CASCADE_ORIGIN_X + (CASCADE_DELTA_X * CASCADE_COUNTER);
- top = CASCADE_ORIGIN_Y - (CASCADE_DELTA_Y * CASCADE_COUNTER);
- [window setFrameTopLeftPoint:NSMakePoint( left, top )];
- if (++CASCADE_COUNTER >= CASCADE_MAX)
- CASCADE_COUNTER = 0;
- }
-
-
- //-----------------------------------------------------------------------------
- // - isDir:
- //-----------------------------------------------------------------------------
- - (BOOL)isDir:(int)r
- {
- return [[[dirArray objectAtIndex:r]
- objectForKey:DA_IS_DIRECTORY] boolValue];
- }
-
-
- //-----------------------------------------------------------------------------
- // - updateButtons
- //-----------------------------------------------------------------------------
- - (void)updateButtons
- {
- BOOL const enable = [scroll numberOfSelectedRows] == 1 &&
- [self isDir:[scroll selectedRow]];
- if (enable != [cdButton isEnabled])
- [cdButton setEnabled:enable];
- }
-
-
- //-----------------------------------------------------------------------------
- // - scrollColor
- //-----------------------------------------------------------------------------
- - (NSColor*)scrollColor
- {
- if ([DEFAULT_COLOR isEqual:[NSColor controlColor]])
- return [MiscTableScroll defaultBackgroundColor];
- else
- return DEFAULT_COLOR;
- }
-
-
- //-----------------------------------------------------------------------------
- // - tableScroll:cellAtRow:column:
- //-----------------------------------------------------------------------------
- - (id)tableScroll:(MiscTableScroll*)ts cellAtRow:(int)row column:(int)col
- {
- id cell = [lazyRow objectAtIndex:col];
- NSDictionary* dict = [dirArray objectAtIndex:row];
- format_cell( ts, dict, cell, col );
- if ([cell respondsToSelector:@selector(setBackgroundColor:)])
- {
- if (highlightDirs && [self isDir:row])
- [cell setBackgroundColor:[NSColor cyanColor]];
- else
- [cell setBackgroundColor:[ts backgroundColor]];
- }
- return cell;
- }
-
-
- //-----------------------------------------------------------------------------
- // - tableScroll:stringValueAtRow:column:
- //-----------------------------------------------------------------------------
- - (NSString*)tableScroll:(MiscTableScroll*)ts
- stringValueAtRow:(int)r column:(int)c
- {
- NSString* rc = 0;
- if (r < [dirArray count])
- {
- NSDictionary* dict = [dirArray objectAtIndex:r];
- switch (c)
- {
- case SIZE_SLOT:
- rc = [[dict objectForKey:NSFileSize] stringValue];
- break;
- case MODIFIED_SLOT:
- rc = str_date( [dict fileModificationDate] );
- break;
- case PERMS_SLOT:
- rc = str_perms( [dict filePosixPermissions], [dict fileType] );
- break;
- case OWNER_SLOT:
- rc = [dict fileOwnerAccountName];
- break;
- case GROUP_SLOT:
- rc = [dict fileGroupOwnerAccountName];
- break;
- case HARDLINKS_SLOT:
- rc = [[dict objectForKey:NSFileReferenceCount] stringValue];
- break;
- case NAME_SLOT:
- rc = [dict objectForKey:DA_SHORT_NAME];
- break;
- case SOFTLINK_SLOT:
- rc = [dict objectForKey:DA_SOFT_LINK];
- break;
- case ICON_SLOT:
- case LOCK_SLOT:
- default:
- rc = @"";
- break;
- }
- }
- return (rc != 0 ? rc : @""); // Owner or group may have returned nil.
- }
-
-
- //-----------------------------------------------------------------------------
- // -intValueAtRow:column:
- //-----------------------------------------------------------------------------
- - (int)intValueAtRow:(int)r column:(int)c
- {
- int rc = 0;
- if (r < [dirArray count])
- {
- NSDictionary* dict = [dirArray objectAtIndex:r];
- switch (c)
- {
- case LOCK_SLOT:
- rc = [[dict objectForKey:DA_IS_LOCKED] intValue];
- break;
- case SIZE_SLOT:
- rc = [dict fileSize];
- break;
- case MODIFIED_SLOT:
- rc = [[dict fileModificationDate]
- timeIntervalSinceReferenceDate];
- break;
- case PERMS_SLOT:
- rc = [dict filePosixPermissions];
- break;
- case HARDLINKS_SLOT:
- rc = [[dict objectForKey:NSFileReferenceCount] intValue];
- break;
- case OWNER_SLOT:
- case GROUP_SLOT:
- case ICON_SLOT:
- case NAME_SLOT:
- case SOFTLINK_SLOT:
- default:
- break;
- }
- }
- return rc;
- }
-
-
- //-----------------------------------------------------------------------------
- // - tableScroll:intValueAtRow:column:
- //-----------------------------------------------------------------------------
- - (int)tableScroll:(MiscTableScroll*)ts intValueAtRow:(int)r column:(int)c
- {
- return [self intValueAtRow:r column:c];
- }
-
-
- //-----------------------------------------------------------------------------
- // - tableScroll:tagAtRow:column:
- //-----------------------------------------------------------------------------
- - (int)tableScroll:(MiscTableScroll*)ts tagAtRow:(int)r column:(int)c
- {
- return [self intValueAtRow:r column:c];
- }
-
-
- //-----------------------------------------------------------------------------
- // - tableScroll:stateAtRow:column:
- //-----------------------------------------------------------------------------
- - (int)tableScroll:(MiscTableScroll*)ts stateAtRow:(int)r column:(int)c
- {
- return [self intValueAtRow:r column:c];
- }
-
-
- //-----------------------------------------------------------------------------
- // - tableScroll:fontChangedFrom:to:
- //-----------------------------------------------------------------------------
- - (void)tableScroll:(MiscTableScroll*)ts
- fontChangedFrom:(NSFont*)oldFont
- to:(NSFont*)newFont
- {
- int col;
- for (col = 0; col < MAX_SLOT; col++)
- [[lazyRow objectAtIndex:col] setFont:newFont];
-
- [DEFAULT_FONT autorelease];
- DEFAULT_FONT = [newFont retain];
- [Defaults set:FONT_DEF font:DEFAULT_FONT];
- }
-
-
- //-----------------------------------------------------------------------------
- // - tableScroll:border:slotResized:
- //-----------------------------------------------------------------------------
- - (void)tableScroll:(MiscTableScroll*)ts
- border:(MiscBorderType)b
- slotResized:(int)n
- {
- [Defaults set:COL_SIZES_DEF str:[ts columnSizesAsString]];
- }
-
-
- //-----------------------------------------------------------------------------
- // saveSlotOrder:border:
- //-----------------------------------------------------------------------------
- - (void)saveSlotOrder:(MiscTableScroll*)ts
- border:(MiscBorderType)b
- {
- if (b == MISC_COL_BORDER)
- [Defaults set:COL_ORDER_DEF str:[ts columnOrderAsString]];
- }
-
-
- //-----------------------------------------------------------------------------
- // - tableScroll:border:slotDraggedFrom:to:
- //-----------------------------------------------------------------------------
- - (void)tableScroll:(MiscTableScroll*)ts
- border:(MiscBorderType)b
- slotDraggedFrom:(int)fromPos
- to:(int)toPos
- {
- [self saveSlotOrder:ts border:b];
- }
-
-
- //-----------------------------------------------------------------------------
- // - tableScroll:border:slotSortReversed:
- //-----------------------------------------------------------------------------
- - (void)tableScroll:(MiscTableScroll*)ts
- border:(MiscBorderType)b
- slotSortReversed:(int)n
- {
- [self saveSlotOrder:ts border:b];
- }
-
-
- //-----------------------------------------------------------------------------
- // - tableScroll:canEdit:atRow:column:
- //-----------------------------------------------------------------------------
- - (BOOL)tableScroll:(MiscTableScroll*)ts
- canEdit:(NSEvent*)ev
- atRow:(int)row column:(int)col
- {
- return ((ev == 0 || [ev clickCount] == 2) && col == NAME_SLOT &&
- ![[[dirArray objectAtIndex:row] objectForKey:DA_IS_LOCKED] boolValue]);
- }
-
-
- //-----------------------------------------------------------------------------
- // - tableScroll:setStringValue:atRow:column:
- //-----------------------------------------------------------------------------
- - (BOOL)tableScroll:(MiscTableScroll*)ts
- setStringValue:(NSString*)s
- atRow:(int)row column:(int)col
- {
- NSMutableDictionary* dict = [dirArray objectAtIndex:row];
- [dict setObject:s forKey:DA_SHORT_NAME];
- [dict setObject:[path stringByAppendingPathComponent:s]
- forKey:DA_LONG_NAME];
- return YES;
- }
-
-
- //-----------------------------------------------------------------------------
- // -tableScroll:draggingSourceOperationMaskForLocal:
- //-----------------------------------------------------------------------------
- - (unsigned int)tableScroll:(MiscTableScroll*)s
- draggingSourceOperationMaskForLocal:(BOOL)isLocal
- {
- return NSDragOperationAll;
- }
-
-
- //-----------------------------------------------------------------------------
- // tableScrollIgnoreModifierKeysWhileDragging:
- //-----------------------------------------------------------------------------
- - (BOOL)tableScrollIgnoreModifierKeysWhileDragging:(MiscTableScroll*)s
- {
- return NO;
- }
-
-
- //-----------------------------------------------------------------------------
- // - tableScroll:preparePasteboard:forDragOperationAtRow:column:
- //-----------------------------------------------------------------------------
- - (void)tableScroll:(MiscTableScroll*)s
- preparePasteboard:(NSPasteboard*)pb
- forDragOperationAtRow:(int)r column:(int)c
- {
- NSString* file = [[dirArray objectAtIndex:r] objectForKey:DA_LONG_NAME];
- [pb declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:0];
- [pb setPropertyList:[NSArray arrayWithObject:file]
- forType:NSFilenamesPboardType];
- }
-
-
- //-----------------------------------------------------------------------------
- // - tableScroll:allowDragOperationAtRow:column:
- //-----------------------------------------------------------------------------
- - (BOOL)tableScroll:(MiscTableScroll*)s
- allowDragOperationAtRow:(int)r column:(int)c
- {
- return (c == ICON_SLOT);
- }
-
-
- //-----------------------------------------------------------------------------
- // - tableScroll:imageForDragOperationAtRow:column:
- //-----------------------------------------------------------------------------
- - (NSImage*)tableScroll:(MiscTableScroll*)s
- imageForDragOperationAtRow:(int)r column:(int)c
- {
- NSDictionary* dict = [dirArray objectAtIndex:r];
- return (dragUnscaled ? [dict unscaledImage] : [dict scaledImage]);
- }
-
-
- //-----------------------------------------------------------------------------
- // - fillScroll
- //-----------------------------------------------------------------------------
- - (void)fillScroll
- {
- [scroll renewRows:[dirArray count]];
- if ([scroll autoSortRows])
- [scroll sortRows];
-
- [countField setStringValue:
- [NSString stringWithFormat:@"%d files %lu bytes",
- [dirArray count], [dirArray totalBytes]]];
-
- [self updateButtons];
- }
-
-
- //-----------------------------------------------------------------------------
- // - setPath:
- //-----------------------------------------------------------------------------
- - (void)setPath:(NSString*)dirname
- {
- [path autorelease];
- if (dirname == 0) dirname = NSHomeDirectory();
- if ([dirname length] == 0) dirname = @"/";
- path = [dirname retain];
- [window setTitleWithRepresentedFilename:path];
- }
-
-
- //-----------------------------------------------------------------------------
- // - loadDirectory:
- //-----------------------------------------------------------------------------
- - (void)loadDirectory:(NSString*)dirname
- {
- if (![dirArray loadPath:dirname showHidden:showHidden])
- NSRunAlertPanel( @"Can't Read", @"Cannot read directory, %@",
- @"OK", 0, 0, path );
- }
-
-
- //-----------------------------------------------------------------------------
- // - reload
- //-----------------------------------------------------------------------------
- - (void)reload
- {
- [scroll abortEditing];
- [self loadDirectory:path];
- [self fillScroll];
- }
-
-
- //-----------------------------------------------------------------------------
- // - load:
- //-----------------------------------------------------------------------------
- - (void)load:(NSString*)dirname
- {
- [self setPath:dirname];
- [self reload];
- }
-
-
- //-----------------------------------------------------------------------------
- // - save:
- //-----------------------------------------------------------------------------
- - (void)save:(id)sender
- {
- [[MiscExporter commonInstance] exportTableScroll:scroll];
- }
-
-
- //-----------------------------------------------------------------------------
- // - printDirectory:
- //-----------------------------------------------------------------------------
- - (void)printDirectory:(id)sender
- {
- [scroll print:self];
- }
-
-
- //-----------------------------------------------------------------------------
- // - open:
- //-----------------------------------------------------------------------------
- - (void)open:(id)sender
- {
- if ([scroll hasRowSelection])
- {
- int i;
- NSArray* list = [scroll selectedRows];
- for (i = [list count]; i-- > 0; )
- {
- int const r = [[list objectAtIndex:i] intValue];
- NSString* s = [[dirArray objectAtIndex:r]
- objectForKey:DA_LONG_NAME];
- if ([self isDir:r])
- [[self class] launchDir:s];
- else
- [[NSWorkspace sharedWorkspace] openFile:s];
- }
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // - destroy:
- //-----------------------------------------------------------------------------
- - (void)destroy:(id)sender
- {
- if ([dirArray writable] && [scroll hasRowSelection])
- {
- int i;
- NSArray* list = [scroll selectedRows];
- NSFileManager* manager = [NSFileManager defaultManager];
- for (i = [list count]; i-- > 0; )
- [manager removeFileAtPath:[[dirArray objectAtIndex:i]
- objectForKey:DA_LONG_NAME] handler:0];
- [self reload];
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // - fileManager:shouldProceedAfterError:
- //-----------------------------------------------------------------------------
- - (BOOL)fileManager:(NSFileManager*)manager
- shouldProceedAfterError:(NSDictionary*)errorInfo
- {
- NSRunAlertPanel( @"Error", @"Rename failed: %@.", @"OK", 0, 0,
- [errorInfo objectForKey:@"Error"]);
- return NO;
- }
-
-
- //-----------------------------------------------------------------------------
- // - rename:to:
- //-----------------------------------------------------------------------------
- - (BOOL)rename:(NSString*)oldName to:(NSString*)newName
- {
- return [[NSFileManager defaultManager]
- movePath:[path stringByAppendingPathComponent:oldName]
- toPath:[path stringByAppendingPathComponent:newName]
- handler:self];
- }
-
-
- //-----------------------------------------------------------------------------
- // - control:textShouldEndEditing:
- //-----------------------------------------------------------------------------
- - (BOOL)control:(NSControl*)control textShouldEndEditing:(NSText*)fieldEditor
- {
- BOOL accept = YES;
- NSString* oldName;
- NSString* newName;
-
- int const r = [scroll clickedRow];
- int const c = [scroll clickedColumn];
- NSParameterAssert( c == NAME_SLOT );
-
- oldName = [[dirArray objectAtIndex:r] objectForKey:DA_SHORT_NAME];
- newName = [fieldEditor string];
-
- if (![newName isEqualToString:oldName])
- accept = [self rename:oldName to:newName];
-
- if (!accept)
- [fieldEditor setString:oldName];
-
- return accept;
- }
-
-
- //-----------------------------------------------------------------------------
- // - refreshPressed:
- //-----------------------------------------------------------------------------
- - (void)refreshPressed:(id)sender
- {
- [self reload];
- }
-
-
- //-----------------------------------------------------------------------------
- // - cdPressed:
- //-----------------------------------------------------------------------------
- - (void)cdPressed:(id)sender
- {
- [scroll abortEditing];
- if ([scroll numberOfSelectedRows] == 1)
- {
- MiscCoord_P const row = [scroll selectedRow];
- if ([self isDir:row])
- [self load:normalize_path( [path stringByAppendingPathComponent:
- [[dirArray objectAtIndex:row] objectForKey:DA_SHORT_NAME]] )];
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // - rowNumbersClick:
- //-----------------------------------------------------------------------------
- - (void)rowNumbersClick:(id)sender
- {
- BOOL const newVal = ([rowNumbersSwitch state] != 0);
- BOOL const oldVal = [scroll rowTitlesOn];
- if (newVal != oldVal)
- {
- DEFAULT_ROW_NUMBERS = newVal;
- [scroll setRowTitlesOn:DEFAULT_ROW_NUMBERS];
- [Defaults set:ROW_NUMBERS_DEF bool:DEFAULT_ROW_NUMBERS];
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // - autoSortClick:
- //-----------------------------------------------------------------------------
- - (void)autoSortClick:(id)sender
- {
- BOOL const switchState = [autoSortSwitch state];
- [scroll abortEditing];
- if (autoSort != switchState)
- {
- DEFAULT_AUTO_SORT = autoSort = switchState;
- [Defaults set:SORT_DEF bool:DEFAULT_AUTO_SORT];
- [scroll setAutoSortRows:switchState];
- if (switchState)
- [scroll sortRows];
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // - hiddenFilesClick:
- //-----------------------------------------------------------------------------
- - (void)hiddenFilesClick:(id)sender
- {
- BOOL const switchState = [hiddenFilesSwitch state];
- [scroll abortEditing];
- if (showHidden != switchState)
- {
- DEFAULT_SHOW_HIDDEN = showHidden = switchState;
- [Defaults set:HIDDEN_DEF bool:DEFAULT_SHOW_HIDDEN];
- [self reload];
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // - highlightClick:
- //-----------------------------------------------------------------------------
- - (void)highlightClick:(id)sender
- {
- BOOL const switchState = [highlightSwitch state];
- [scroll abortEditing];
- if (highlightDirs != switchState)
- {
- DEFAULT_HIGHLIGHT_DIRS = highlightDirs = switchState;
- [Defaults set:HLIGHT_DEF bool:DEFAULT_HIGHLIGHT_DIRS];
- [scroll setNeedsDisplay:YES];
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // - dragUnscaledClick:
- //-----------------------------------------------------------------------------
- - (void)dragUnscaledClick:(id)sender
- {
- BOOL const switchState = [dragUnscaledSwitch state];
- if (dragUnscaled != switchState)
- {
- DEFAULT_DRAG_UNSCALED = dragUnscaled = switchState;
- [Defaults set:UNSCALED_DEF bool:DEFAULT_DRAG_UNSCALED];
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // - lockClick:
- //-----------------------------------------------------------------------------
- - (void)lockClick:(id)sender
- {
- int const row = [sender clickedRow];
- NSMutableDictionary* dict = [dirArray objectAtIndex:row];
- if ([[dict objectForKey:DA_CAN_TOGGLE_LOCK] boolValue])
- {
- BOOL const wasLocked = [[dict objectForKey:DA_IS_LOCKED] boolValue];
- [dict setObject:[NSNumber numberWithBool:!wasLocked]
- forKey:DA_IS_LOCKED];
- if ([sender autoSortRows])
- [sender sortRow:row];
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // - didClick:
- //-----------------------------------------------------------------------------
- - (void)didClick:(id)sender
- {
- [self updateButtons];
- }
-
-
- //-----------------------------------------------------------------------------
- // - didDoubleClick:
- //-----------------------------------------------------------------------------
- - (void)didDoubleClick:(id)sender
- {
- [self open:sender];
- }
-
-
- //-----------------------------------------------------------------------------
- // - makeKeyAndOrderFront:
- //-----------------------------------------------------------------------------
- - (void)makeKeyAndOrderFront:(id)sender
- {
- [window makeKeyAndOrderFront:sender];
- }
-
-
- //-----------------------------------------------------------------------------
- // - windowShouldClose:
- //-----------------------------------------------------------------------------
- - (BOOL)windowShouldClose:(id)sender
- {
- [scroll abortEditing];
- [OPEN_DIRS removeObject:self];
- [self autorelease];
- return YES;
- }
-
-
- //-----------------------------------------------------------------------------
- // - windowDidResize:
- //-----------------------------------------------------------------------------
- - (void)windowDidResize:(NSNotification*)notification
- {
- NSRect r = [[notification object] frame];
- if (NSWidth (r) != DEFAULT_WIN_SIZE.width ||
- NSHeight(r) != DEFAULT_WIN_SIZE.height)
- {
- DEFAULT_WIN_SIZE = r.size;
- [Defaults set:SIZE_DEF size:DEFAULT_WIN_SIZE];
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // - setDefaultColor:
- //-----------------------------------------------------------------------------
- - (void)setDefaultColor:(NSColor*)c
- {
- [DEFAULT_COLOR autorelease];
- DEFAULT_COLOR = [c retain];
- [Defaults set:COLOR_DEF color:c];
- }
-
-
- //-----------------------------------------------------------------------------
- // - setColors:
- //-----------------------------------------------------------------------------
- - (void)setColors:(NSColor*)c
- {
- [window setBackgroundColor:c];
- [scroll setBackgroundColor:[self scrollColor]];
- [window display];
- }
-
-
- //-----------------------------------------------------------------------------
- // - draggingEntered:
- //-----------------------------------------------------------------------------
- - (unsigned int)draggingEntered:(id<NSDraggingInfo>)sender
- {
- return ([sender draggingSourceOperationMask] & NSDragOperationGeneric);
- }
-
-
- //-----------------------------------------------------------------------------
- // - performDragOperation:
- //-----------------------------------------------------------------------------
- - (BOOL)performDragOperation:(id<NSDraggingInfo>)sender
- {
- [self setDefaultColor:
- [NSColor colorFromPasteboard:[sender draggingPasteboard]]];
- [self setColors:DEFAULT_COLOR];
- return YES;
- }
-
-
- //-----------------------------------------------------------------------------
- // - initLazyRow
- // NOTE *1*: NeXT docs say immutable arrays are accessed more efficiently.
- //-----------------------------------------------------------------------------
- - (NSArray*)initLazyRow
- {
- NSMutableArray* array = [NSMutableArray array];
- NSFont* font = [scroll font];
- NSZone* const z = [self zone];
- int i;
- for (i = 0; i < MAX_SLOT; i++)
- {
- id c = [[[scroll columnCellPrototype:i] copyWithZone:z] autorelease];
- if ([c respondsToSelector:@selector(setOwner:)])
- [c setOwner:scroll];
- else if ([c respondsToSelector:@selector(setFont:)])
- [c setFont:font];
- [array addObject:c];
- }
- return [[array copy] autorelease]; // NOTE *1*
- }
-
-
- //-----------------------------------------------------------------------------
- // - initDefaults
- //-----------------------------------------------------------------------------
- - (void)initDefaults
- {
- static BOOL initialized = NO;
- if (!initialized)
- {
- NSRect r = [window frame];
- DEFAULT_WIN_SIZE = r.size;
- DEFAULT_FONT =
- [[Defaults getFont:FONT_DEF fallback:[scroll font]] retain];
- initialized = YES;
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // - loadDefaults
- //-----------------------------------------------------------------------------
- - (void)loadDefaults
- {
- NSString* s;
-
- NSRect r = [window frame];
- r.size = [Defaults getSize:SIZE_DEF fallback:DEFAULT_WIN_SIZE];
- [window setFrame:r display:NO];
-
- autoSort = DEFAULT_AUTO_SORT;
- showHidden = DEFAULT_SHOW_HIDDEN;
- highlightDirs = DEFAULT_HIGHLIGHT_DIRS;
- dragUnscaled = DEFAULT_DRAG_UNSCALED;
-
- [autoSortSwitch setState:autoSort];
- [hiddenFilesSwitch setState:showHidden];
- [highlightSwitch setState:highlightDirs];
- [dragUnscaledSwitch setState:dragUnscaled];
- [rowNumbersSwitch setState:DEFAULT_ROW_NUMBERS];
-
- [scroll setRowTitlesOn:DEFAULT_ROW_NUMBERS];
- [scroll setAutoSortRows:autoSort];
- [scroll setFont:DEFAULT_FONT];
- [self setColors:DEFAULT_COLOR];
-
- s = [Defaults getStr:COL_SIZES_DEF fallback:0];
- if (s)
- [scroll setColumnSizesFromString:s];
-
- s = [Defaults getStr:COL_ORDER_DEF fallback:0];
- if (s)
- [scroll setColumnOrderFromString:s];
- }
-
-
- //-----------------------------------------------------------------------------
- // - initLockSlot
- //-----------------------------------------------------------------------------
- - (void)initLockSlot
- {
- id proto = [scroll columnCellPrototype:LOCK_SLOT];
- [proto setButtonType:NSSwitchButton];
- [proto setImagePosition:NSImageOnly];
- [proto setTarget:self];
- [proto setAction:@selector(lockClick:)];
- [proto setImage:LOCKED_IMAGE];
- [proto setAlternateImage:UNLOCKED_IMAGE];
- }
-
-
- //-----------------------------------------------------------------------------
- // - initNameSlot
- //-----------------------------------------------------------------------------
- - (void)initNameSlot
- {
- id proto = [scroll columnCellPrototype:NAME_SLOT];
- [proto setEditable:YES];
- [proto setScrollable:YES];
- }
-
-
- //-----------------------------------------------------------------------------
- // - initSlots
- //-----------------------------------------------------------------------------
- - (void)initSlots
- {
- [self initLockSlot];
- [self initNameSlot];
- [[scroll columnCellPrototype:SIZE_SLOT] setAlignment:NSRightTextAlignment];
- [[scroll columnCellPrototype:HARDLINKS_SLOT]
- setAlignment:NSRightTextAlignment];
- }
-
-
- //-----------------------------------------------------------------------------
- // - initWithDir:
- //-----------------------------------------------------------------------------
- - (id)initWithDir:(NSString*)dirname
- {
- [super init];
- path = [[NSString alloc] init];
- [NSBundle loadNibNamed:@"DirWindow" owner:self];
- [window registerForDraggedTypes:
- [NSArray arrayWithObject:NSColorPboardType]];
- dirArray = [[DirArray allocWithZone:[self zone]] init];
- [self initSlots];
- [self initDefaults];
- [self loadDefaults];
- lazyRow = [[self initLazyRow] retain];
- [self load:dirname];
- [OPEN_DIRS addObject:self];
- [self cascade];
- [window makeKeyAndOrderFront:self];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - init
- //-----------------------------------------------------------------------------
- - (id)init
- {
- return [self initWithDir:NSHomeDirectory()];
- }
-
-
- //-----------------------------------------------------------------------------
- // - dealloc
- //-----------------------------------------------------------------------------
- - (void)dealloc
- {
- NSZone* const z = [self zone];
- [window setDelegate:0];
- [window close];
- [window release];
- [path release];
- [dirArray release];
- [lazyRow release];
- [super dealloc];
- RETIRE_ZONE(z);
- }
-
-
- //-----------------------------------------------------------------------------
- // - path
- //-----------------------------------------------------------------------------
- - (NSString*)path
- {
- return path;
- }
-
-
- //-----------------------------------------------------------------------------
- // + findDir:
- //-----------------------------------------------------------------------------
- + (DirWindow*)findDir:(NSString*)normalizedPath
- {
- if (normalizedPath != 0)
- {
- unsigned int i;
- unsigned int const lim = [OPEN_DIRS count];
- for (i = 0; i < lim; i++)
- {
- DirWindow* p = (DirWindow*)[OPEN_DIRS objectAtIndex:i];
- NSString* s = [p path];
- if (s != 0 && [s isEqualToString:normalizedPath])
- return p;
- }
- }
- return 0;
- }
-
-
- //-----------------------------------------------------------------------------
- // + launchDir:
- //-----------------------------------------------------------------------------
- + (void)launchDir:(NSString*)dirname
- {
- DirWindow* p = 0;
- if (dirname == 0) dirname = NSHomeDirectory();
- if (dirname == 0) dirname = @"/";
- dirname = normalize_path( dirname );
- if ((p = [self findDir:dirname]) != 0)
- [p makeKeyAndOrderFront:self];
- else
- p = [[self allocWithZone:EMPLOY_ZONE()] initWithDir:dirname];
- }
-
- @end
-