-
Notifications
You must be signed in to change notification settings - Fork 8
/
WebmailerPref.m
187 lines (157 loc) · 6.85 KB
/
WebmailerPref.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#import "WebmailerPref.h"
#import "DefaultsDomain.h"
#import "EditTrackingTableView.h"
#import "ImageForStateTransformer.h"
#import "NSDictionary+NSArray+PlistMutableCopy.h"
#import "URLHandlerController.h"
#import "WebmailerShared.h"
static NSString *const kAppleMailID = @"com.apple.mail";
@implementation ComBelkadanWebmailer_PrefPane
- (id)initWithBundle:(NSBundle *)bundle
{
if (self = [super initWithBundle:bundle])
{
defaults = [[DefaultsDomain domainForName:WebmailerAppDomain] retain];
if ([defaults objectForKey:WebmailerCurrentDestinationKey] == nil)
{
// First time setup
NSDictionary *initialDefaults = [[NSDictionary alloc] initWithContentsOfFile:[bundle pathForResource:@"default" ofType:@"plist"]];
[defaults setDictionary:initialDefaults];
[initialDefaults release];
}
NSURL *daemonURL = [[NSURL alloc] initFileURLWithPath:[bundle pathForResource:@"Webmailer" ofType:@"app"]];
LSRegisterURL((CFURLRef) daemonURL, false);
[daemonURL release];
configurations = [[defaults objectForKey:WebmailerConfigurationsKey] mutableDeepPropertyListCopy];
NSImage *activeImage;
#if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_10_6 <= MAC_OS_X_VERSION_MAX_ALLOWED
if (&NSImageNameStatusAvailable != NULL)
{
activeImage = [[NSImage imageNamed:NSImageNameStatusAvailable] copy];
}
else
#endif
{
activeImage = [[NSImage alloc] initWithContentsOfFile:[bundle pathForImageResource:@"active"]];
}
ImageForStateTransformer *transformer = [[ImageForStateTransformer alloc] initWithTrueImage:activeImage falseImage:nil];
[NSValueTransformer setValueTransformer:transformer forName:@"ImageForState"];
[transformer release];
[activeImage release];
}
return self;
}
- (void)mainViewDidLoad
{
NSSortDescriptor *sortByName = [[NSSortDescriptor alloc] initWithKey:WebmailerDestinationNameKey ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
NSSortDescriptor *sortByDestination = [[NSSortDescriptor alloc] initWithKey:WebmailerDestinationURLKey ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortByName, sortByDestination, nil];
[configurationController setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortByName release];
[sortByDestination release];
[configurationTable setDoubleAction:@selector(apply:)];
[configurationTable setTarget:self];
mailtoController.shouldFullRefresh = YES;
[mailtoController setScheme:WebmailerMailtoScheme fallbackBundleID:kAppleMailID];
[mailtoController addObserver:self forKeyPath:@"selectedBundleID" options:0 context:[WebmailerPref class]];
}
/*!
* Sets the selected configuration as the active destination, and saves this into
* the preferences. The active configuration is marked in two ways; the "active"
* key in each configuration's data dictionary, and the global "currentDestination"
* key. This is to allow quick access for the URL handler application while
* maintaining a tabular view in the preference pane. It also provides a bit of
* redundancy, useful for finding corrupted preferences and saving data.
*/
- (IBAction)apply:(id)sender
{
NSInteger row = [configurationTable clickedRow];
if (row < 0) row = [configurationTable selectedRow];
if (row >= 0)
{
[[configurationController arrangedObjects] setValue:nil forKey:WebmailerDestinationIsActiveKey];
id newActiveDestination = [[configurationController arrangedObjects] objectAtIndex:row];
[newActiveDestination setValue:[NSNumber numberWithBool:YES] forKey:WebmailerDestinationIsActiveKey];
NSString *currentDestination = [newActiveDestination valueForKey:WebmailerDestinationURLKey];
[defaults beginTransaction];
[defaults setObject:currentDestination forKey:WebmailerCurrentDestinationKey];
[defaults setObject:configurations forKey:WebmailerConfigurationsKey];
[defaults endTransaction];
}
}
/*!
* Saves changes to the name or destination of a configuration back to user defaults.
* If the row that was changed was the active configuration,
* also refreshes the "currentDestination" key.
*/
- (IBAction)update:(id)sender
{
if ([configurationTable editedRow] == -1)
{
[configurationController rearrangeObjects];
}
[defaults beginTransaction];
[defaults setObject:configurations forKey:WebmailerConfigurationsKey];
NSInteger row = [configurationTable selectedRow];
NSArray *arrangedConfigurations = [configurationController arrangedObjects];
if (row >= 0 && [[[arrangedConfigurations objectAtIndex:row] objectForKey:WebmailerDestinationIsActiveKey] boolValue])
{
NSString *currentDestination = [[arrangedConfigurations objectAtIndex:row] objectForKey:WebmailerDestinationURLKey];
[defaults setObject:currentDestination forKey:WebmailerCurrentDestinationKey];
}
[defaults endTransaction];
}
/*!
* Adds a new configuration to the list, and tells the table view to edit the name
* of this configuration (name column, first cell).
*/
- (IBAction)add:(id)sender
{
NSMutableDictionary *newConfiguration = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
@"", WebmailerDestinationNameKey,
@"", WebmailerDestinationURLKey,
nil];
// Avoid a save with manual KVO notifications.
NSIndexSet *firstIndex = [NSIndexSet indexSetWithIndex:0];
[self willChange:NSKeyValueChangeInsertion valuesAtIndexes:firstIndex forKey:@"configurations"];
[configurations insertObject:newConfiguration atIndex:0];
[self didChange:NSKeyValueChangeInsertion valuesAtIndexes:firstIndex forKey:@"configurations"];
[newConfiguration release];
[configurationTable selectRowIndexes:firstIndex byExtendingSelection:NO];
[configurationTable editColumn:1 row:0 withEvent:nil select:YES];
}
#pragma mark -
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (context == [WebmailerPref class])
{
NSAssert(object == mailtoController, @"No other objects should be observed.");
(void)LSSetDefaultHandlerForURLScheme((CFStringRef)WebmailerMailtoScheme, (CFStringRef)mailtoController.selectedBundleID);
}
else
{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
#pragma mark -
- (NSUInteger)countOfConfigurations { return [configurations count]; }
- (NSArray *)configurationsAtIndexes:(NSIndexSet *)indexes { return [configurations objectsAtIndexes:indexes]; }
- (void)getConfigurations:(id *)buffer range:(NSRange)range { [configurations getObjects:buffer range:range]; }
- (void)insertConfigurations:(NSArray *)newConfigurations atIndexes:(NSIndexSet *)indexes
{
[configurations insertObjects:newConfigurations atIndexes:indexes];
[defaults setObject:configurations forKey:WebmailerConfigurationsKey];
}
- (void)removeConfigurationsAtIndexes:(NSIndexSet *)indexes
{
[configurations removeObjectsAtIndexes:indexes];
[defaults setObject:configurations forKey:WebmailerConfigurationsKey];
}
- (void)dealloc
{
[configurations release];
[defaults release];
[super dealloc];
}
@end