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

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

Issue 339010: Make the About box display existing pending operations instead of firing off a new update check (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month 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
« no previous file with comments | « chrome/app/keystone_glue.mm ('k') | chrome/browser/cocoa/about_window_controller_unittest.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include "app/l10n_util_mac.h" 5 #include "app/l10n_util_mac.h"
6 #include "app/resource_bundle.h" 6 #include "app/resource_bundle.h"
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/mac_util.h" 8 #include "base/mac_util.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "base/sys_string_conversions.h" 10 #include "base/sys_string_conversions.h"
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 NSRect oldLegalRect = [legalBlock_ frame]; 134 NSRect oldLegalRect = [legalBlock_ frame];
135 [legalText_ sizeToFit]; 135 [legalText_ sizeToFit];
136 NSRect newRect = oldLegalRect; 136 NSRect newRect = oldLegalRect;
137 newRect.size.height = [legalText_ frame].size.height; 137 newRect.size.height = [legalText_ frame].size.height;
138 [legalBlock_ setFrame:newRect]; 138 [legalBlock_ setFrame:newRect];
139 CGFloat legalShift = newRect.size.height - oldLegalRect.size.height; 139 CGFloat legalShift = newRect.size.height - oldLegalRect.size.height;
140 140
141 KeystoneGlue* keystoneGlue = [KeystoneGlue defaultKeystoneGlue]; 141 KeystoneGlue* keystoneGlue = [KeystoneGlue defaultKeystoneGlue];
142 CGFloat updateShift; 142 CGFloat updateShift;
143 if (keystoneGlue) { 143 if (keystoneGlue) {
144 NSNotification* recentNotification = [keystoneGlue recentNotification]; 144 if ([keystoneGlue asyncOperationPending] ||
145 NSDictionary* recentDictionary = [recentNotification userInfo]; 145 [keystoneGlue recentStatus] == kAutoupdateInstallFailed) {
146 AutoupdateStatus recentStatus = static_cast<AutoupdateStatus>( 146 // If an asynchronous update operation is currently pending, such as a
147 [[recentDictionary objectForKey:kAutoupdateStatusStatus] intValue]); 147 // check for updates or an update installation attempt, set the status
148 if (recentStatus == kAutoupdateInstallFailed) { 148 // up correspondingly without launching a new update check.
149 // A previous update attempt was unsuccessful, but no About box was 149 //
150 // around to report status. Use the saved notification to set up the 150 // If a previous update attempt was unsuccessful but no About box was
151 // About box with the error message, and to allow another chance to 151 // around to report the error, show it now, and allow another chance to
152 // install the update. 152 // install the update.
153 [self updateStatus:recentNotification]; 153 [self updateStatus:[keystoneGlue recentNotification]];
154 } else { 154 } else {
155 // Launch a new update check, even if one was already completed, because
156 // a new update may be available or a new update may have been installed
157 // in the background since the last time an About box was displayed.
155 [self checkForUpdate]; 158 [self checkForUpdate];
156 } 159 }
157 160
158 updateShift = 0.0; 161 updateShift = 0.0;
159 } else { 162 } else {
160 // Hide all the update UI 163 // Hide all the update UI
161 [updateBlock_ setHidden:YES]; 164 [updateBlock_ setHidden:YES];
162 165
163 // Figure out the amount being removed by taking out the update block 166 // Figure out the amount being removed by taking out the update block
164 // and its spacing. 167 // and its spacing.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 204 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
202 NSImage* statusImage = rb.GetNSImageNamed(imageID); 205 NSImage* statusImage = rb.GetNSImageNamed(imageID);
203 DCHECK(statusImage); 206 DCHECK(statusImage);
204 [updateStatusIndicator_ setImage:statusImage]; 207 [updateStatusIndicator_ setImage:statusImage];
205 [updateStatusIndicator_ setHidden:NO]; 208 [updateStatusIndicator_ setHidden:NO];
206 209
207 [updateText_ setStringValue:message]; 210 [updateText_ setStringValue:message];
208 } 211 }
209 212
210 - (void)checkForUpdate { 213 - (void)checkForUpdate {
211 [self setUpdateThrobberMessage:
212 l10n_util::GetNSStringWithFixup(IDS_UPGRADE_CHECK_STARTED)];
213 [[KeystoneGlue defaultKeystoneGlue] checkForUpdate]; 214 [[KeystoneGlue defaultKeystoneGlue] checkForUpdate];
214 215
216 // Immediately, kAutoupdateStatusNotification will be posted, and
217 // -updateStatus: will be called with status kAutoupdateChecking.
218 //
215 // Upon completion, kAutoupdateStatusNotification will be posted, and 219 // Upon completion, kAutoupdateStatusNotification will be posted, and
216 // -updateStatus: will be called. 220 // -updateStatus: will be called with a status indicating the result of the
221 // check.
217 } 222 }
218 223
219 - (IBAction)updateNow:(id)sender { 224 - (IBAction)updateNow:(id)sender {
220 updateTriggered_ = YES; 225 updateTriggered_ = YES;
221 226
222 // Don't let someone click "Update Now" twice!
223 [updateNowButton_ setEnabled:NO];
224 [self setUpdateThrobberMessage:
225 l10n_util::GetNSStringWithFixup(IDS_UPGRADE_STARTED)];
226 [[KeystoneGlue defaultKeystoneGlue] installUpdate]; 227 [[KeystoneGlue defaultKeystoneGlue] installUpdate];
227 228
229 // Immediately, kAutoupdateStatusNotification will be posted, and
230 // -updateStatus: will be called with status kAutoupdateInstalling.
231 //
228 // Upon completion, kAutoupdateStatusNotification will be posted, and 232 // Upon completion, kAutoupdateStatusNotification will be posted, and
229 // -updateStatus: will be called. 233 // -updateStatus: will be called with a status indicating the result of the
234 // installation attempt.
230 } 235 }
231 236
232 - (void)updateStatus:(NSNotification*)notification { 237 - (void)updateStatus:(NSNotification*)notification {
233 NSDictionary* dictionary = [notification userInfo]; 238 NSDictionary* dictionary = [notification userInfo];
234 AutoupdateStatus status = static_cast<AutoupdateStatus>( 239 AutoupdateStatus status = static_cast<AutoupdateStatus>(
235 [[dictionary objectForKey:kAutoupdateStatusStatus] intValue]); 240 [[dictionary objectForKey:kAutoupdateStatusStatus] intValue]);
236 241
237 // Don't assume |version| is a real string. It may be nil. 242 // Don't assume |version| is a real string. It may be nil.
238 NSString* version = [dictionary objectForKey:kAutoupdateStatusVersion]; 243 NSString* version = [dictionary objectForKey:kAutoupdateStatusVersion];
239 244
240 int imageID; 245 bool throbber = false;
246 int imageID = 0;
241 NSString* message; 247 NSString* message;
242 248
243 switch (status) { 249 switch (status) {
250 case kAutoupdateChecking:
251 throbber = true;
252 message = l10n_util::GetNSStringWithFixup(IDS_UPGRADE_CHECK_STARTED);
253
254 break;
255
244 case kAutoupdateCurrent: 256 case kAutoupdateCurrent:
245 imageID = IDR_UPDATE_UPTODATE; 257 imageID = IDR_UPDATE_UPTODATE;
246 message = l10n_util::GetNSStringFWithFixup( 258 message = l10n_util::GetNSStringFWithFixup(
247 IDS_UPGRADE_ALREADY_UP_TO_DATE, 259 IDS_UPGRADE_ALREADY_UP_TO_DATE,
248 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), 260 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
249 base::SysNSStringToUTF16(version)); 261 base::SysNSStringToUTF16(version));
250 262
251 break; 263 break;
252 264
253 case kAutoupdateAvailable: 265 case kAutoupdateAvailable:
254 imageID = IDR_UPDATE_AVAILABLE; 266 imageID = IDR_UPDATE_AVAILABLE;
255 message = l10n_util::GetNSStringFWithFixup( 267 message = l10n_util::GetNSStringFWithFixup(
256 IDS_UPGRADE_AVAILABLE, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); 268 IDS_UPGRADE_AVAILABLE, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
257 [updateNowButton_ setEnabled:YES]; 269 [updateNowButton_ setEnabled:YES];
258 270
259 break; 271 break;
260 272
273 case kAutoupdateInstalling:
274 // Don't let someone click "Update Now" twice.
275 [updateNowButton_ setEnabled:NO];
276
277 throbber = true;
278 message = l10n_util::GetNSStringWithFixup(IDS_UPGRADE_STARTED);
279
280 break;
281
261 case kAutoupdateInstalled: 282 case kAutoupdateInstalled:
262 { 283 {
263 imageID = IDR_UPDATE_UPTODATE; 284 imageID = IDR_UPDATE_UPTODATE;
264 string16 productName = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); 285 string16 productName = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
265 if (version) { 286 if (version) {
266 message = l10n_util::GetNSStringFWithFixup( 287 message = l10n_util::GetNSStringFWithFixup(
267 IDS_UPGRADE_SUCCESSFUL, 288 IDS_UPGRADE_SUCCESSFUL,
268 productName, 289 productName,
269 base::SysNSStringToUTF16(version)); 290 base::SysNSStringToUTF16(version));
270 } else { 291 } else {
271 message = l10n_util::GetNSStringFWithFixup( 292 message = l10n_util::GetNSStringFWithFixup(
272 IDS_UPGRADE_SUCCESSFUL_NOVERSION, productName); 293 IDS_UPGRADE_SUCCESSFUL_NOVERSION, productName);
273 } 294 }
274 295
275 // TODO(mark): Turn the button in the dialog into a restart button 296 // TODO(mark): Turn the button in the dialog into a restart button
276 // instead of springing this sheet or dialog. 297 // instead of springing this sheet or dialog.
277 NSWindow* window = [self window]; 298 NSWindow* window = [self window];
278 NSWindow* restartDialogParent = [window isVisible] ? window : nil; 299 NSWindow* restartDialogParent = [window isVisible] ? window : nil;
279 restart_browser::RequestRestart(restartDialogParent); 300 restart_browser::RequestRestart(restartDialogParent);
280 } 301 }
281 302
282 break; 303 break;
283 304
284 case kAutoupdateInstallFailed: 305 case kAutoupdateInstallFailed:
306 // Since the installation failure will now be displayed in an About box,
307 // the saved state can be cleared. If the About box is closed and then
308 // reopened, this will let it start out with a clean slate and not be
309 // affected by past failures.
310 [[KeystoneGlue defaultKeystoneGlue] clearRecentNotification];
311
285 // Allow another chance. 312 // Allow another chance.
286 [updateNowButton_ setEnabled:YES]; 313 [updateNowButton_ setEnabled:YES];
287 314
288 // Fall through. 315 // Fall through.
289 316
290 case kAutoupdateCheckFailed: 317 case kAutoupdateCheckFailed:
291 // TODO(mark): Keystone doesn't currently indicate when a check for 318 // TODO(mark): Keystone doesn't currently indicate when a check for
292 // updates failed. Fix that. 319 // updates failed. Fix that.
293 imageID = IDR_UPDATE_FAIL; 320 imageID = IDR_UPDATE_FAIL;
294 message = l10n_util::GetNSStringFWithFixup(IDS_UPGRADE_ERROR, 321 message = l10n_util::GetNSStringFWithFixup(IDS_UPGRADE_ERROR,
295 IntToString16(status)); 322 IntToString16(status));
296 323
297 break; 324 break;
298 325
299 default: 326 default:
300 NOTREACHED(); 327 NOTREACHED();
301 return; 328 return;
302 } 329 }
303 330
304 [self setUpdateImage:imageID message:message]; 331 if (throbber) {
305 332 [self setUpdateThrobberMessage:message];
306 // Since the update status is now displayed in an About box, the saved state 333 } else {
307 // can be cleared. If the About box is closed and then reopened, this will 334 DCHECK_NE(imageID, 0);
308 // let it start out with a clean slate and not be affected by past failures. 335 [self setUpdateImage:imageID message:message];
309 [[KeystoneGlue defaultKeystoneGlue] clearRecentNotification]; 336 }
310 } 337 }
311 338
312 - (BOOL)textView:(NSTextView *)aTextView 339 - (BOOL)textView:(NSTextView *)aTextView
313 clickedOnLink:(id)link 340 clickedOnLink:(id)link
314 atIndex:(NSUInteger)charIndex { 341 atIndex:(NSUInteger)charIndex {
315 // We always create a new window, so there's no need to try to re-use 342 // We always create a new window, so there's no need to try to re-use
316 // an existing one just to pass in the NEW_WINDOW disposition. 343 // an existing one just to pass in the NEW_WINDOW disposition.
317 Browser* browser = Browser::Create(profile_); 344 Browser* browser = Browser::Create(profile_);
318 if (browser) { 345 if (browser) {
319 browser->OpenURL(GURL([link UTF8String]), GURL(), NEW_WINDOW, 346 browser->OpenURL(GURL([link UTF8String]), GURL(), NEW_WINDOW,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 388
362 // Now fetch the license string and deal with the markers 389 // Now fetch the license string and deal with the markers
363 390
364 NSString* license = 391 NSString* license =
365 l10n_util::GetNSStringWithFixup(IDS_ABOUT_VERSION_LICENSE); 392 l10n_util::GetNSStringWithFixup(IDS_ABOUT_VERSION_LICENSE);
366 393
367 NSRange begin_chr = [license rangeOfString:kBeginLinkChr]; 394 NSRange begin_chr = [license rangeOfString:kBeginLinkChr];
368 NSRange begin_oss = [license rangeOfString:kBeginLinkOss]; 395 NSRange begin_oss = [license rangeOfString:kBeginLinkOss];
369 NSRange end_chr = [license rangeOfString:kEndLinkChr]; 396 NSRange end_chr = [license rangeOfString:kEndLinkChr];
370 NSRange end_oss = [license rangeOfString:kEndLinkOss]; 397 NSRange end_oss = [license rangeOfString:kEndLinkOss];
371 DCHECK(begin_chr.location != NSNotFound); 398 DCHECK_NE(begin_chr.location, NSNotFound);
372 DCHECK(begin_oss.location != NSNotFound); 399 DCHECK_NE(begin_oss.location, NSNotFound);
373 DCHECK(end_chr.location != NSNotFound); 400 DCHECK_NE(end_chr.location, NSNotFound);
374 DCHECK(end_oss.location != NSNotFound); 401 DCHECK_NE(end_oss.location, NSNotFound);
375 402
376 // We don't know which link will come first, so we have to deal with things 403 // We don't know which link will come first, so we have to deal with things
377 // like this: 404 // like this:
378 // [text][begin][text][end][text][start][text][end][text] 405 // [text][begin][text][end][text][start][text][end][text]
379 406
380 bool chromium_link_first = begin_chr.location < begin_oss.location; 407 bool chromium_link_first = begin_chr.location < begin_oss.location;
381 408
382 NSRange* begin1 = &begin_chr; 409 NSRange* begin1 = &begin_chr;
383 NSRange* begin2 = &begin_oss; 410 NSRange* begin2 = &begin_oss;
384 NSRange* end1 = &end_chr; 411 NSRange* end1 = &end_chr;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 NSRange string_range = NSMakeRange(0, [legal_block length]); 474 NSRange string_range = NSMakeRange(0, [legal_block length]);
448 [legal_block addAttribute:NSFontAttributeName 475 [legal_block addAttribute:NSFontAttributeName
449 value:[NSFont labelFontOfSize:11] 476 value:[NSFont labelFontOfSize:11]
450 range:string_range]; 477 range:string_range];
451 478
452 [legal_block endEditing]; 479 [legal_block endEditing];
453 return legal_block; 480 return legal_block;
454 } 481 }
455 482
456 @end // @implementation AboutWindowController 483 @end // @implementation AboutWindowController
OLDNEW
« no previous file with comments | « chrome/app/keystone_glue.mm ('k') | chrome/browser/cocoa/about_window_controller_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698