-
Notifications
You must be signed in to change notification settings - Fork 8
/
ExtraSettingsController.m
272 lines (218 loc) · 11.2 KB
/
ExtraSettingsController.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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
#import "ExtraSettingsController.h"
#import <Sparkle/Sparkle.h>
#import "URLHandlerController.h"
#import "DefaultsDomain.h"
static NSString * const kHTTPScheme = @"http";
static NSString * const kAppleSafariID = @"com.apple.safari";
static NSString * const kWebmailerIconName = @"com.belkadan.Webmailer";
static NSImage *GetWebmailerIcon ()
{
static NSImage *prefIcon = nil;
if (!prefIcon) {
prefIcon = [NSImage imageNamed:kWebmailerIconName];
if (!prefIcon) {
NSBundle *bundle = [NSBundle bundleForClass:[ExtraSettingsController class]];
prefIcon = [[NSImage alloc] initByReferencingFile:[bundle pathForImageResource:@"icon"]];
[prefIcon setName:kWebmailerIconName];
}
}
return prefIcon;
}
@implementation ComBelkadanWebmailer_ExtraSettingsController
- (id)init
{
return [self initWithWindowNibName:@"AdditionalSettings"];
}
- (void)windowDidLoad
{
[super windowDidLoad];
ComBelkadanUtils_DefaultsDomain *defaults = [ComBelkadanUtils_DefaultsDomain domainForName:WebmailerAppDomain];
[browserController setScheme:kHTTPScheme fallbackBundleID:kAppleSafariID];
browserController.selectedBundleID = [defaults objectForKey:WebmailerChosenBrowserIDKey];
[browserController addObserver:self forKeyPath:@"selectedBundleID" options:0 context:[ExtraSettingsController class]];
}
#pragma mark -
- (BrowserChoice)browserChoosingMode
{
ComBelkadanUtils_DefaultsDomain *defaults = [ComBelkadanUtils_DefaultsDomain domainForName:WebmailerAppDomain];
NSNumber *modeObject = [defaults objectForKey:WebmailerBrowserChoosingModeKey];
// Backwards compatibility
if (!modeObject)
{
modeObject = [defaults objectForKey:WebmailerDisableAppChoosingKey];
if (modeObject)
{
[defaults removeObjectForKey:WebmailerDisableAppChoosingKey];
[defaults setObject:[NSNumber numberWithUnsignedInteger:[modeObject unsignedIntegerValue]] forKey:WebmailerBrowserChoosingModeKey];
}
}
return [modeObject unsignedIntegerValue];
}
- (void)setBrowserChoosingMode:(BrowserChoice)mode
{
NSAssert(mode <= BrowserChoiceLast, @"Invalid browser choice mode.");
ComBelkadanUtils_DefaultsDomain *defaults = [ComBelkadanUtils_DefaultsDomain domainForName:WebmailerAppDomain];
[defaults setObject:[NSNumber numberWithUnsignedInteger:mode] forKey:WebmailerBrowserChoosingModeKey];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (context == [ExtraSettingsController class])
{
NSAssert(object == browserController, @"No other objects should be observed.");
ComBelkadanUtils_DefaultsDomain *defaults = [ComBelkadanUtils_DefaultsDomain domainForName:WebmailerAppDomain];
[defaults setObject:browserController.selectedBundleID forKey:WebmailerChosenBrowserIDKey];
}
else
{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
#pragma mark -
- (IBAction)checkForUpdates:(id)sender
{
[updateController checkForUpdates:sender];
}
- (IBAction)exportSettings:(id)sender
{
NSString *fileName = NSLocalizedStringFromTableInBundle(@"Webmailer Settings", @"Localizable", [NSBundle bundleForClass:[ExtraSettingsController class]], @"Settings import/export");
NSSavePanel *savePanel = [NSSavePanel savePanel];
[savePanel setAllowedFileTypes:[NSArray arrayWithObject:@"plist"]];
[savePanel setAllowsOtherFileTypes:NO];
[self endSheet:nil];
[savePanel beginSheetForDirectory:nil file:fileName modalForWindow:[mainWindowView window] modalDelegate:self didEndSelector:@selector(exportSettingsPanelDidEnd:returnCode:contextInfo:) contextInfo:NULL];
}
- (void)exportSettingsPanelDidEnd:(NSSavePanel *)savePanel returnCode:(NSInteger)returnCode contextInfo:(void *)unused
{
if (returnCode == NSCancelButton) return;
NSMutableDictionary *settings = [[ComBelkadanUtils_DefaultsDomain domainForName:WebmailerAppDomain] mutableCopy];
NSBundle *bundle = [NSBundle bundleForClass:[ExtraSettingsController class]];
NSString *bundleVersion = [bundle objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
[settings setObject:bundleVersion forKey:WebmailerAppDomain];
[settings writeToURL:[savePanel URL] atomically:YES];
[settings release];
}
- (IBAction)importSettings:(id)sender {
[self endSheet:nil];
[[NSOpenPanel openPanel] beginSheetForDirectory:nil file:nil types:[NSArray arrayWithObject:@"plist"] modalForWindow:[mainWindowView window] modalDelegate:self didEndSelector:@selector(importSettingsPanelDidEnd:returnCode:contextInfo:) contextInfo:NULL];
}
- (void)importSettingsPanelDidEnd:(NSOpenPanel *)openPanel returnCode:(NSInteger)returnCode contextInfo:(void *)unused {
if (returnCode == NSCancelButton) return;
[openPanel orderOut:nil];
[self importSettingsFromURL:[openPanel URL]];
}
- (void)importSettingsFromURL:(NSURL *)url {
NSDictionary *settings = [[NSDictionary alloc] initWithContentsOfURL:url];
NSString *settingsVersion = [settings objectForKey:WebmailerAppDomain];
NSArray *destinations = [settings objectForKey:WebmailerConfigurationsKey];
if (!settingsVersion && !destinations) {
NSBundle *bundle = [NSBundle bundleForClass:[ExtraSettingsController class]];
NSAlert *sorry = [[[NSAlert alloc] init] autorelease];
[sorry setIcon:GetWebmailerIcon()];
[sorry setMessageText:NSLocalizedStringFromTableInBundle(@"Could not read settings file.", @"Localizable", bundle, @"Settings import/export")];
[sorry setInformativeText:NSLocalizedStringFromTableInBundle(@"This does not appear to be a Webmailer settings file.", @"Localizable", bundle, @"Settings import/export")];
[sorry beginSheetModalForWindow:[mainWindowView window] modalDelegate:nil didEndSelector:NULL contextInfo:NULL];
} else if ([settingsVersion compare:@"2" options:NSCaseInsensitiveSearch|NSNumericSearch] != NSOrderedAscending) {
NSBundle *bundle = [NSBundle bundleForClass:[ExtraSettingsController class]];
NSAlert *sorry = [[[NSAlert alloc] init] autorelease];
[sorry setIcon:GetWebmailerIcon()];
[sorry setMessageText:NSLocalizedStringFromTableInBundle(@"Could not read settings file.", @"Localizable", bundle, @"Settings import/export")];
[sorry setInformativeText:[NSString stringWithFormat:NSLocalizedStringFromTableInBundle(@"These settings are for Webmailer %@, but you have %@.", @"Localizable", bundle, @"Settings import/export"), settingsVersion, [bundle objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey]]];
[sorry beginSheetModalForWindow:[mainWindowView window] modalDelegate:nil didEndSelector:NULL contextInfo:NULL];
} else {
ComBelkadanUtils_DefaultsDomain *defaults = [DefaultsDomain domainForName:WebmailerAppDomain];
[defaults beginTransaction];
NSMutableSet *existingDestinations = [NSMutableSet setWithArray:[[configurationController arrangedObjects] valueForKey:WebmailerDestinationURLKey]];
// Change to the new selected destination.
NSString *newActiveDestination = [settings objectForKey:WebmailerCurrentDestinationKey];
if (newActiveDestination && ![[defaults objectForKey:WebmailerCurrentDestinationKey] isEqual:newActiveDestination]) {
if ([existingDestinations containsObject:newActiveDestination]) {
// Case 1: The selected destination already exists in the current set.
// We have to (a) set the new active destination, and (b) clear the old one.
BOOL foundOneAlready = NO;
for (NSMutableDictionary *existing in [configurationController arrangedObjects]) {
if ([newActiveDestination isEqual:[existing objectForKey:WebmailerDestinationURLKey]]) {
[existing setObject:[NSNumber numberWithBool:YES] forKey:WebmailerDestinationIsActiveKey];
if (foundOneAlready) break;
foundOneAlready = YES;
} else if ([[existing objectForKey:WebmailerDestinationIsActiveKey] boolValue]) {
[existing removeObjectForKey:WebmailerDestinationIsActiveKey];
if (foundOneAlready) break;
foundOneAlready = YES;
}
}
} else {
// Case 2: The selected destination is new.
// We only have to clear the old active flag.
for (NSMutableDictionary *existing in [configurationController arrangedObjects]) {
if ([[existing objectForKey:WebmailerDestinationIsActiveKey] boolValue]) {
[existing removeObjectForKey:WebmailerDestinationIsActiveKey];
break;
}
}
}
[defaults setObject:newActiveDestination forKey:WebmailerCurrentDestinationKey];
}
// Add any missing destination URLs. Unique by URL only -- if two destinations have the same name, keep the existing one.
NSMutableArray *newConfigurations = [NSMutableArray array];
for (NSDictionary *dict in destinations) {
if (![existingDestinations containsObject:[dict objectForKey:WebmailerDestinationURLKey]]) {
NSMutableDictionary *newConfiguration = [dict mutableCopy];
if (!newActiveDestination) [newConfiguration removeObjectForKey:WebmailerDestinationIsActiveKey];
[newConfigurations addObject:newConfiguration];
[newConfiguration release];
}
}
if ([newConfigurations count] > 0) {
[configurationController addObjects:newConfigurations];
[configurationController rearrangeObjects];
}
// Set the browser choosing mode...
NSNumber *browserChoosingMode = [settings objectForKey:WebmailerBrowserChoosingModeKey];
if (!browserChoosingMode) {
if (![defaults objectForKey:WebmailerBrowserChoosingModeKey]) {
// Only fall back to the legacy key if we don't have an explicit setting here.
browserChoosingMode = [settings objectForKey:WebmailerDisableAppChoosingKey];
}
}
if (browserChoosingMode) self.browserChoosingMode = [browserChoosingMode unsignedIntegerValue];
// ...and the selected browser.
NSString *selectedBrowser = [settings objectForKey:WebmailerChosenBrowserIDKey];
if (selectedBrowser) browserController.selectedBundleID = selectedBrowser;
[defaults endTransaction];
}
[settings release];
}
#pragma mark -
- (NSArray *)dragTypesForDropOverlayView:(ComBelkadanUtils_DropOverlayView *)dropView {
return [NSArray arrayWithObject:NSFilenamesPboardType];
}
- (NSDragOperation)dropOverlayView:(ComBelkadanUtils_DropOverlayView *)view validateDrop:(id <NSDraggingInfo>)info {
NSPasteboard *pboard = [info draggingPasteboard];
NSString *type = [pboard availableTypeFromArray:[NSArray arrayWithObject:NSFilenamesPboardType]];
NSAssert([type isEqual:NSFilenamesPboardType], @"Only our drag type should be enabled.");
NSArray *array = [pboard propertyListForType:type];
if ([array count] != 1) return NSDragOperationNone;
if (![[[array objectAtIndex:0] pathExtension] isEqual:@"plist"]) return NSDragOperationNone;
return NSDragOperationCopy;
}
- (BOOL)dropOverlayView:(ComBelkadanUtils_DropOverlayView *)view acceptDrop:(id <NSDraggingInfo>)info {
NSPasteboard *pboard = [info draggingPasteboard];
NSString *type = [pboard availableTypeFromArray:[NSArray arrayWithObject:NSFilenamesPboardType]];
NSAssert([type isEqual:NSFilenamesPboardType], @"Only our drag type should be enabled.");
NSArray *array = [pboard propertyListForType:type];
[self importSettingsFromURL:[NSURL fileURLWithPath:[array objectAtIndex:0]]];
// Whether or not we succeeded in importing the file, the drag icon should
// still not slide back.
return YES;
}
#pragma mark -
- (IBAction)showAsSheet:(id)sender
{
[NSApp beginSheet:[self window] modalForWindow:[mainWindowView window] modalDelegate:nil didEndSelector:NULL contextInfo:NULL];
}
- (IBAction)endSheet:(id)sender
{
[NSApp endSheet:[self window]];
[self close];
}
@end