Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: chrome/browser/cocoa/about_window_controller.mm

Issue 449004: Merge r33241 to the 249 branch.... (Closed) Base URL: svn://svn.chromium.org/chrome/branches/249/src/
Patch Set: Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "chrome/browser/cocoa/about_window_controller.h"
6
5 #include "app/l10n_util_mac.h" 7 #include "app/l10n_util_mac.h"
6 #include "app/resource_bundle.h" 8 #include "app/resource_bundle.h"
7 #include "base/logging.h" 9 #include "base/logging.h"
8 #include "base/mac_util.h" 10 #include "base/mac_util.h"
9 #include "base/string_util.h" 11 #include "base/string_util.h"
10 #include "base/sys_string_conversions.h" 12 #include "base/sys_string_conversions.h"
11 #import "chrome/app/keystone_glue.h"
12 #include "chrome/browser/browser_list.h" 13 #include "chrome/browser/browser_list.h"
13 #import "chrome/browser/cocoa/about_window_controller.h"
14 #import "chrome/browser/cocoa/background_tile_view.h" 14 #import "chrome/browser/cocoa/background_tile_view.h"
15 #import "chrome/browser/cocoa/keystone_glue.h"
15 #include "chrome/browser/cocoa/restart_browser.h" 16 #include "chrome/browser/cocoa/restart_browser.h"
16 #include "grit/chromium_strings.h" 17 #include "grit/chromium_strings.h"
17 #include "grit/generated_resources.h" 18 #include "grit/generated_resources.h"
18 #include "grit/theme_resources.h" 19 #include "grit/theme_resources.h"
19 #include "grit/locale_settings.h" 20 #include "grit/locale_settings.h"
20 #include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" 21 #include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
21 22
22 namespace { 23 namespace {
23 24
24 void AttributedStringAppendString(NSMutableAttributedString* attr_str, 25 void AttributedStringAppendString(NSMutableAttributedString* attr_str,
(...skipping 27 matching lines...) Expand all
52 range:range]; 53 range:range];
53 } 54 }
54 55
55 } // namespace 56 } // namespace
56 57
57 @interface AboutWindowController(Private) 58 @interface AboutWindowController(Private)
58 59
59 // Launches a check for available updates. 60 // Launches a check for available updates.
60 - (void)checkForUpdate; 61 - (void)checkForUpdate;
61 62
63 // Turns the update and promotion blocks on and off as needed based on whether
64 // updates are possible and promotion is desired or required.
65 - (void)adjustUpdateUIVisibility;
66
67 // Maintains the update and promotion block visibility and window sizing.
68 // This uses bool instead of BOOL for the convenience of the internal
69 // implementation.
70 - (void)setAllowsUpdate:(bool)update allowsPromotion:(bool)promotion;
71
62 // Notification callback, called with the status of asynchronous 72 // Notification callback, called with the status of asynchronous
63 // -checkForUpdate and -updateNow: operations. 73 // -checkForUpdate and -updateNow: operations.
64 - (void)updateStatus:(NSNotification*)notification; 74 - (void)updateStatus:(NSNotification*)notification;
65 75
66 // These methods maintain the image (or throbber) and text displayed regarding 76 // These methods maintain the image (or throbber) and text displayed regarding
67 // update status. -setUpdateThrobberMessage: starts a progress throbber and 77 // update status. -setUpdateThrobberMessage: starts a progress throbber and
68 // sets the text. -setUpdateImage:message: displays an image and sets the 78 // sets the text. -setUpdateImage:message: displays an image and sets the
69 // text. 79 // text.
70 - (void)setUpdateThrobberMessage:(NSString*)message; 80 - (void)setUpdateThrobberMessage:(NSString*)message;
71 - (void)setUpdateImage:(int)imageID message:(NSString*)message; 81 - (void)setUpdateImage:(int)imageID message:(NSString*)message;
(...skipping 27 matching lines...) Expand all
99 } 109 }
100 110
101 - (void)dealloc { 111 - (void)dealloc {
102 [[NSNotificationCenter defaultCenter] removeObserver:self]; 112 [[NSNotificationCenter defaultCenter] removeObserver:self];
103 [super dealloc]; 113 [super dealloc];
104 } 114 }
105 115
106 // YES when an About box is currently showing the kAutoupdateInstallFailed 116 // YES when an About box is currently showing the kAutoupdateInstallFailed
107 // status, or if no About box is visible, if the most recent About box to be 117 // status, or if no About box is visible, if the most recent About box to be
108 // closed was closed while showing this status. When an About box opens, if 118 // closed was closed while showing this status. When an About box opens, if
109 // the recent status is kAutoupdateInstallFailed and 119 // the recent status is kAutoupdateInstallFailed or kAutoupdatePromoteFailed
110 // recentShownInstallFailedStatus is NO, the failure needs to be shown instead 120 // and recentShownUserActionFailedStatus is NO, the failure needs to be shown
111 // of launching a new update check. recentShownInstallFailedStatus is 121 // instead of launching a new update check. recentShownInstallFailedStatus is
112 // maintained by -updateStatus:. 122 // maintained by -updateStatus:.
113 static BOOL recentShownInstallFailedStatus = NO; 123 static BOOL recentShownUserActionFailedStatus = NO;
114 124
115 - (void)awakeFromNib { 125 - (void)awakeFromNib {
116 NSBundle* bundle = mac_util::MainAppBundle(); 126 NSBundle* bundle = mac_util::MainAppBundle();
117 NSString* chromeVersion = 127 NSString* chromeVersion =
118 [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; 128 [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
119 129
120 #if defined(GOOGLE_CHROME_BUILD) 130 #if defined(GOOGLE_CHROME_BUILD)
121 NSString* version = chromeVersion; 131 NSString* version = chromeVersion;
122 #else // GOOGLE_CHROME_BUILD 132 #else // GOOGLE_CHROME_BUILD
123 // The format string is not localized, but this is how the displayed version 133 // The format string is not localized, but this is how the displayed version
(...skipping 15 matching lines...) Expand all
139 [logoView_ setImage:logoImage]; 149 [logoView_ setImage:logoImage];
140 150
141 [[legalText_ textStorage] setAttributedString:[[self class] legalTextBlock]]; 151 [[legalText_ textStorage] setAttributedString:[[self class] legalTextBlock]];
142 152
143 // Resize our text view now so that the |updateShift| below is set 153 // Resize our text view now so that the |updateShift| below is set
144 // correctly. The About box has its controls manually positioned, so we need 154 // correctly. The About box has its controls manually positioned, so we need
145 // to calculate how much larger (or smaller) our text box is and store that 155 // to calculate how much larger (or smaller) our text box is and store that
146 // difference in |legalShift|. We do something similar with |updateShift| 156 // difference in |legalShift|. We do something similar with |updateShift|
147 // below, which is either 0, or the amount of space to offset the window size 157 // below, which is either 0, or the amount of space to offset the window size
148 // because the view that contains the update button has been removed because 158 // because the view that contains the update button has been removed because
149 // this build doesn't have KeyStone. 159 // this build doesn't have Keystone.
150 NSRect oldLegalRect = [legalBlock_ frame]; 160 NSRect oldLegalRect = [legalBlock_ frame];
151 [legalText_ sizeToFit]; 161 [legalText_ sizeToFit];
152 NSRect newRect = oldLegalRect; 162 NSRect newRect = oldLegalRect;
153 newRect.size.height = [legalText_ frame].size.height; 163 newRect.size.height = [legalText_ frame].size.height;
154 [legalBlock_ setFrame:newRect]; 164 [legalBlock_ setFrame:newRect];
155 CGFloat legalShift = newRect.size.height - oldLegalRect.size.height; 165 CGFloat legalShift = newRect.size.height - oldLegalRect.size.height;
156 166
157 KeystoneGlue* keystoneGlue = [KeystoneGlue defaultKeystoneGlue]; 167 NSRect backgroundFrame = [backgroundView_ frame];
158 CGFloat updateShift; 168 backgroundFrame.origin.y += legalShift;
159 if (keystoneGlue) { 169 [backgroundView_ setFrame:backgroundFrame];
170
171 NSSize windowDelta = NSMakeSize(0.0, legalShift);
172 [GTMUILocalizerAndLayoutTweaker
173 resizeWindowWithoutAutoResizingSubViews:[self window]
174 delta:windowDelta];
175
176 windowHeight_ = [[self window] frame].size.height;
177
178 [self adjustUpdateUIVisibility];
179
180 // Don't do anything update-related if adjustUpdateUIVisibility decided that
181 // updates aren't possible.
182 if (![updateBlock_ isHidden]) {
183 KeystoneGlue* keystoneGlue = [KeystoneGlue defaultKeystoneGlue];
184 AutoupdateStatus recentStatus = [keystoneGlue recentStatus];
160 if ([keystoneGlue asyncOperationPending] || 185 if ([keystoneGlue asyncOperationPending] ||
161 ([keystoneGlue recentStatus] == kAutoupdateInstallFailed && 186 recentStatus == kAutoupdateRegisterFailed ||
162 !recentShownInstallFailedStatus)) { 187 ((recentStatus == kAutoupdateInstallFailed ||
188 recentStatus == kAutoupdatePromoteFailed) &&
189 !recentShownUserActionFailedStatus)) {
163 // If an asynchronous update operation is currently pending, such as a 190 // If an asynchronous update operation is currently pending, such as a
164 // check for updates or an update installation attempt, set the status 191 // check for updates or an update installation attempt, set the status
165 // up correspondingly without launching a new update check. 192 // up correspondingly without launching a new update check.
166 // 193 //
167 // If a previous update attempt was unsuccessful but no About box was 194 // If registration failed, no other operations make sense, so just go
168 // around to report the error, show it now, and allow another chance to 195 // straight to the error.
169 // install the update. 196 //
197 // If a previous update or promotion attempt was unsuccessful but no
198 // About box was around to report the error, show it now, and allow
199 // another chance to perform the action.
170 [self updateStatus:[keystoneGlue recentNotification]]; 200 [self updateStatus:[keystoneGlue recentNotification]];
171 } else { 201 } else {
172 // Launch a new update check, even if one was already completed, because 202 // Launch a new update check, even if one was already completed, because
173 // a new update may be available or a new update may have been installed 203 // a new update may be available or a new update may have been installed
174 // in the background since the last time an About box was displayed. 204 // in the background since the last time an About box was displayed.
175 [self checkForUpdate]; 205 [self checkForUpdate];
176 } 206 }
177
178 updateShift = 0.0;
179 } else {
180 // Hide all the update UI
181 [updateBlock_ setHidden:YES];
182
183 // Figure out the amount being removed by taking out the update block
184 // and its spacing.
185 updateShift = NSMinY([legalBlock_ frame]) - NSMinY([updateBlock_ frame]);
186
187 NSRect legalFrame = [legalBlock_ frame];
188 legalFrame.origin.y -= updateShift;
189 [legalBlock_ setFrame:legalFrame];
190 } 207 }
191 208
192 NSRect backgroundFrame = [backgroundView_ frame]; 209 [[self window] center];
193 backgroundFrame.origin.y += legalShift - updateShift;
194 [backgroundView_ setFrame:backgroundFrame];
195
196 NSSize windowDelta = NSMakeSize(0.0, legalShift - updateShift);
197
198 [GTMUILocalizerAndLayoutTweaker
199 resizeWindowWithoutAutoResizingSubViews:[self window]
200 delta:windowDelta];
201 } 210 }
202 211
203 - (void)windowWillClose:(NSNotification*)notification { 212 - (void)windowWillClose:(NSNotification*)notification {
204 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; 213 NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
205 [center postNotificationName:kUserClosedAboutNotification object:self]; 214 [center postNotificationName:kUserClosedAboutNotification object:self];
206 } 215 }
207 216
217 - (void)adjustUpdateUIVisibility {
218 bool allowUpdate;
219 bool allowPromotion;
220
221 KeystoneGlue* keystoneGlue = [KeystoneGlue defaultKeystoneGlue];
222 if (keystoneGlue && ![keystoneGlue isOnReadOnlyFilesystem]) {
223 AutoupdateStatus recentStatus = [keystoneGlue recentStatus];
224 if (recentStatus == kAutoupdateRegistering ||
225 recentStatus == kAutoupdateRegisterFailed ||
226 recentStatus == kAutoupdatePromoted) {
227 // Show the update block while registering so that there's a progress
228 // spinner, and if registration failed so that there's an error message.
229 // Show it following a promotion because updates should be possible
230 // after promotion successfully completes.
231 allowUpdate = true;
232
233 // Promotion isn't possible at this point.
234 allowPromotion = false;
235 } else if (recentStatus == kAutoupdatePromoteFailed) {
236 // TODO(mark): Add kAutoupdatePromoting to this block. KSRegistration
237 // currently handles the promotion synchronously, meaning that the main
238 // thread's loop doesn't spin, meaning that animations and other updates
239 // to the window won't occur until KSRegistration is done with
240 // promotion. This looks laggy and bad and probably qualifies as
241 // "jank." For now, there just won't be any visual feedback while
242 // promotion is in progress, but it should complete (or fail) very
243 // quickly. http://b/2290009.
244 //
245 // Also see the TODO for kAutoupdatePromoting in -updateStatus:version:.
246 //
247 // Show the update block so that there's some visual feedback that
248 // promotion is under way or that it's failed. Show the promotion block
249 // because the user either just clicked that button or because the user
250 // should be able to click it again.
251 allowUpdate = true;
252 allowPromotion = true;
253 } else {
254 // Show the update block only if a promotion is not absolutely required.
255 allowUpdate = ![keystoneGlue needsPromotion];
256
257 // Show the promotion block if promotion is a possibility.
258 allowPromotion = [keystoneGlue wantsPromotion];
259 }
260 } else {
261 // There is no glue, or the application is on a read-only filesystem.
262 // Updates and promotions are impossible.
263 allowUpdate = false;
264 allowPromotion = false;
265 }
266
267 [self setAllowsUpdate:allowUpdate allowsPromotion:allowPromotion];
268 }
269
270 - (void)setAllowsUpdate:(bool)update allowsPromotion:(bool)promotion {
271 bool oldUpdate = ![updateBlock_ isHidden];
272 bool oldPromotion = ![promotionBlock_ isHidden];
273
274 if (promotion == oldPromotion && update == oldUpdate) {
275 return;
276 }
277
278 NSRect updateFrame = [updateBlock_ frame];
279 NSRect promotionFrame = [promotionBlock_ frame];
280
281 // This routine assumes no space between the update and promotion blocks.
282 DCHECK_EQ(NSMinY(updateFrame), NSMaxY(promotionFrame));
283
284 bool promotionOnly = !update && promotion;
285 bool oldPromotionOnly = !oldUpdate && oldPromotion;
286 if (promotionOnly != oldPromotionOnly) {
287 // The window is transitioning from having a promotion block and no update
288 // block to any other state, or the other way around. Move the promotion
289 // frame up so that its top edge is in the same position as the update
290 // frame's top edge, or move it back down to its original location.
291 promotionFrame.origin.y += (promotionOnly ? 1.0 : -1.0) *
292 NSHeight(updateFrame);
293 }
294
295 CGFloat delta = 0.0;
296
297 if (update != oldUpdate) {
298 [updateBlock_ setHidden:!update];
299 delta += (update ? 1.0 : -1.0) * NSHeight(updateFrame);
300 }
301
302 if (promotion != oldPromotion) {
303 [promotionBlock_ setHidden:!promotion];
304 delta += (promotion ? 1.0 : -1.0) * NSHeight(promotionFrame);
305 }
306
307 NSRect legalFrame = [legalBlock_ frame];
308
309 bool updateOrPromotion = update || promotion;
310 bool oldUpdateOrPromotion = oldUpdate || oldPromotion;
311 if (updateOrPromotion != oldUpdateOrPromotion) {
312 // The window is transitioning from having an update or promotion block or
313 // both to not having either, or the other way around. Adjust delta to
314 // account for the space between the legal block and the update or
315 // promotion block. When the update and promotion blocks are not visible,
316 // this extra spacing is not used.
317 delta += (updateOrPromotion ? 1.0 : -1.0) *
318 (NSMinY(legalFrame) - NSMaxY(updateFrame));
319 }
320
321 // The promotion frame may have changed even if delta is 0, so always reset
322 // its frame.
323 promotionFrame.origin.y += delta;
324 [promotionBlock_ setFrame:promotionFrame];
325
326 if (delta) {
327 updateFrame.origin.y += delta;
328 [updateBlock_ setFrame:updateFrame];
329
330 legalFrame.origin.y += delta;
331 [legalBlock_ setFrame:legalFrame];
332
333 NSRect backgroundFrame = [backgroundView_ frame];
334 backgroundFrame.origin.y += delta;
335 [backgroundView_ setFrame:backgroundFrame];
336
337 // GTMUILocalizerAndLayoutTweaker resizes the window without any
338 // opportunity for animation. In order to animate, disable window
339 // updates, save the current frame, let GTMUILocalizerAndLayoutTweaker do
340 // its thing, save the desired frame, restore the original frame, and then
341 // animate.
342 NSWindow* window = [self window];
343 [window disableScreenUpdatesUntilFlush];
344
345 NSRect oldFrame = [window frame];
346
347 // GTMUILocalizerAndLayoutTweaker applies its delta to the window's
348 // current size (like oldFrame.size), but oldFrame isn't trustworthy if
349 // an animation is in progress. Set the window's frame to
350 // intermediateFrame, which is a frame of the size that an existing
351 // animation is animating to, so that GTM can apply the delta to the right
352 // size.
353 NSRect intermediateFrame = oldFrame;
354 intermediateFrame.origin.y -= intermediateFrame.size.height - windowHeight_;
355 intermediateFrame.size.height = windowHeight_;
356 [window setFrame:intermediateFrame display:NO];
357
358 NSSize windowDelta = NSMakeSize(0.0, delta);
359 [GTMUILocalizerAndLayoutTweaker
360 resizeWindowWithoutAutoResizingSubViews:window
361 delta:windowDelta];
362 [window setFrameTopLeftPoint:NSMakePoint(NSMinX(intermediateFrame),
363 NSMaxY(intermediateFrame))];
364 NSRect newFrame = [window frame];
365
366 windowHeight_ += delta;
367
368 if (![[self window] isVisible]) {
369 // Don't animate if the window isn't on screen yet.
370 [window setFrame:newFrame display:NO];
371 } else {
372 [window setFrame:oldFrame display:NO];
373 [window setFrame:newFrame display:YES animate:YES];
374 }
375 }
376 }
377
208 - (void)setUpdateThrobberMessage:(NSString*)message { 378 - (void)setUpdateThrobberMessage:(NSString*)message {
209 [updateStatusIndicator_ setHidden:YES]; 379 [updateStatusIndicator_ setHidden:YES];
210 380
211 [spinner_ setHidden:NO]; 381 [spinner_ setHidden:NO];
212 [spinner_ startAnimation:self]; 382 [spinner_ startAnimation:self];
213 383
214 [updateText_ setStringValue:message]; 384 [updateText_ setStringValue:message];
215 } 385 }
216 386
217 - (void)setUpdateImage:(int)imageID message:(NSString*)message { 387 - (void)setUpdateImage:(int)imageID message:(NSString*)message {
(...skipping 14 matching lines...) Expand all
232 402
233 // Immediately, kAutoupdateStatusNotification will be posted, and 403 // Immediately, kAutoupdateStatusNotification will be posted, and
234 // -updateStatus: will be called with status kAutoupdateChecking. 404 // -updateStatus: will be called with status kAutoupdateChecking.
235 // 405 //
236 // Upon completion, kAutoupdateStatusNotification will be posted, and 406 // Upon completion, kAutoupdateStatusNotification will be posted, and
237 // -updateStatus: will be called with a status indicating the result of the 407 // -updateStatus: will be called with a status indicating the result of the
238 // check. 408 // check.
239 } 409 }
240 410
241 - (IBAction)updateNow:(id)sender { 411 - (IBAction)updateNow:(id)sender {
242 updateTriggered_ = YES;
243
244 [[KeystoneGlue defaultKeystoneGlue] installUpdate]; 412 [[KeystoneGlue defaultKeystoneGlue] installUpdate];
245 413
246 // Immediately, kAutoupdateStatusNotification will be posted, and 414 // Immediately, kAutoupdateStatusNotification will be posted, and
247 // -updateStatus: will be called with status kAutoupdateInstalling. 415 // -updateStatus: will be called with status kAutoupdateInstalling.
248 // 416 //
249 // Upon completion, kAutoupdateStatusNotification will be posted, and 417 // Upon completion, kAutoupdateStatusNotification will be posted, and
250 // -updateStatus: will be called with a status indicating the result of the 418 // -updateStatus: will be called with a status indicating the result of the
251 // installation attempt. 419 // installation attempt.
252 } 420 }
253 421
422 - (IBAction)promoteUpdater:(id)sender {
423 [[KeystoneGlue defaultKeystoneGlue] promoteTicket];
424
425 // Immediately, kAutoupdateStatusNotification will be posted, and
426 // -updateStatus: will be called with status kAutoupdatePromoting.
427 //
428 // Upon completion, kAutoupdateStatusNotification will be posted, and
429 // -updateStatus: will be called with a status indicating a result of the
430 // installation attempt.
431 //
432 // If the promotion was successful, KeystoneGlue will re-register the ticket
433 // and -updateStatus: will be called again indicating first that
434 // registration is in progress and subsequently that it has completed.
435 }
436
254 - (void)updateStatus:(NSNotification*)notification { 437 - (void)updateStatus:(NSNotification*)notification {
255 recentShownInstallFailedStatus = NO; 438 recentShownUserActionFailedStatus = NO;
256 439
257 NSDictionary* dictionary = [notification userInfo]; 440 NSDictionary* dictionary = [notification userInfo];
258 AutoupdateStatus status = static_cast<AutoupdateStatus>( 441 AutoupdateStatus status = static_cast<AutoupdateStatus>(
259 [[dictionary objectForKey:kAutoupdateStatusStatus] intValue]); 442 [[dictionary objectForKey:kAutoupdateStatusStatus] intValue]);
260 443
261 // Don't assume |version| is a real string. It may be nil. 444 // Don't assume |version| is a real string. It may be nil.
262 NSString* version = [dictionary objectForKey:kAutoupdateStatusVersion]; 445 NSString* version = [dictionary objectForKey:kAutoupdateStatusVersion];
263 446
447 bool updateMessage = true;
264 bool throbber = false; 448 bool throbber = false;
265 int imageID = 0; 449 int imageID = 0;
266 NSString* message; 450 NSString* message;
451 bool enableUpdateButton = false;
452 bool enablePromoteButton = true;
267 453
268 switch (status) { 454 switch (status) {
455 case kAutoupdateRegistering:
456 // When registering, use the "checking" message. The check will be
457 // launched if appropriate immediately after registration.
458 throbber = true;
459 message = l10n_util::GetNSStringWithFixup(IDS_UPGRADE_CHECK_STARTED);
460 enablePromoteButton = false;
461
462 break;
463
464 case kAutoupdateRegistered:
465 // Once registered, the ability to update and promote is known.
466 [self adjustUpdateUIVisibility];
467
468 if (![updateBlock_ isHidden]) {
469 // If registration completes while the window is visible, go straight
470 // into an update check. Return immediately, this routine will be
471 // re-entered shortly with kAutoupdateChecking.
472 [self checkForUpdate];
473 return;
474 }
475
476 // Nothing actually failed, but updates aren't possible. The throbber
477 // and message are hidden, but they'll be reset to these dummy values
478 // just to get the throbber to stop spinning if it's running.
479 imageID = IDR_UPDATE_FAIL;
480 message = l10n_util::GetNSStringFWithFixup(IDS_UPGRADE_ERROR,
481 IntToString16(status));
482
483 break;
484
269 case kAutoupdateChecking: 485 case kAutoupdateChecking:
270 throbber = true; 486 throbber = true;
271 message = l10n_util::GetNSStringWithFixup(IDS_UPGRADE_CHECK_STARTED); 487 message = l10n_util::GetNSStringWithFixup(IDS_UPGRADE_CHECK_STARTED);
488 enablePromoteButton = false;
272 489
273 break; 490 break;
274 491
275 case kAutoupdateCurrent: 492 case kAutoupdateCurrent:
276 imageID = IDR_UPDATE_UPTODATE; 493 imageID = IDR_UPDATE_UPTODATE;
277 message = l10n_util::GetNSStringFWithFixup( 494 message = l10n_util::GetNSStringFWithFixup(
278 IDS_UPGRADE_ALREADY_UP_TO_DATE, 495 IDS_UPGRADE_ALREADY_UP_TO_DATE,
279 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), 496 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
280 base::SysNSStringToUTF16(version)); 497 base::SysNSStringToUTF16(version));
281 498
282 break; 499 break;
283 500
284 case kAutoupdateAvailable: 501 case kAutoupdateAvailable:
285 imageID = IDR_UPDATE_AVAILABLE; 502 imageID = IDR_UPDATE_AVAILABLE;
286 message = l10n_util::GetNSStringFWithFixup( 503 message = l10n_util::GetNSStringFWithFixup(
287 IDS_UPGRADE_AVAILABLE, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); 504 IDS_UPGRADE_AVAILABLE, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
288 [updateNowButton_ setEnabled:YES]; 505 enableUpdateButton = true;
289 506
290 break; 507 break;
291 508
292 case kAutoupdateInstalling: 509 case kAutoupdateInstalling:
293 // Don't let anyone click "Update Now" twice.
294 [updateNowButton_ setEnabled:NO];
295
296 throbber = true; 510 throbber = true;
297 message = l10n_util::GetNSStringWithFixup(IDS_UPGRADE_STARTED); 511 message = l10n_util::GetNSStringWithFixup(IDS_UPGRADE_STARTED);
512 enablePromoteButton = false;
298 513
299 break; 514 break;
300 515
301 case kAutoupdateInstalled: 516 case kAutoupdateInstalled:
302 { 517 {
303 imageID = IDR_UPDATE_UPTODATE; 518 imageID = IDR_UPDATE_UPTODATE;
304 string16 productName = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); 519 string16 productName = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
305 if (version) { 520 if (version) {
306 message = l10n_util::GetNSStringFWithFixup( 521 message = l10n_util::GetNSStringFWithFixup(
307 IDS_UPGRADE_SUCCESSFUL, 522 IDS_UPGRADE_SUCCESSFUL,
308 productName, 523 productName,
309 base::SysNSStringToUTF16(version)); 524 base::SysNSStringToUTF16(version));
310 } else { 525 } else {
311 message = l10n_util::GetNSStringFWithFixup( 526 message = l10n_util::GetNSStringFWithFixup(
312 IDS_UPGRADE_SUCCESSFUL_NOVERSION, productName); 527 IDS_UPGRADE_SUCCESSFUL_NOVERSION, productName);
313 } 528 }
314 529
315 // TODO(mark): Turn the button in the dialog into a restart button 530 // TODO(mark): Turn the button in the dialog into a restart button
316 // instead of springing this sheet or dialog. 531 // instead of springing this sheet or dialog.
317 NSWindow* window = [self window]; 532 NSWindow* window = [self window];
318 NSWindow* restartDialogParent = [window isVisible] ? window : nil; 533 NSWindow* restartDialogParent = [window isVisible] ? window : nil;
319 restart_browser::RequestRestart(restartDialogParent); 534 restart_browser::RequestRestart(restartDialogParent);
320 } 535 }
321 536
322 break; 537 break;
323 538
324 case kAutoupdateInstallFailed: 539 case kAutoupdatePromoting:
325 recentShownInstallFailedStatus = YES; 540 #if 1
541 // TODO(mark): See the TODO in -adjustUpdateUIVisibility for an
542 // explanation of why nothing can be done here at the moment. When
543 // KSRegistration handles promotion asynchronously, this dummy block can
544 // be replaced with the #else block. For now, just leave the messaging
545 // alone. http://b/2290009.
546 updateMessage = false;
547 #else
548 // The visibility may be changing.
549 [self adjustUpdateUIVisibility];
326 550
327 // Allow another chance. 551 // This is not a terminal state, and kAutoupdatePromoted or
328 [updateNowButton_ setEnabled:YES]; 552 // kAutoupdatePromoteFailed will follow. Use the throbber and
553 // "checking" message so that it looks like something's happening.
554 throbber = true;
555 message = l10n_util::GetNSStringWithFixup(IDS_UPGRADE_CHECK_STARTED);
556 #endif
329 557
330 // Fall through. 558 enablePromoteButton = false;
559
560 break;
561
562 case kAutoupdatePromoted:
563 // The visibility may be changing.
564 [self adjustUpdateUIVisibility];
565
566 if (![updateBlock_ isHidden]) {
567 // If promotion completes while the window is visible, go straight
568 // into an update check. Return immediately, this routine will be
569 // re-entered shortly with kAutoupdateChecking.
570 [self checkForUpdate];
571 return;
572 }
573
574 // Nothing actually failed, but updates aren't possible. The throbber
575 // and message are hidden, but they'll be reset to these dummy values
576 // just to get the throbber to stop spinning if it's running.
577 imageID = IDR_UPDATE_FAIL;
578 message = l10n_util::GetNSStringFWithFixup(IDS_UPGRADE_ERROR,
579 IntToString16(status));
580
581 break;
582
583 case kAutoupdateRegisterFailed:
584 imageID = IDR_UPDATE_FAIL;
585 message = l10n_util::GetNSStringFWithFixup(IDS_UPGRADE_ERROR,
586 IntToString16(status));
587 enablePromoteButton = false;
588
589 break;
331 590
332 case kAutoupdateCheckFailed: 591 case kAutoupdateCheckFailed:
333 imageID = IDR_UPDATE_FAIL; 592 imageID = IDR_UPDATE_FAIL;
334 message = l10n_util::GetNSStringFWithFixup(IDS_UPGRADE_ERROR, 593 message = l10n_util::GetNSStringFWithFixup(IDS_UPGRADE_ERROR,
335 IntToString16(status)); 594 IntToString16(status));
595
596 break;
597
598 case kAutoupdateInstallFailed:
599 recentShownUserActionFailedStatus = YES;
600
601 imageID = IDR_UPDATE_FAIL;
602 message = l10n_util::GetNSStringFWithFixup(IDS_UPGRADE_ERROR,
603 IntToString16(status));
604
605 // Allow another chance.
606 enableUpdateButton = true;
607
608 break;
609
610 case kAutoupdatePromoteFailed:
611 recentShownUserActionFailedStatus = YES;
612
613 imageID = IDR_UPDATE_FAIL;
614 message = l10n_util::GetNSStringFWithFixup(IDS_UPGRADE_ERROR,
615 IntToString16(status));
336 616
337 break; 617 break;
338 618
339 default: 619 default:
340 NOTREACHED(); 620 NOTREACHED();
621
341 return; 622 return;
342 } 623 }
343 624
344 if (throbber) { 625 if (updateMessage) {
345 [self setUpdateThrobberMessage:message]; 626 if (throbber) {
346 } else { 627 [self setUpdateThrobberMessage:message];
347 DCHECK_NE(imageID, 0); 628 } else {
348 [self setUpdateImage:imageID message:message]; 629 DCHECK_NE(imageID, 0);
630 [self setUpdateImage:imageID message:message];
631 }
349 } 632 }
633
634 // Note that these buttons may be hidden depending on what
635 // -adjustUpdateUIVisibility did. Their enabled/disabled status doesn't
636 // necessarily have anything to do with their visibility.
637 [updateNowButton_ setEnabled:enableUpdateButton];
638 [promoteButton_ setEnabled:enablePromoteButton];
350 } 639 }
351 640
352 - (BOOL)textView:(NSTextView *)aTextView 641 - (BOOL)textView:(NSTextView *)aTextView
353 clickedOnLink:(id)link 642 clickedOnLink:(id)link
354 atIndex:(NSUInteger)charIndex { 643 atIndex:(NSUInteger)charIndex {
355 // We always create a new window, so there's no need to try to re-use 644 // We always create a new window, so there's no need to try to re-use
356 // an existing one just to pass in the NEW_WINDOW disposition. 645 // an existing one just to pass in the NEW_WINDOW disposition.
357 Browser* browser = Browser::Create(profile_); 646 Browser* browser = Browser::Create(profile_);
358 if (browser) { 647 if (browser) {
359 browser->OpenURL(GURL([link UTF8String]), GURL(), NEW_WINDOW, 648 browser->OpenURL(GURL([link UTF8String]), GURL(), NEW_WINDOW,
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 NSRange string_range = NSMakeRange(0, [legal_block length]); 776 NSRange string_range = NSMakeRange(0, [legal_block length]);
488 [legal_block addAttribute:NSFontAttributeName 777 [legal_block addAttribute:NSFontAttributeName
489 value:[NSFont labelFontOfSize:11] 778 value:[NSFont labelFontOfSize:11]
490 range:string_range]; 779 range:string_range];
491 780
492 [legal_block endEditing]; 781 [legal_block endEditing];
493 return legal_block; 782 return legal_block;
494 } 783 }
495 784
496 @end // @implementation AboutWindowController 785 @end // @implementation AboutWindowController
OLDNEW
« no previous file with comments | « chrome/browser/cocoa/about_window_controller.h ('k') | chrome/browser/cocoa/about_window_controller_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698