10.6 compatibility: Fix some new compiler warnings, and work around apparent regressions in NSTask and -stringByStandardizingPath.
5 // Created by Jens Alfke on 7/16/08.
6 // Copyright 2008 Jens Alfke. All rights reserved.
9 #import "MYAddressField.h"
10 #import "RegexKitLite.h"
11 #import <AddressBook/AddressBook.h>
14 @interface MYAddressField ()
15 @property (retain) MYAddressItem *selectedAddress;
19 @implementation MYAddressField
22 @synthesize defaultAddresses=_defaultAddresses, addressProperty=_property, selectedAddress=_selectedAddress;
25 - (void) _computeAddresses
27 NSMutableArray *newAddresses = $marray();
29 if( _prefix.length ) {
30 // Find all the people in the address book matching _prefix:
31 ABAddressBook *ab = [ABAddressBook sharedAddressBook];
32 ABSearchElement *search = [ABPerson searchElementForProperty: _property
36 comparison: kABNotEqual];
37 for( ABPerson *person in [ab recordsMatchingSearchElement: search] ) {
38 ABMultiValue *values = [person valueForProperty: _property];
39 NSString *first = [person valueForProperty: kABFirstNameProperty];
40 NSString *last = [person valueForProperty: kABLastNameProperty];
41 BOOL nameMatches = _prefix==nil || ([first.lowercaseString hasPrefix: _prefix]
42 || [last.lowercaseString hasPrefix: _prefix]);
43 for( int i=0; i<values.count; i++ ) {
44 NSString *address = [values valueAtIndex: i];
45 if( nameMatches || [address.lowercaseString hasPrefix: _prefix] ) {
46 MYAddressItem *item = [[MYAddressItem alloc] initWithPerson: person
47 addressType: _property
49 [newAddresses addObject: item];
54 } else if( _defaultAddresses ) {
55 [newAddresses addObjectsFromArray: _defaultAddresses];
59 [newAddresses sortUsingSelector: @selector(compare:)];
61 if( ifSetObj(&_addresses,newAddresses) )
65 - (NSArray*) addresses
68 [self _computeAddresses];
76 _addresses = [[NSMutableArray alloc] init];
77 _property = [kABEmailProperty retain];
79 self.usesDataSource = YES;
80 self.dataSource = self;
89 [_selectedAddress release];
96 id ax = NSAccessibilityUnignoredDescendant(self);
97 return [[ax accessibilityAttributeValue: NSAccessibilityExpandedAttribute] boolValue];
101 - (void) setExpanded: (BOOL)expanded
103 id ax = NSAccessibilityUnignoredDescendant(self);
104 [ax accessibilitySetValue: $object(expanded) forAttribute: NSAccessibilityExpandedAttribute];
108 - (void) controlTextDidChange: (NSNotification*)n
110 if( _prefix.length == 0 )
113 if( ifSetObj(&_prefix, self.stringValue.lowercaseString) )
114 [self _computeAddresses];
115 MYAddressItem *item = [[MYAddressItem alloc] initWithString: self.stringValue
116 addressType: _property];
117 self.selectedAddress = item;
120 if( _prefix.length == 0 )
123 //Log(@"Address selection = %@",self.selectedAddress);
126 - (void)comboBoxSelectionDidChange:(NSNotification *)notification
128 int sel = self.indexOfSelectedItem;
129 self.selectedAddress = sel>=0 ?[self.addresses objectAtIndex: sel] :nil;
130 //Log(@"Address selection = %@",self.selectedAddress);
135 #pragma mark DATA SOURCE:
138 - (NSInteger)numberOfItemsInComboBox:(NSComboBox *)aComboBox
140 return self.addresses.count;
143 - (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(NSInteger)index
145 return [[self.addresses objectAtIndex: index] description];
154 @implementation MYAddressItem
156 - (id) initWithName: (NSString*)name
157 addressType: (NSString*)addressType address: (NSString*)address
161 _name = name.length ?[name copy] :nil;
162 _addressType = [addressType copy];
163 _address = [address copy];
168 - (id) initWithPerson: (ABPerson*)person
169 addressType: (NSString*)addressType address: (NSString*)address
171 NSString *first = [person valueForProperty: kABFirstNameProperty] ?: @"";
172 NSString *last = [person valueForProperty: kABLastNameProperty] ?: @"";
173 NSString *name = $sprintf(@"%@ %@", first,last);
175 self = [self initWithName: name addressType: addressType address: address];
177 _uuid = person.uniqueId.copy;
181 - (id) initWithString: (NSString*)str addressType: (NSString*)addressType
183 #define kJustAddrRegex "[-a-zA-Z0-9%_+.]+(?:@[-a-zA-Z0-9.]+)"
184 static NSString* const kNameAndAddrRegex = @"^\\s*(\\S+)?\\s*<("kJustAddrRegex")>\\s*$";
185 static NSString* const kAddrRegex = @"^\\s*("kJustAddrRegex")\\s*$";
187 NSString *name = nil;
188 NSString *address = [str stringByMatching: kNameAndAddrRegex capture: 2];
190 name = [str stringByMatching: kNameAndAddrRegex capture: 1];
192 address = [str stringByMatching: kAddrRegex];
198 return [self initWithName: name addressType: addressType address: address];
201 @synthesize name=_name, addressType=_addressType, address=_address;
206 return (ABPerson*) [[ABAddressBook sharedAddressBook] recordForUniqueId: _uuid];
211 - (NSString*) description
213 return $sprintf(@"%@%@<%@>", _name,(_name ?@" ":@""),_address);
216 - (NSComparisonResult) compare: (MYAddressItem*)other
218 NSString *str1 = _name ?:_address;
219 NSString *str2 = other->_name ?: other->_address;
220 return [str1 localizedCaseInsensitiveCompare: str2];