| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/ui/cocoa/extensions/extension_installed_bubble_controlle
r.h" | 5 #import "chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controlle
r.h" |
| 6 | 6 |
| 7 #include "base/i18n/rtl.h" | 7 #include "base/i18n/rtl.h" |
| 8 #include "base/mac/bundle_locations.h" | 8 #include "base/mac/bundle_locations.h" |
| 9 #include "base/mac/mac_util.h" | 9 #include "base/mac/mac_util.h" |
| 10 #include "base/sys_string_conversions.h" | 10 #include "base/sys_string_conversions.h" |
| 11 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
| 12 #include "chrome/browser/extensions/bundle_installer.h" |
| 12 #include "chrome/browser/ui/browser.h" | 13 #include "chrome/browser/ui/browser.h" |
| 13 #include "chrome/browser/ui/browser_window.h" | 14 #include "chrome/browser/ui/browser_window.h" |
| 14 #include "chrome/browser/ui/cocoa/browser_window_cocoa.h" | 15 #include "chrome/browser/ui/cocoa/browser_window_cocoa.h" |
| 15 #include "chrome/browser/ui/cocoa/browser_window_controller.h" | 16 #include "chrome/browser/ui/cocoa/browser_window_controller.h" |
| 16 #include "chrome/browser/ui/cocoa/extensions/browser_actions_controller.h" | 17 #include "chrome/browser/ui/cocoa/extensions/browser_actions_controller.h" |
| 17 #include "chrome/browser/ui/cocoa/hover_close_button.h" | 18 #include "chrome/browser/ui/cocoa/hover_close_button.h" |
| 18 #include "chrome/browser/ui/cocoa/info_bubble_view.h" | 19 #include "chrome/browser/ui/cocoa/info_bubble_view.h" |
| 19 #include "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" | 20 #include "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" |
| 20 #include "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" | 21 #include "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" |
| 21 #include "chrome/common/chrome_notification_types.h" | 22 #include "chrome/common/chrome_notification_types.h" |
| 22 #include "chrome/common/extensions/extension.h" | 23 #include "chrome/common/extensions/extension.h" |
| 23 #include "chrome/common/extensions/extension_action.h" | 24 #include "chrome/common/extensions/extension_action.h" |
| 24 #include "content/public/browser/notification_details.h" | 25 #include "content/public/browser/notification_details.h" |
| 25 #include "content/public/browser/notification_registrar.h" | 26 #include "content/public/browser/notification_registrar.h" |
| 26 #include "content/public/browser/notification_source.h" | 27 #include "content/public/browser/notification_source.h" |
| 27 #include "grit/chromium_strings.h" | 28 #include "grit/chromium_strings.h" |
| 28 #include "grit/generated_resources.h" | 29 #include "grit/generated_resources.h" |
| 29 #import "skia/ext/skia_utils_mac.h" | 30 #import "skia/ext/skia_utils_mac.h" |
| 30 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" | 31 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" |
| 31 #include "ui/base/l10n/l10n_util.h" | 32 #include "ui/base/l10n/l10n_util.h" |
| 32 | 33 |
| 33 using content::BrowserThread; | 34 using content::BrowserThread; |
| 35 using extensions::BundleInstaller; |
| 34 | 36 |
| 35 // C++ class that receives EXTENSION_LOADED notifications and proxies them back | 37 // C++ class that receives EXTENSION_LOADED notifications and proxies them back |
| 36 // to |controller|. | 38 // to |controller|. |
| 37 class ExtensionLoadedNotificationObserver | 39 class ExtensionLoadedNotificationObserver |
| 38 : public content::NotificationObserver { | 40 : public content::NotificationObserver { |
| 39 public: | 41 public: |
| 40 ExtensionLoadedNotificationObserver( | 42 ExtensionLoadedNotificationObserver( |
| 41 ExtensionInstalledBubbleController* controller, Profile* profile) | 43 ExtensionInstalledBubbleController* controller, Profile* profile) |
| 42 : controller_(controller) { | 44 : controller_(controller) { |
| 43 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, | 45 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
| (...skipping 29 matching lines...) Expand all Loading... |
| 73 } | 75 } |
| 74 } | 76 } |
| 75 | 77 |
| 76 content::NotificationRegistrar registrar_; | 78 content::NotificationRegistrar registrar_; |
| 77 ExtensionInstalledBubbleController* controller_; // weak, owns us | 79 ExtensionInstalledBubbleController* controller_; // weak, owns us |
| 78 }; | 80 }; |
| 79 | 81 |
| 80 @implementation ExtensionInstalledBubbleController | 82 @implementation ExtensionInstalledBubbleController |
| 81 | 83 |
| 82 @synthesize extension = extension_; | 84 @synthesize extension = extension_; |
| 85 @synthesize bundle = bundle_; |
| 83 @synthesize pageActionRemoved = pageActionRemoved_; // Exposed for unit test. | 86 @synthesize pageActionRemoved = pageActionRemoved_; // Exposed for unit test. |
| 84 | 87 |
| 85 - (id)initWithParentWindow:(NSWindow*)parentWindow | 88 - (id)initWithParentWindow:(NSWindow*)parentWindow |
| 86 extension:(const Extension*)extension | 89 extension:(const Extension*)extension |
| 90 bundle:(const BundleInstaller*)bundle |
| 87 browser:(Browser*)browser | 91 browser:(Browser*)browser |
| 88 icon:(SkBitmap)icon { | 92 icon:(SkBitmap)icon { |
| 89 NSString* nibPath = | 93 NSString* nibName = bundle ? @"ExtensionInstalledBubbleBundle" : |
| 90 [base::mac::FrameworkBundle() pathForResource:@"ExtensionInstalledBubble" | 94 @"ExtensionInstalledBubble"; |
| 91 ofType:@"nib"]; | 95 NSString* nibPath = [base::mac::FrameworkBundle() pathForResource:nibName |
| 96 ofType:@"nib"]; |
| 92 if ((self = [super initWithWindowNibPath:nibPath owner:self])) { | 97 if ((self = [super initWithWindowNibPath:nibPath owner:self])) { |
| 93 DCHECK(parentWindow); | 98 DCHECK(parentWindow); |
| 94 parentWindow_ = parentWindow; | 99 parentWindow_ = parentWindow; |
| 95 DCHECK(extension); | |
| 96 extension_ = extension; | 100 extension_ = extension; |
| 101 bundle_ = bundle; |
| 97 DCHECK(browser); | 102 DCHECK(browser); |
| 98 browser_ = browser; | 103 browser_ = browser; |
| 99 icon_.reset([gfx::SkBitmapToNSImage(icon) retain]); | 104 icon_.reset([gfx::SkBitmapToNSImage(icon) retain]); |
| 100 pageActionRemoved_ = NO; | 105 pageActionRemoved_ = NO; |
| 101 | 106 |
| 102 if (!extension->omnibox_keyword().empty()) { | 107 if (bundle_) { |
| 108 type_ = extension_installed_bubble::kBundle; |
| 109 } else if (!extension->omnibox_keyword().empty()) { |
| 103 type_ = extension_installed_bubble::kOmniboxKeyword; | 110 type_ = extension_installed_bubble::kOmniboxKeyword; |
| 104 } else if (extension->browser_action()) { | 111 } else if (extension->browser_action()) { |
| 105 type_ = extension_installed_bubble::kBrowserAction; | 112 type_ = extension_installed_bubble::kBrowserAction; |
| 106 } else if (extension->page_action() && | 113 } else if (extension->page_action() && |
| 107 !extension->page_action()->default_icon_path().empty()) { | 114 !extension->page_action()->default_icon_path().empty()) { |
| 108 type_ = extension_installed_bubble::kPageAction; | 115 type_ = extension_installed_bubble::kPageAction; |
| 109 } else { | 116 } else { |
| 110 NOTREACHED(); // kGeneric installs handled in the extension_install_ui. | 117 NOTREACHED(); // kGeneric installs handled in the extension_install_ui. |
| 111 } | 118 } |
| 112 | 119 |
| 113 // Start showing window only after extension has fully loaded. | 120 if (type_ == extension_installed_bubble::kBundle) { |
| 114 extensionObserver_.reset(new ExtensionLoadedNotificationObserver( | 121 [self showWindow:self]; |
| 115 self, browser->profile())); | 122 } else { |
| 123 // Start showing window only after extension has fully loaded. |
| 124 extensionObserver_.reset(new ExtensionLoadedNotificationObserver( |
| 125 self, browser->profile())); |
| 126 } |
| 116 | 127 |
| 117 // Watch to see if the parent window closes, and if so, close this one. | 128 // Watch to see if the parent window closes, and if so, close this one. |
| 118 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; | 129 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; |
| 119 [center addObserver:self | 130 [center addObserver:self |
| 120 selector:@selector(parentWindowWillClose:) | 131 selector:@selector(parentWindowWillClose:) |
| 121 name:NSWindowWillCloseNotification | 132 name:NSWindowWillCloseNotification |
| 122 object:parentWindow_]; | 133 object:parentWindow_]; |
| 123 } | 134 } |
| 124 return self; | 135 return self; |
| 125 } | 136 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 // would ordinarily only be displayed on a page of the appropriate type. | 228 // would ordinarily only be displayed on a page of the appropriate type. |
| 218 // We remove this preview when the extension installed bubble closes. | 229 // We remove this preview when the extension installed bubble closes. |
| 219 locationBarView->SetPreviewEnabledPageAction(extension_->page_action(), | 230 locationBarView->SetPreviewEnabledPageAction(extension_->page_action(), |
| 220 true); | 231 true); |
| 221 | 232 |
| 222 // Find the center of the bottom of the page action icon. | 233 // Find the center of the bottom of the page action icon. |
| 223 arrowPoint = | 234 arrowPoint = |
| 224 locationBarView->GetPageActionBubblePoint(extension_->page_action()); | 235 locationBarView->GetPageActionBubblePoint(extension_->page_action()); |
| 225 break; | 236 break; |
| 226 } | 237 } |
| 238 case extension_installed_bubble::kBundle: { |
| 239 NSView* wrenchButton = |
| 240 [[window->cocoa_controller() toolbarController] wrenchButton]; |
| 241 const NSRect bounds = [wrenchButton bounds]; |
| 242 NSPoint anchor = NSMakePoint(NSMidX(bounds), NSMidY(bounds)); |
| 243 arrowPoint = [wrenchButton convertPoint:anchor toView:nil]; |
| 244 break; |
| 245 } |
| 227 default: { | 246 default: { |
| 228 NOTREACHED() << "Generic extension type not allowed in install bubble."; | 247 NOTREACHED() << "Generic extension type not allowed in install bubble."; |
| 229 } | 248 } |
| 230 } | 249 } |
| 231 return arrowPoint; | 250 return arrowPoint; |
| 232 } | 251 } |
| 233 | 252 |
| 234 // We want this to be a child of a browser window. addChildWindow: | 253 // We want this to be a child of a browser window. addChildWindow: |
| 235 // (called from this function) will bring the window on-screen; | 254 // (called from this function) will bring the window on-screen; |
| 236 // unfortunately, [NSWindowController showWindow:] will also bring it | 255 // unfortunately, [NSWindowController showWindow:] will also bring it |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 // function is exposed for unit testing. | 296 // function is exposed for unit testing. |
| 278 - (NSWindow*)initializeWindow { | 297 - (NSWindow*)initializeWindow { |
| 279 NSWindow* window = [self window]; // completes nib load | 298 NSWindow* window = [self window]; // completes nib load |
| 280 | 299 |
| 281 if (type_ == extension_installed_bubble::kOmniboxKeyword) { | 300 if (type_ == extension_installed_bubble::kOmniboxKeyword) { |
| 282 [infoBubbleView_ setArrowLocation:info_bubble::kTopLeft]; | 301 [infoBubbleView_ setArrowLocation:info_bubble::kTopLeft]; |
| 283 } else { | 302 } else { |
| 284 [infoBubbleView_ setArrowLocation:info_bubble::kTopRight]; | 303 [infoBubbleView_ setArrowLocation:info_bubble::kTopRight]; |
| 285 } | 304 } |
| 286 | 305 |
| 306 if (type_ == extension_installed_bubble::kBundle) |
| 307 return window; |
| 308 |
| 287 // Set appropriate icon, resizing if necessary. | 309 // Set appropriate icon, resizing if necessary. |
| 288 if ([icon_ size].width > extension_installed_bubble::kIconSize) { | 310 if ([icon_ size].width > extension_installed_bubble::kIconSize) { |
| 289 [icon_ setSize:NSMakeSize(extension_installed_bubble::kIconSize, | 311 [icon_ setSize:NSMakeSize(extension_installed_bubble::kIconSize, |
| 290 extension_installed_bubble::kIconSize)]; | 312 extension_installed_bubble::kIconSize)]; |
| 291 } | 313 } |
| 292 [iconImage_ setImage:icon_]; | 314 [iconImage_ setImage:icon_]; |
| 293 [iconImage_ setNeedsDisplay:YES]; | 315 [iconImage_ setNeedsDisplay:YES]; |
| 294 return window; | 316 return window; |
| 295 } | 317 } |
| 296 | 318 |
| 297 // Calculate the height of each install message, resizing messages in their | 319 // Calculate the height of each install message, resizing messages in their |
| 298 // frames to fit window width. Return the new window height, based on the | 320 // frames to fit window width. Return the new window height, based on the |
| 299 // total of all message heights. | 321 // total of all message heights. |
| 300 - (int)calculateWindowHeight { | 322 - (int)calculateWindowHeight { |
| 301 // Adjust the window height to reflect the sum height of all messages | 323 // Adjust the window height to reflect the sum height of all messages |
| 302 // and vertical padding. | 324 // and vertical padding. |
| 303 int newWindowHeight = 2 * extension_installed_bubble::kOuterVerticalMargin; | 325 int newWindowHeight = 2 * extension_installed_bubble::kOuterVerticalMargin; |
| 304 | 326 |
| 305 // First part of extension installed message. | 327 // First part of extension installed message. |
| 306 string16 extension_name = UTF8ToUTF16(extension_->name().c_str()); | 328 if (type_ != extension_installed_bubble::kBundle) { |
| 307 base::i18n::AdjustStringForLocaleDirection(&extension_name); | 329 string16 extension_name = UTF8ToUTF16(extension_->name().c_str()); |
| 308 [extensionInstalledMsg_ setStringValue:l10n_util::GetNSStringF( | 330 base::i18n::AdjustStringForLocaleDirection(&extension_name); |
| 309 IDS_EXTENSION_INSTALLED_HEADING, extension_name)]; | 331 [extensionInstalledMsg_ setStringValue:l10n_util::GetNSStringF( |
| 310 [GTMUILocalizerAndLayoutTweaker | 332 IDS_EXTENSION_INSTALLED_HEADING, extension_name)]; |
| 333 [GTMUILocalizerAndLayoutTweaker |
| 311 sizeToFitFixedWidthTextField:extensionInstalledMsg_]; | 334 sizeToFitFixedWidthTextField:extensionInstalledMsg_]; |
| 312 newWindowHeight += [extensionInstalledMsg_ frame].size.height + | 335 newWindowHeight += [extensionInstalledMsg_ frame].size.height + |
| 313 extension_installed_bubble::kInnerVerticalMargin; | 336 extension_installed_bubble::kInnerVerticalMargin; |
| 337 } |
| 314 | 338 |
| 315 // If type is page action, include a special message about page actions. | 339 // If type is page action, include a special message about page actions. |
| 316 if (type_ == extension_installed_bubble::kPageAction) { | 340 if (type_ == extension_installed_bubble::kPageAction) { |
| 317 [extraInfoMsg_ setHidden:NO]; | 341 [extraInfoMsg_ setHidden:NO]; |
| 318 [[extraInfoMsg_ cell] | 342 [[extraInfoMsg_ cell] |
| 319 setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; | 343 setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; |
| 320 [GTMUILocalizerAndLayoutTweaker | 344 [GTMUILocalizerAndLayoutTweaker |
| 321 sizeToFitFixedWidthTextField:extraInfoMsg_]; | 345 sizeToFitFixedWidthTextField:extraInfoMsg_]; |
| 322 newWindowHeight += [extraInfoMsg_ frame].size.height + | 346 newWindowHeight += [extraInfoMsg_ frame].size.height + |
| 323 extension_installed_bubble::kInnerVerticalMargin; | 347 extension_installed_bubble::kInnerVerticalMargin; |
| 324 } | 348 } |
| 325 | 349 |
| 326 // If type is omnibox keyword, include a special message about the keyword. | 350 // If type is omnibox keyword, include a special message about the keyword. |
| 327 if (type_ == extension_installed_bubble::kOmniboxKeyword) { | 351 if (type_ == extension_installed_bubble::kOmniboxKeyword) { |
| 328 [extraInfoMsg_ setStringValue:l10n_util::GetNSStringF( | 352 [extraInfoMsg_ setStringValue:l10n_util::GetNSStringF( |
| 329 IDS_EXTENSION_INSTALLED_OMNIBOX_KEYWORD_INFO, | 353 IDS_EXTENSION_INSTALLED_OMNIBOX_KEYWORD_INFO, |
| 330 UTF8ToUTF16(extension_->omnibox_keyword()))]; | 354 UTF8ToUTF16(extension_->omnibox_keyword()))]; |
| 331 [extraInfoMsg_ setHidden:NO]; | 355 [extraInfoMsg_ setHidden:NO]; |
| 332 [[extraInfoMsg_ cell] | 356 [[extraInfoMsg_ cell] |
| 333 setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; | 357 setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; |
| 334 [GTMUILocalizerAndLayoutTweaker | 358 [GTMUILocalizerAndLayoutTweaker |
| 335 sizeToFitFixedWidthTextField:extraInfoMsg_]; | 359 sizeToFitFixedWidthTextField:extraInfoMsg_]; |
| 336 newWindowHeight += [extraInfoMsg_ frame].size.height + | 360 newWindowHeight += [extraInfoMsg_ frame].size.height + |
| 337 extension_installed_bubble::kInnerVerticalMargin; | 361 extension_installed_bubble::kInnerVerticalMargin; |
| 338 } | 362 } |
| 339 | 363 |
| 340 // Second part of extension installed message. | 364 // If type is bundle, list the extensions that were installed and those that |
| 341 [[extensionInstalledInfoMsg_ cell] | 365 // failed. |
| 342 setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; | 366 if (type_ == extension_installed_bubble::kBundle) { |
| 343 [GTMUILocalizerAndLayoutTweaker | 367 NSInteger installedListHeight = |
| 344 sizeToFitFixedWidthTextField:extensionInstalledInfoMsg_]; | 368 [self addExtensionList:installedHeadingMsg_ |
| 345 newWindowHeight += [extensionInstalledInfoMsg_ frame].size.height; | 369 itemsMsg:installedItemsMsg_ |
| 370 state:BundleInstaller::Item::STATE_INSTALLED]; |
| 371 |
| 372 NSInteger failedListHeight = |
| 373 [self addExtensionList:failedHeadingMsg_ |
| 374 itemsMsg:failedItemsMsg_ |
| 375 state:BundleInstaller::Item::STATE_FAILED]; |
| 376 |
| 377 newWindowHeight += installedListHeight + failedListHeight; |
| 378 |
| 379 // Put some space between the lists if both are present. |
| 380 if (installedListHeight > 0 && failedListHeight > 0) |
| 381 newWindowHeight += extension_installed_bubble::kInnerVerticalMargin; |
| 382 } else { |
| 383 // Second part of extension installed message. |
| 384 [[extensionInstalledInfoMsg_ cell] |
| 385 setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; |
| 386 [GTMUILocalizerAndLayoutTweaker |
| 387 sizeToFitFixedWidthTextField:extensionInstalledInfoMsg_]; |
| 388 newWindowHeight += [extensionInstalledInfoMsg_ frame].size.height; |
| 389 } |
| 346 | 390 |
| 347 return newWindowHeight; | 391 return newWindowHeight; |
| 348 } | 392 } |
| 349 | 393 |
| 394 - (NSInteger)addExtensionList:(NSTextField*)headingMsg |
| 395 itemsMsg:(NSTextField*)itemsMsg |
| 396 state:(BundleInstaller::Item::State)state { |
| 397 string16 heading = bundle_->GetHeadingTextFor(state); |
| 398 bool hidden = heading.empty(); |
| 399 [headingMsg setHidden:hidden]; |
| 400 [itemsMsg setHidden:hidden]; |
| 401 if (hidden) |
| 402 return 0; |
| 403 |
| 404 [headingMsg setStringValue:base::SysUTF16ToNSString(heading)]; |
| 405 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:headingMsg]; |
| 406 |
| 407 NSMutableString* joinedItems = [NSMutableString string]; |
| 408 BundleInstaller::ItemList items = bundle_->GetItemsWithState(state); |
| 409 for (size_t i = 0; i < items.size(); ++i) { |
| 410 if (i > 0) |
| 411 [joinedItems appendString:@"\n"]; |
| 412 [joinedItems appendString:base::SysUTF16ToNSString( |
| 413 items[i].GetNameForDisplay())]; |
| 414 } |
| 415 |
| 416 [itemsMsg setStringValue:joinedItems]; |
| 417 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:itemsMsg]; |
| 418 |
| 419 return [headingMsg frame].size.height + |
| 420 extension_installed_bubble::kInnerVerticalMargin + |
| 421 [itemsMsg frame].size.height; |
| 422 } |
| 423 |
| 350 // Adjust y-position of messages to sit properly in new window height. | 424 // Adjust y-position of messages to sit properly in new window height. |
| 351 - (void)setMessageFrames:(int)newWindowHeight { | 425 - (void)setMessageFrames:(int)newWindowHeight { |
| 352 // The extension messages will always be shown. | 426 if (type_ == extension_installed_bubble::kBundle) { |
| 427 // Layout the messages from the bottom up. |
| 428 NSTextField* msgs[] = { failedItemsMsg_, failedHeadingMsg_, |
| 429 installedItemsMsg_, installedHeadingMsg_ }; |
| 430 NSInteger offsetFromBottom = 0; |
| 431 BOOL isFirstVisible = YES; |
| 432 for (size_t i = 0; i < arraysize(msgs); ++i) { |
| 433 if ([msgs[i] isHidden]) |
| 434 continue; |
| 435 |
| 436 NSRect frame = [msgs[i] frame]; |
| 437 NSInteger margin = isFirstVisible ? |
| 438 extension_installed_bubble::kOuterVerticalMargin : |
| 439 extension_installed_bubble::kInnerVerticalMargin; |
| 440 |
| 441 frame.origin.y = offsetFromBottom + margin; |
| 442 [msgs[i] setFrame:frame]; |
| 443 offsetFromBottom += frame.size.height + margin; |
| 444 |
| 445 isFirstVisible = NO; |
| 446 } |
| 447 |
| 448 // Move the close button a bit to vertically align it with the heading. |
| 449 NSInteger closeButtonFudge = 1; |
| 450 NSRect frame = [closeButton_ frame]; |
| 451 frame.origin.y = newWindowHeight - (frame.size.height + closeButtonFudge + |
| 452 extension_installed_bubble::kOuterVerticalMargin); |
| 453 [closeButton_ setFrame:frame]; |
| 454 |
| 455 return; |
| 456 } |
| 457 |
| 353 NSRect extensionMessageFrame1 = [extensionInstalledMsg_ frame]; | 458 NSRect extensionMessageFrame1 = [extensionInstalledMsg_ frame]; |
| 354 NSRect extensionMessageFrame2 = [extensionInstalledInfoMsg_ frame]; | 459 NSRect extensionMessageFrame2 = [extensionInstalledInfoMsg_ frame]; |
| 355 | 460 |
| 356 extensionMessageFrame1.origin.y = newWindowHeight - ( | 461 extensionMessageFrame1.origin.y = newWindowHeight - ( |
| 357 extensionMessageFrame1.size.height + | 462 extensionMessageFrame1.size.height + |
| 358 extension_installed_bubble::kOuterVerticalMargin); | 463 extension_installed_bubble::kOuterVerticalMargin); |
| 359 [extensionInstalledMsg_ setFrame:extensionMessageFrame1]; | 464 [extensionInstalledMsg_ setFrame:extensionMessageFrame1]; |
| 360 if (type_ == extension_installed_bubble::kPageAction || | 465 if (type_ == extension_installed_bubble::kPageAction || |
| 361 type_ == extension_installed_bubble::kOmniboxKeyword) { | 466 type_ == extension_installed_bubble::kOmniboxKeyword) { |
| 362 // The extra message is only shown when appropriate. | 467 // The extra message is only shown when appropriate. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 387 | 492 |
| 388 - (NSRect)getExtensionInstalledInfoMsgFrame { | 493 - (NSRect)getExtensionInstalledInfoMsgFrame { |
| 389 return [extensionInstalledInfoMsg_ frame]; | 494 return [extensionInstalledInfoMsg_ frame]; |
| 390 } | 495 } |
| 391 | 496 |
| 392 - (void)extensionUnloaded:(id)sender { | 497 - (void)extensionUnloaded:(id)sender { |
| 393 extension_ = NULL; | 498 extension_ = NULL; |
| 394 } | 499 } |
| 395 | 500 |
| 396 @end | 501 @end |
| OLD | NEW |