Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 223 lines (185 sloc) 8.534 kB
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
1 //
2 // SUUIBasedUpdateDriver.m
3 // Sparkle
4 //
5 // Created by Andy Matuschak on 5/5/08.
6 // Copyright 2008 Andy Matuschak. All rights reserved.
7 //
8
9 #import "SUUIBasedUpdateDriver.h"
f815eec @andymatuschak Fixes 243884
andymatuschak authored
10
11 #import "SUUpdateAlert.h"
ba6c3b6 @andymatuschak Cleaned up SUUpdater.h
andymatuschak authored
12 #import "SUUpdater_Private.h"
f815eec @andymatuschak Fixes 243884
andymatuschak authored
13 #import "SUHost.h"
14 #import "SUStatusController.h"
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
15 #import "SUConstants.h"
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
16
17 @implementation SUUIBasedUpdateDriver
18
19 - (void)didFindValidUpdate
20 {
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
21 updateAlert = [[SUUpdateAlert alloc] initWithAppcastItem:updateItem host:host];
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
22 [updateAlert setDelegate:self];
23
a453afa Delegate can now control how version numbers are formatted/displayed …
Uli Kusterer authored
24 id<SUVersionDisplay> versDisp = nil;
25 if ([[updater delegate] respondsToSelector:@selector(versionDisplayerForUpdater:)])
26 versDisp = [[updater delegate] versionDisplayerForUpdater: updater];
27 [updateAlert setVersionDisplayer: versDisp];
28
675c66f @andymatuschak Fixes 250170
andymatuschak authored
29 if ([[updater delegate] respondsToSelector:@selector(updater:didFindValidUpdate:)])
30 [[updater delegate] updater:updater didFindValidUpdate:updateItem];
c42e3a3 @andymatuschak Fixed 251010
andymatuschak authored
31
cec9166 @mattstevens Improved notification handling for otherwise UI-less background appli…
mattstevens authored
32 // If the app is a menubar app or the like, we need to focus it first and alter the
33 // update prompt to behave like a normal window. Otherwise if the window were hidden
34 // there may be no way for the application to be activated to make it visible again.
c42e3a3 @andymatuschak Fixed 251010
andymatuschak authored
35 if ([host isBackgroundApplication])
cec9166 @mattstevens Improved notification handling for otherwise UI-less background appli…
mattstevens authored
36 {
37 [[updateAlert window] setHidesOnDeactivate:NO];
38 [NSApp activateIgnoringOtherApps:YES];
39 }
675c66f @andymatuschak Fixes 250170
andymatuschak authored
40
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
41 // Only show the update alert if the app is active; otherwise, we'll wait until it is.
42 if ([NSApp isActive])
af245f3 @andymatuschak Fixes 236636:
andymatuschak authored
43 [[updateAlert window] makeKeyAndOrderFront:self];
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
44 else
45 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) name:NSApplicationDidBecomeActiveNotification object:NSApp];
46 }
47
48 - (void)didNotFindUpdate
49 {
b3f3944 @andymatuschak Fixes 244857
andymatuschak authored
50 if ([[updater delegate] respondsToSelector:@selector(updaterDidNotFindUpdate:)])
51 [[updater delegate] updaterDidNotFindUpdate:updater];
f6710e2 @uliwitness Sparkle now warns the delegate before and after it brings up a modal …
uliwitness authored
52
34586bc @andymatuschak Finishing fixing #279454 (up to date -> up-to-date)
andymatuschak authored
53 NSAlert *alert = [NSAlert alertWithMessageText:SULocalizedString(@"You're up-to-date!", nil) defaultButton:SULocalizedString(@"OK", nil) alternateButton:nil otherButton:nil informativeTextWithFormat:SULocalizedString(@"%@ %@ is currently the newest version available.", nil), [host name], [host displayVersion]];
cec9166 @mattstevens Improved notification handling for otherwise UI-less background appli…
mattstevens authored
54 [self showModalAlert:alert];
6a55122 @andymatuschak Fixes bug 236694
andymatuschak authored
55 [self abortUpdate];
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
56 }
57
58 - (void)applicationDidBecomeActive:(NSNotification *)aNotification
59 {
af245f3 @andymatuschak Fixes 236636:
andymatuschak authored
60 [[updateAlert window] makeKeyAndOrderFront:self];
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
61 [[NSNotificationCenter defaultCenter] removeObserver:self name:@"NSApplicationDidBecomeActiveNotification" object:NSApp];
62 }
63
64 - (void)updateAlert:(SUUpdateAlert *)alert finishedWithChoice:(SUUpdateAlertChoice)choice
65 {
66 [updateAlert release]; updateAlert = nil;
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
67 [host setObject:nil forUserDefaultsKey:SUSkippedVersionKey];
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
68 switch (choice)
69 {
70 case SUInstallUpdateChoice:
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
71 statusController = [[SUStatusController alloc] initWithHost:host];
d7774c0 performed a code review, specifically:
Sean McBride authored
72 [statusController beginActionWithTitle:SULocalizedString(@"Downloading update...", @"Take care not to overflow the status window.") maxProgressValue:0.0 statusText:nil];
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
73 [statusController setButtonTitle:SULocalizedString(@"Cancel", nil) target:self action:@selector(cancelDownload:) isDefault:NO];
74 [statusController showWindow:self];
75 [self downloadUpdate];
76 break;
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
77
78 case SUOpenInfoURLChoice:
79 [[NSWorkspace sharedWorkspace] openURL: [updateItem infoURL]];
80 [self abortUpdate];
81 break;
82
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
83 case SUSkipThisVersionChoice:
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
84 [host setObject:[updateItem versionString] forUserDefaultsKey:SUSkippedVersionKey];
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
85 [self abortUpdate];
86 break;
87
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
88 case SURemindMeLaterChoice:
89 [self abortUpdate];
90 break;
91 }
92 }
93
94 - (void)download:(NSURLDownload *)download didReceiveResponse:(NSURLResponse *)response
95 {
96 [statusController setMaxProgressValue:[response expectedContentLength]];
97 }
98
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
99 - (NSString *)humanReadableSizeFromDouble:(double)value
95aabd5 @andymatuschak Fixed the old-style em-dash in the French localization; fixed localiz…
andymatuschak authored
100 {
d7774c0 performed a code review, specifically:
Sean McBride authored
101 if (value < 1000)
95aabd5 @andymatuschak Fixed the old-style em-dash in the French localization; fixed localiz…
andymatuschak authored
102 return [NSString stringWithFormat:@"%.0lf %@", value, SULocalizedString(@"B", @"the unit for bytes")];
103
d7774c0 performed a code review, specifically:
Sean McBride authored
104 if (value < 1000 * 1000)
105 return [NSString stringWithFormat:@"%.0lf %@", value / 1000.0, SULocalizedString(@"KB", @"the unit for kilobytes")];
95aabd5 @andymatuschak Fixed the old-style em-dash in the French localization; fixed localiz…
andymatuschak authored
106
d7774c0 performed a code review, specifically:
Sean McBride authored
107 if (value < 1000 * 1000 * 1000)
108 return [NSString stringWithFormat:@"%.1lf %@", value / 1000.0 / 1000.0, SULocalizedString(@"MB", @"the unit for megabytes")];
95aabd5 @andymatuschak Fixed the old-style em-dash in the French localization; fixed localiz…
andymatuschak authored
109
d7774c0 performed a code review, specifically:
Sean McBride authored
110 return [NSString stringWithFormat:@"%.2lf %@", value / 1000.0 / 1000.0 / 1000.0, SULocalizedString(@"GB", @"the unit for gigabytes")];
95aabd5 @andymatuschak Fixed the old-style em-dash in the French localization; fixed localiz…
andymatuschak authored
111 }
112
c2745f5 @andymatuschak Fixes #236948:
andymatuschak authored
113 - (void)download:(NSURLDownload *)download didReceiveDataOfLength:(NSUInteger)length
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
114 {
d7774c0 performed a code review, specifically:
Sean McBride authored
115 [statusController setProgressValue:[statusController progressValue] + (double)length];
116 if ([statusController maxProgressValue] > 0.0)
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
117 [statusController setStatusText:[NSString stringWithFormat:SULocalizedString(@"%@ of %@", nil), [self humanReadableSizeFromDouble:[statusController progressValue]], [self humanReadableSizeFromDouble:[statusController maxProgressValue]]]];
3d7e8c6 @andymatuschak Fixes 244214
andymatuschak authored
118 else
dab8a36 renamed all methods that start with underscore, since that's reserved…
Sean McBride authored
119 [statusController setStatusText:[NSString stringWithFormat:SULocalizedString(@"%@ downloaded", nil), [self humanReadableSizeFromDouble:[statusController progressValue]]]];
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
120 }
121
fa8aace @uliwitness Make sure we also delete the temp dir when the user clicks "cancel" d…
uliwitness authored
122 - (IBAction)cancelDownload: (id)sender
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
123 {
124 if (download)
125 [download cancel];
126 [self abortUpdate];
127 }
128
129 - (void)extractUpdate
130 {
131 // Now we have to extract the downloaded archive.
d7774c0 performed a code review, specifically:
Sean McBride authored
132 [statusController beginActionWithTitle:SULocalizedString(@"Extracting update...", @"Take care not to overflow the status window.") maxProgressValue:0.0 statusText:nil];
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
133 [statusController setButtonEnabled:NO];
134 [super extractUpdate];
135 }
136
d7774c0 performed a code review, specifically:
Sean McBride authored
137 - (void)unarchiver:(SUUnarchiver *)ua extractedLength:(unsigned long)length
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
138 {
139 // We do this here instead of in extractUpdate so that we only have a determinate progress bar for archives with progress.
d7774c0 performed a code review, specifically:
Sean McBride authored
140 if ([statusController maxProgressValue] == 0.0)
141 {
142 NSDictionary * attributes;
4fad530 Change availability checks so that they build on 10.4
Stuart Morgan authored
143 #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
d7774c0 performed a code review, specifically:
Sean McBride authored
144 attributes = [[NSFileManager defaultManager] fileAttributesAtPath:downloadPath traverseLink:NO];
54299d7 added #ifdef's for Tiger support
August Joki authored
145 #else
d7774c0 performed a code review, specifically:
Sean McBride authored
146 attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:downloadPath error:nil];
54299d7 added #ifdef's for Tiger support
August Joki authored
147 #endif
d7774c0 performed a code review, specifically:
Sean McBride authored
148 [statusController setMaxProgressValue:[[attributes objectForKey:NSFileSize] doubleValue]];
149 }
150 [statusController setProgressValue:[statusController progressValue] + (double)length];
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
151 }
152
153 - (void)unarchiverDidFinish:(SUUnarchiver *)ua
154 {
d7774c0 performed a code review, specifically:
Sean McBride authored
155 [statusController beginActionWithTitle:SULocalizedString(@"Ready to Install", nil) maxProgressValue:1.0 statusText:nil];
156 [statusController setProgressValue:1.0]; // Fill the bar.
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
157 [statusController setButtonEnabled:YES];
158 [statusController setButtonTitle:SULocalizedString(@"Install and Relaunch", nil) target:self action:@selector(installAndRestart:) isDefault:YES];
18df114 @uliwitness Bring window to front when progress panel changes to "Install and res…
uliwitness authored
159 [[statusController window] makeKeyAndOrderFront: self];
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
160 [NSApp requestUserAttention:NSInformationalRequest];
161 }
162
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
163 - (void)installAndRestart: (id)sender
164 {
c96aa2e @andymatuschak The finish_installation tool will not relaunch the host app if it's u…
andymatuschak authored
165 [self installWithToolAndRelaunch:YES];
43a0a7d @uliwitness Merge of changes from SVN repository:
uliwitness authored
166 }
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
167
c96aa2e @andymatuschak The finish_installation tool will not relaunch the host app if it's u…
andymatuschak authored
168 - (void)installWithToolAndRelaunch:(BOOL)relaunch
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
169 {
d7774c0 performed a code review, specifically:
Sean McBride authored
170 [statusController beginActionWithTitle:SULocalizedString(@"Installing update...", @"Take care not to overflow the status window.") maxProgressValue:0.0 statusText:nil];
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
171 [statusController setButtonEnabled:NO];
c96aa2e @andymatuschak The finish_installation tool will not relaunch the host app if it's u…
andymatuschak authored
172 [super installWithToolAndRelaunch:relaunch];
43a603c if the user chooses to not restart the host app after installing the …
Simone Manganelli authored
173
174
175 // if a user chooses to NOT relaunch the app (as is the case with WebKit
176 // when it asks you if you are sure you want to close the app with multiple
177 // tabs open), the status window still stays on the screen and obscures
178 // other windows; with this fix, it doesn't
179
180 if (statusController)
181 {
182 [statusController close];
183 [statusController autorelease];
2fc1b66 @andymatuschak Fixing:
andymatuschak authored
184 statusController = nil;
43a603c if the user chooses to not restart the host app after installing the …
Simone Manganelli authored
185 }
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
186 }
187
188 - (void)abortUpdateWithError:(NSError *)error
189 {
190 NSAlert *alert = [NSAlert alertWithMessageText:SULocalizedString(@"Update Error!", nil) defaultButton:SULocalizedString(@"Cancel Update", nil) alternateButton:nil otherButton:nil informativeTextWithFormat:[error localizedDescription]];
cec9166 @mattstevens Improved notification handling for otherwise UI-less background appli…
mattstevens authored
191 [self showModalAlert:alert];
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
192 [super abortUpdateWithError:error];
193 }
194
195 - (void)abortUpdate
196 {
197 if (statusController)
198 {
199 [statusController close];
200 [statusController autorelease];
2fc1b66 @andymatuschak Fixing:
andymatuschak authored
201 statusController = nil;
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
202 }
203 [super abortUpdate];
204 }
205
cec9166 @mattstevens Improved notification handling for otherwise UI-less background appli…
mattstevens authored
206 - (void)showModalAlert:(NSAlert *)alert
207 {
f6710e2 @uliwitness Sparkle now warns the delegate before and after it brings up a modal …
uliwitness authored
208 if ([[updater delegate] respondsToSelector:@selector(updaterWillShowModalAlert:)])
209 [[updater delegate] updaterWillShowModalAlert: updater];
210
cec9166 @mattstevens Improved notification handling for otherwise UI-less background appli…
mattstevens authored
211 // When showing a modal alert we need to ensure that background applications
212 // are focused to inform the user since there is no dock icon to notify them.
c42e3a3 @andymatuschak Fixed 251010
andymatuschak authored
213 if ([host isBackgroundApplication]) { [NSApp activateIgnoringOtherApps:YES]; }
cec9166 @mattstevens Improved notification handling for otherwise UI-less background appli…
mattstevens authored
214
c42e3a3 @andymatuschak Fixed 251010
andymatuschak authored
215 [alert setIcon:[host icon]];
cec9166 @mattstevens Improved notification handling for otherwise UI-less background appli…
mattstevens authored
216 [alert runModal];
f6710e2 @uliwitness Sparkle now warns the delegate before and after it brings up a modal …
uliwitness authored
217
218 if ([[updater delegate] respondsToSelector:@selector(updaterDidShowModalAlert:)])
219 [[updater delegate] updaterDidShowModalAlert: updater];
cec9166 @mattstevens Improved notification handling for otherwise UI-less background appli…
mattstevens authored
220 }
221
43ee593 @andymatuschak Fixes bug 236235.
andymatuschak authored
222 @end
Something went wrong with that request. Please try again.