1/* emacs buffer mode hint -*- objc -*- */ 2 3#import <AppKit/AppKit.h> 4#import "TaskEditor.h" 5#import "StoreManager.h" 6#import "Task.h" 7#import "AlarmEditor.h" 8#import "HourFormatter.h" 9#import "Date.h" 10 11static NSMutableDictionary *editors; 12 13@implementation TaskEditor 14- (BOOL)canBeModified 15{ 16 id <MemoryStore> selectedStore = [[StoreManager globalManager] storeForName:[store titleOfSelectedItem]]; 17 return [selectedStore enabled] && [selectedStore writable]; 18} 19 20- (id)init 21{ 22 HourFormatter *formatter; 23 NSDateFormatter *dateFormatter; 24 25 if (![NSBundle loadNibNamed:@"Task" owner:self]) 26 return nil; 27 if ((self = [super init])) { 28 formatter = AUTORELEASE([[HourFormatter alloc] init]); 29 dateFormatter = AUTORELEASE([[NSDateFormatter alloc] initWithDateFormat:[[NSUserDefaults standardUserDefaults] objectForKey:NSShortDateFormatString] allowNaturalLanguage:NO]); 30 [dueTime setFormatter:formatter]; 31 [dueDate setFormatter:dateFormatter]; 32 } 33 return self; 34} 35 36- (id)initWithTask:(Task *)task 37{ 38 StoreManager *sm = [StoreManager globalManager]; 39 NSEnumerator *list = [sm storeEnumerator]; 40 id <MemoryStore> aStore; 41 id <MemoryStore> originalStore; 42 43 self = [self init]; 44 if (self) { 45 ASSIGN(_task, task); 46 ASSIGNCOPY(_modifiedAlarms, [task alarms]); 47 [summary setStringValue:[task summary]]; 48 49 [[description textStorage] deleteCharactersInRange:NSMakeRange(0, [[description textStorage] length])]; 50 [[description textStorage] appendAttributedString:[task text]]; 51 52 [window makeFirstResponder:summary]; 53 54 originalStore = [task store]; 55 [store removeAllItems]; 56 while ((aStore = [list nextObject])) { 57 if ([aStore enabled] && ([aStore writable] || aStore == originalStore)) 58 [store addItemWithTitle:[aStore description]]; 59 } 60 if ([task store]) 61 [store selectItemWithTitle:[[task store] description]]; 62 else 63 [store selectItemWithTitle:[[sm defaultStore] description]]; 64 65 [state removeAllItems]; 66 [state addItemsWithTitles:[Task stateNamesArray]]; 67 [state selectItemWithTitle:[task stateAsString]]; 68 [ok setEnabled:[self canBeModified]]; 69 if ([task dueDate]) { 70 [dueDate setObjectValue:[[task dueDate] calendarDate]]; 71 [dueTime setIntValue:[[task dueDate] hourOfDay] * 3600 + [[task dueDate] minuteOfHour] * 60]; 72 [toggleDueDate setState:YES]; 73 } 74 [dueDate setEnabled:[toggleDueDate state]]; 75 [dueTime setEnabled:[toggleDueDate state]]; 76 [window makeKeyAndOrderFront:self]; 77 } 78 return self; 79} 80 81- (void)dealloc 82{ 83 RELEASE(_task); 84 RELEASE(_modifiedAlarms); 85 [super dealloc]; 86} 87 88+ (void)initialize 89{ 90 editors = [[NSMutableDictionary alloc] initWithCapacity:2]; 91} 92 93+ (TaskEditor *)editorForTask:(Task *)task 94{ 95 TaskEditor *editor; 96 97 if ((editor = [editors objectForKey:[task UID]])) { 98 [editor->window makeKeyAndOrderFront:self]; 99 return editor; 100 } 101 editor = [[TaskEditor alloc] initWithTask:task]; 102 [editors setObject:editor forKey:[task UID]]; 103 return AUTORELEASE(editor); 104} 105 106- (void)validate:(id)sender 107{ 108 StoreManager *sm = [StoreManager globalManager]; 109 id <MemoryStore> originalStore = [_task store]; 110 id <MemoryStore> aStore; 111 Date *date; 112 113 [_task setSummary:[summary stringValue]]; 114 [_task setText:[[description textStorage] copy]]; 115 [_task setState:[state indexOfSelectedItem]]; 116 [_task setAlarms:_modifiedAlarms]; 117 if ([toggleDueDate state]) { 118 date = [Date dateWithCalendarDate:[dueDate objectValue] withTime:NO]; 119 date = [Date dateWithTimeInterval:[dueTime intValue] sinceDate:date]; 120 [_task setDueDate:date]; 121 } else { 122 [_task setDueDate:nil]; 123 } 124 aStore = [sm storeForName:[store titleOfSelectedItem]]; 125 if (!originalStore) 126 [aStore add:_task]; 127 else if (originalStore == aStore) 128 [aStore update:_task]; 129 else { 130 [originalStore remove:_task]; 131 [aStore add:_task]; 132 } 133 [window close]; 134 [editors removeObjectForKey:[_task UID]]; 135} 136 137- (void)cancel:(id)sender 138{ 139 [window close]; 140 [editors removeObjectForKey:[_task UID]]; 141} 142 143- (void)editAlarms:(id)sender 144{ 145 NSArray *alarmArray; 146 147 alarmArray = [AlarmEditor editAlarms:_modifiedAlarms]; 148 if (alarmArray) 149 ASSIGN(_modifiedAlarms, alarmArray); 150 [window makeKeyAndOrderFront:self]; 151} 152 153- (void)toggleDueDate:(id)sender 154{ 155 Date *date; 156 157 [dueDate setEnabled:[toggleDueDate state]]; 158 [dueTime setEnabled:[toggleDueDate state]]; 159 if ([toggleDueDate state]) { 160 date = [Date now]; 161 [date changeDayBy:7]; 162 [dueDate setObjectValue:[date calendarDate]]; 163 [dueTime setIntValue:[date hourOfDay] * 3600 + [date minuteOfHour] * 60]; 164 } else { 165 [dueDate setObjectValue:nil]; 166 [dueTime setObjectValue:nil]; 167 } 168} 169 170- (BOOL)textView:(NSTextView *)aTextView doCommandBySelector:(SEL)aSelector 171{ 172 if ([NSStringFromSelector(aSelector) isEqualToString:@"insertTab:"]) { 173 [[description window] selectNextKeyView:self]; 174 return YES; 175 } 176 return [description tryToPerform:aSelector with:aTextView]; 177} 178@end 179