Source

Murky / Source / HgFile.m

//
//  HgFile.m
//  Murky
//
//  Copyright 2008-2009 Jens Alfke. All rights reserved.
//

#define HGFILE_PRIVATE
#import "HgFile.h"
#import "HgDir.h"
#import "HgRepository.h"
#import "HgRevision.h"


@implementation HgFile


- (id) initWithName: (NSString*)name directory: (HgDir*)parentDir
{
    self = [super init];
    if (self != nil) {
        _name = [name copy];
        _dir = parentDir;
        _status = kNotTracked;
    }
    return self;
}


- (NSString*) description
{
    return [NSString stringWithFormat: @"%@[%@]",[self class],_name];
}


@synthesize name=_name, directory=_dir, status=_status, mergeStatus=_mergeStatus;

- (BOOL) isFile         {return YES;}
- (BOOL) isDirectory    {return NO;}
- (BOOL) isRoot         {return _dir==nil;}

- (HgRevision*) revision        {return self.root.revision;}
- (HgRepository*) repository    {return self.root.revision.repository;}

- (HgDir*) root
{
    HgFile *f = self;
    while(YES) {
        HgDir *dir = f->_dir;
        if( ! dir )
            return (HgDir*)f;
        else
            f = dir;
    }
}

- (NSMutableString*) _getPath: (BOOL)absolute
{
    NSMutableString *path = [_dir _getPath: absolute];
    [path appendString: _name];
    return path;
}

- (NSString*) path
{
    return [self _getPath: NO];
}

- (NSString*) absolutePath
{
    return [self _getPath: YES];
}

- (NSURL*) URL
{
    return [NSURL fileURLWithPath: self.absolutePath];
}

- (NSIndexPath*) indexPath
{
    if( _dir ) {
        NSUInteger index = [_dir.files indexOfObjectIdenticalTo: self];
        return [_dir.indexPath indexPathByAddingIndex: index];
    } else
        return [[NSIndexPath alloc] initWithIndexes: NULL length: 0];
}

- (NSImage*) icon
{
    if( ! _icon ) {
        _icon = [[NSWorkspace sharedWorkspace] iconForFile: self.absolutePath];
    }
    return _icon;
}

- (NSDictionary*) fileAttributes
{
    return [[NSFileManager defaultManager] attributesOfItemAtPath: self.absolutePath error: nil];
}

- (CFAbsoluteTime) modTime
{
    return self.fileAttributes.fileModificationDate.timeIntervalSinceReferenceDate;
}


- (BOOL) isUncommitted
{
    return strchr("MAR!?", _status) != NULL;
}

+ (NSArray*) keyPathsForValuesAffectingIsUncommitted  {return [NSArray arrayWithObject: @"status"];}


- (NSComparisonResult) compare: (id)object
{
    return [_name caseInsensitiveCompare: [object name]];
}


- (void) addFilesMatching: (Predicate)predicate toArray: (NSMutableArray*)array
{
    if( CheckPredicate(predicate,self) )
        [array addObject: self];
}


- (void) remove
{
    [_dir _removeFile: self];
}



#pragma mark -
#pragma mark ACTIONS:

- (NSImage*) statusImage
{
    NSString *imageName;
    switch (_status) {
        case kModified:
            switch (_mergeStatus) {
                case kResolved:
                    imageName = @"status_resolved";
                    break;
                case kConflict:
                    imageName = @"status_conflict";
                    break;
                default:
                    imageName = @"status_modified";
                    break;
            }
            break;
        case kNeedsUpdate:
            imageName = @"status_needs_update";
            break;
        case kAdded:
            imageName = @"status_added";
            break;
        case kRemoved:
            imageName = @"status_removed";
            break;
        case kDeleted:
            imageName = @"status_deleted";
            break;
        case kIgnored:
            imageName = @"status_ignored";
            break;
        case kNotTracked:
            imageName = @"status_nottracked";
            break;
        default:
            imageName = @"status_null";
            break;
    }
    return [NSImage imageNamed:imageName];
}

+ (NSArray*) keyPathsForValuesAffectingStatusImage
{
    return $array(@"status", @"mergeStatus");
}


#pragma mark -
#pragma mark REVISIONS:


- (NSArray*) revisions
{
    NSError *error;
    return [self.repository revisionsOfFile: self error: &error];
}


@end