Created
March 24, 2011 03:07
-
-
Save BlackFrog1/884478 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// LoginItem.h | |
// Medium | |
// | |
// Created by Collin Bennett on 1/13/11. | |
// Copyright 2011 Black Frog. All rights reserved. | |
// | |
#import <Cocoa/Cocoa.h> | |
@interface LoginItem : NSObject <NSCoding> { | |
@private | |
NSURL *url_; | |
// ivars based on url | |
BOOL isFile_; | |
NSString *name_; | |
NSString *kind_; | |
// keep track if the changes need to be saved | |
BOOL dirty_; | |
// user control ivars | |
BOOL hide_; | |
BOOL notify_; | |
NSUInteger seconds_; | |
} | |
@property (nonatomic, readonly, retain) NSString *name; | |
@property (nonatomic, readonly, retain) NSString *kind; | |
@property (readonly, getter=isDirty) BOOL dirty; | |
@property (nonatomic, assign) BOOL hide; | |
@property (nonatomic, assign) BOOL notifyLaunch; | |
@property (nonatomic, assign) NSUInteger launchSeconds; | |
- (id)initWithPath:(NSString *)path; | |
- (id)copyWithZone:(NSZone *)zone; | |
- (NSImage *)image; | |
- (NSString *)toolTip; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// LoginItem.m | |
// Medium | |
// | |
// Created by Collin Bennett on 1/13/11. | |
// Copyright 2011 Black Frog. All rights reserved. | |
// | |
#import "LoginItem.h" | |
// for debugging | |
//#define LOG_URL | |
//#define DEBUG | |
@interface LoginItem () | |
// This second declaration of the dirty property | |
// automatically creates the KVO notification | |
// when setDirty is called | |
@property (readwrite, getter=isDirty) BOOL dirty; | |
- (NSImage *)createIconImage:(OSType)code; | |
- (void)debugURL; | |
@end | |
@implementation LoginItem | |
@synthesize name = name_; | |
@synthesize kind = kind_; | |
@synthesize dirty = dirty_; | |
@synthesize hide = hide_; | |
@synthesize notifyLaunch = notify_; | |
@synthesize launchSeconds = seconds_; | |
- (NSImage *)createIconImage:(OSType)code { | |
// TODO: Research on internet the kGenericWORMIcon, | |
// because on my computer the worm icon is blank, just wondering if that is correct | |
NSImage *img = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(code)]; | |
//[img setSize:NSMakeSize(ICON_SIZE, ICON_SIZE)]; | |
return img; | |
// kGenericURLIcon | |
// kInternetLocationGenericIcon | |
// This sample code use the TIFFRepresentation | |
// I should look into using it also | |
// NSWorkspace *wksp = [NSWorkspace sharedWorkspace]; | |
// timeMachineIconData = [[[wksp iconForFile:[wksp absolutePathForAppBundleWithIdentifier:@"com.apple.backup.launcher"]] TIFFRepresentation] retain]; | |
} | |
- (void)debugURL { | |
#ifdef LOG_URL | |
NSLog(@"Scheme: %@", [url_ scheme]); | |
NSLog(@"URL Absolute: %@", [url_ absoluteString]); | |
NSLog(@"File Path URL: %@", [[url_ filePathURL] absoluteString]); | |
NSLog(@"File Reference URL: %@", [[url_ fileReferenceURL] absoluteString]); | |
#endif | |
} | |
- (id)initWithPath:(NSString *)path { | |
if ((self = [super init]) != nil) { | |
// Check if our path starts with a tilde | |
if ([path hasPrefix:@"~"]) | |
path = [path stringByExpandingTildeInPath]; | |
// I could create all the NSURL with +URLWithString using a valid system path file | |
// but the when I try to retrieve the Kind String using LSCopyKindStringForURL | |
// I get the following error: [paramErr] (error in user parameter list) | |
if ([path hasPrefix:@"/"]) // indicate we have a system path | |
url_ = [NSURL fileURLWithPath:path]; | |
else // everything else must conform to RFC 2396 | |
url_ = [NSURL URLWithString:path]; | |
// Malformed path will result in a nil NSURL | |
if (url_ == nil) { | |
NSLog(@"Malformed Path: %@", path); | |
[self release]; | |
return nil; | |
} | |
// we are going to need the url object around for awhile | |
[url_ retain]; | |
// Check the scheme of the url | |
NSString *itemScheme = [url_ scheme]; | |
// perform a case insensitive match because the user | |
// could type in all caps, AARG | |
if (!([itemScheme caseInsensitiveCompare:@"file"] != NSOrderedSame)) | |
isFile_ = YES; | |
if (!isFile_) { | |
name_ = path; | |
// We have a non-file based url scheme | |
// get the application that can handle this scheme | |
// and set the kind string to the application display name | |
CFURLRef appURL = nil; | |
LSGetApplicationForURL((CFURLRef)url_, kLSRolesAll, NULL, | |
&appURL); | |
if (appURL != nil) { | |
// get display name for kind | |
CFStringRef displayName = nil; | |
LSCopyDisplayNameForURL(appURL, &displayName); | |
if (displayName != nil) | |
kind_ = (NSString *)displayName; | |
// TODO: Research kLSRequestIconAndKind for LSCopyItemInfoForURL | |
// According to the doc, it's not used. | |
// find what really means???? | |
CFRelease(appURL); | |
} | |
} else { | |
// Create a local file manager because this is consider thread-safe | |
NSFileManager *localFileManager = [[NSFileManager alloc] init]; | |
// url is file-based, use it's display name | |
name_ = [localFileManager displayNameAtPath:[url_ path]]; | |
if ([localFileManager fileExistsAtPath:[url_ path]]) { | |
// kind string | |
CFStringRef kindStr = nil; | |
OSStatus stat = LSCopyKindStringForURL((CFURLRef)url_, &kindStr); | |
if (kindStr != nil) { | |
kind_ = (NSString*)kindStr; | |
} else { | |
NSLog(@"Kind String Status: %d", stat); | |
// TODO: Why is Launch Services returning "File Manager Result Codes?" | |
// TODO: -43 [fnfErr] (File not found) | |
// The documents doesn't match the OSStatus | |
} | |
} | |
[localFileManager release]; | |
} | |
[name_ retain]; | |
// all newly created item are dirty | |
dirty_ = YES; | |
#ifdef DEBUG | |
NSLog(@"-------------------------------------------------------"); | |
NSLog(@"Path: %@", path); | |
[self debugURL]; | |
#endif | |
} | |
return self; | |
} | |
- (id)copyWithZone:(NSZone *)zone { | |
LoginItem *newObj = [[[self class] alloc] init]; | |
newObj->url_ = [url_ retain]; | |
newObj->name_ = [name_ retain]; | |
newObj->kind_ = [kind_ retain]; | |
newObj->isFile_ = isFile_; | |
newObj->hide_ = hide_; | |
newObj->notify_ = notify_; | |
newObj->seconds_ = seconds_; | |
newObj->dirty_ = dirty_; | |
return newObj; | |
} | |
- (void)dealloc { | |
#ifdef DEBUG | |
NSLog(@"+++++++++++++++++++++++++++++++++++++"); | |
NSLog(@"Dealloc: %@", name_); | |
[self debugURL]; | |
#endif | |
[name_ release]; | |
[kind_ release]; | |
[url_ release]; | |
[super dealloc]; | |
} | |
// Because I am using the image in two different places, different size | |
// I create them at the time of need. | |
- (NSImage *)image { | |
NSImage *img = nil; | |
if (isFile_) { | |
// check if the file exists and ask the workspace for the icon | |
NSFileManager *fm = [[NSFileManager alloc] init]; | |
if ([fm fileExistsAtPath:[url_ path]]) { | |
// get the icon for the file | |
img = [[NSWorkspace sharedWorkspace] iconForFile:[url_ path]]; | |
} else { | |
// Display a question mark for missing files | |
// That doesn't mean the file won't be unavailable at the time | |
// it's needed by the daemon application | |
img = [self createIconImage:kQuestionMarkIcon]; | |
} | |
[fm release]; | |
} else { | |
NSString *scheme = [url_ scheme]; | |
// assign an icon base on the scheme | |
if ([scheme caseInsensitiveCompare:@"http"] == NSOrderedSame) | |
img = [self createIconImage:kInternetLocationHTTPIcon]; | |
else if ([scheme caseInsensitiveCompare:@"ftp"] == NSOrderedSame) | |
img = [self createIconImage:kInternetLocationFTPIcon]; | |
else if ([scheme caseInsensitiveCompare:@"mailto"] == NSOrderedSame) | |
img = [self createIconImage:kInternetLocationMailIcon]; | |
else if ([scheme caseInsensitiveCompare:@"news"] == NSOrderedSame) | |
img = [self createIconImage:kInternetLocationNewsIcon]; | |
else | |
img = [self createIconImage:kInternetLocationGenericIcon]; | |
} | |
return img; | |
} | |
- (NSString *)toolTip { | |
NSString *tip = nil; | |
if (isFile_) { | |
// get file system path from NSURL | |
CFStringRef filePath = CFURLCopyFileSystemPath((CFURLRef)url_, kCFURLPOSIXPathStyle); | |
if (filePath != nil) { | |
// create a new autorelease NSString | |
tip =[NSString stringWithString:(NSString *)filePath]; | |
CFRelease(filePath); | |
} | |
} else | |
tip = [url_ absoluteString]; | |
return tip; | |
} | |
#pragma mark - | |
#pragma mark User control properties | |
- (void)setHide:(BOOL)aHide { | |
if (hide_ != aHide) { | |
hide_ = aHide; | |
[self setDirty:YES]; | |
} | |
} | |
- (void)setLaunchSeconds:(NSUInteger)seconds { | |
if (seconds_ != seconds) { | |
seconds_ = seconds; | |
[self setDirty:YES]; | |
} | |
} | |
- (void)setNotifyLaunch:(BOOL)notify { | |
if (notify_ != notify) { | |
notify_ = notify; | |
[self setDirty:YES]; | |
} | |
} | |
#pragma mark - | |
#pragma mark NSCoding Protocol | |
// Friday Q&A 2010-08-12: Implementing NSCoding | |
// http://www.mikeash.com/pyblog/friday-qa-2010-08-12-implementing-nscoding.html | |
// http://stackoverflow.com/questions/2944823/iphone-is-initwithcoder-an-exception-to-the-usual-designated-initializer-desig | |
// TODO: Refactor my initWithCoder methods | |
- (id)initWithCoder:(NSCoder *)coder { | |
// first thing we do is decode the path information | |
NSString *path = (NSString *)[coder decodeObjectForKey:@"Path"]; | |
if ((self = [self initWithPath:path])) { | |
// TODO: decode the additional properties | |
//self->name_ = @"Help"; | |
//[self->name_ retain]; | |
hide_ = [coder decodeBoolForKey:@"Hide"]; | |
notify_ = [coder decodeBoolForKey:@"Notify"]; | |
seconds_ = [coder decodeIntegerForKey:@"Seconds"]; | |
// because I just init from a coder | |
// we are not dirty | |
dirty_ = NO; | |
} | |
return self; | |
} | |
- (void)encodeWithCoder:(NSCoder *)coder { | |
#ifdef DEBUG | |
NSLog(@"==================================="); | |
NSLog(@"Encode: %@", name_); | |
[self debugURL]; | |
#endif | |
// If the url_ has a file reference, archive that | |
NSString *path = [[url_ fileReferenceURL] absoluteString]; | |
if (path == nil) // if no file reference, then use the URL absolute path | |
path = [url_ absoluteString]; | |
[coder encodeObject:path forKey:@"Path"]; | |
[coder encodeBool:hide_ forKey:@"Hide"]; | |
[coder encodeBool:notify_ forKey:@"Notify"]; | |
[coder encodeInteger:seconds_ forKey:@"Seconds"]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment