Chromium Code Reviews| 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" |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 85 @synthesize bundle = bundle_; | 85 @synthesize bundle = bundle_; |
| 86 @synthesize pageActionRemoved = pageActionRemoved_; // Exposed for unit test. | 86 @synthesize pageActionRemoved = pageActionRemoved_; // Exposed for unit test. |
| 87 | 87 |
| 88 - (id)initWithParentWindow:(NSWindow*)parentWindow | 88 - (id)initWithParentWindow:(NSWindow*)parentWindow |
| 89 extension:(const Extension*)extension | 89 extension:(const Extension*)extension |
| 90 bundle:(const BundleInstaller*)bundle | 90 bundle:(const BundleInstaller*)bundle |
| 91 browser:(Browser*)browser | 91 browser:(Browser*)browser |
| 92 icon:(SkBitmap)icon { | 92 icon:(SkBitmap)icon { |
| 93 NSString* nibName = bundle ? @"ExtensionInstalledBubbleBundle" : | 93 NSString* nibName = bundle ? @"ExtensionInstalledBubbleBundle" : |
| 94 @"ExtensionInstalledBubble"; | 94 @"ExtensionInstalledBubble"; |
| 95 NSString* nibPath = [base::mac::FrameworkBundle() pathForResource:nibName | 95 if ((self = [super initWithWindowNibPath:nibName |
| 96 ofType:@"nib"]; | 96 parentWindow:parentWindow |
| 97 if ((self = [super initWithWindowNibPath:nibPath owner:self])) { | 97 anchoredAt:NSZeroPoint])) { |
| 98 DCHECK(parentWindow); | |
| 99 parentWindow_ = parentWindow; | |
| 100 extension_ = extension; | 98 extension_ = extension; |
| 101 bundle_ = bundle; | 99 bundle_ = bundle; |
| 102 DCHECK(browser); | 100 DCHECK(browser); |
| 103 browser_ = browser; | 101 browser_ = browser; |
| 104 icon_.reset([gfx::SkBitmapToNSImage(icon) retain]); | 102 icon_.reset([gfx::SkBitmapToNSImage(icon) retain]); |
| 105 pageActionRemoved_ = NO; | 103 pageActionRemoved_ = NO; |
| 106 | 104 |
| 107 if (bundle_) { | 105 if (bundle_) { |
| 108 type_ = extension_installed_bubble::kBundle; | 106 type_ = extension_installed_bubble::kBundle; |
| 109 } else if (!extension->omnibox_keyword().empty()) { | 107 } else if (!extension->omnibox_keyword().empty()) { |
| 110 type_ = extension_installed_bubble::kOmniboxKeyword; | 108 type_ = extension_installed_bubble::kOmniboxKeyword; |
| 111 } else if (extension->browser_action()) { | 109 } else if (extension->browser_action()) { |
| 112 type_ = extension_installed_bubble::kBrowserAction; | 110 type_ = extension_installed_bubble::kBrowserAction; |
| 113 } else if (extension->page_action() && | 111 } else if (extension->page_action() && |
| 114 !extension->page_action()->default_icon_path().empty()) { | 112 !extension->page_action()->default_icon_path().empty()) { |
| 115 type_ = extension_installed_bubble::kPageAction; | 113 type_ = extension_installed_bubble::kPageAction; |
| 116 } else { | 114 } else { |
| 117 NOTREACHED(); // kGeneric installs handled in the extension_install_ui. | 115 NOTREACHED(); // kGeneric installs handled in the extension_install_ui. |
| 118 } | 116 } |
| 119 | 117 |
| 120 if (type_ == extension_installed_bubble::kBundle) { | 118 if (type_ == extension_installed_bubble::kBundle) { |
| 121 [self showWindow:self]; | 119 [self showWindow:self]; |
| 122 } else { | 120 } else { |
| 123 // Start showing window only after extension has fully loaded. | 121 // Start showing window only after extension has fully loaded. |
| 124 extensionObserver_.reset(new ExtensionLoadedNotificationObserver( | 122 extensionObserver_.reset(new ExtensionLoadedNotificationObserver( |
| 125 self, browser->profile())); | 123 self, browser->profile())); |
| 126 } | 124 } |
| 127 | |
| 128 // Watch to see if the parent window closes, and if so, close this one. | |
| 129 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; | |
| 130 [center addObserver:self | |
| 131 selector:@selector(parentWindowWillClose:) | |
| 132 name:NSWindowWillCloseNotification | |
| 133 object:parentWindow_]; | |
| 134 } | 125 } |
| 135 return self; | 126 return self; |
| 136 } | 127 } |
| 137 | 128 |
| 138 - (void)dealloc { | |
| 139 [[NSNotificationCenter defaultCenter] removeObserver:self]; | |
| 140 [super dealloc]; | |
| 141 } | |
| 142 | |
| 143 - (void)close { | |
| 144 [[[self window] parentWindow] removeChildWindow:[self window]]; | |
| 145 [super close]; | |
| 146 } | |
| 147 | |
| 148 - (void)parentWindowWillClose:(NSNotification*)notification { | |
| 149 [self close]; | |
| 150 } | |
| 151 | |
| 152 - (void)windowWillClose:(NSNotification*)notification { | 129 - (void)windowWillClose:(NSNotification*)notification { |
| 153 // Turn off page action icon preview when the window closes, unless we | 130 // Turn off page action icon preview when the window closes, unless we |
| 154 // already removed it when the window resigned key status. | 131 // already removed it when the window resigned key status. |
| 155 [self removePageActionPreviewIfNecessary]; | 132 [self removePageActionPreviewIfNecessary]; |
| 156 extension_ = NULL; | 133 extension_ = NULL; |
| 157 browser_ = NULL; | 134 browser_ = NULL; |
| 158 parentWindow_ = nil; | 135 |
| 159 // We caught a close so we don't need to watch for the parent closing. | 136 [super windowWillClose:notification]; |
| 160 [[NSNotificationCenter defaultCenter] removeObserver:self]; | |
| 161 [self autorelease]; | |
| 162 } | 137 } |
| 163 | 138 |
| 164 // The controller is the delegate of the window, so it receives "did resign | 139 // The controller is the delegate of the window, so it receives "did resign |
| 165 // key" notifications. When key is resigned, close the window. | 140 // key" notifications. When key is resigned, close the window. |
| 166 - (void)windowDidResignKey:(NSNotification*)notification { | 141 - (void)windowDidResignKey:(NSNotification*)notification { |
| 167 NSWindow* window = [self window]; | |
| 168 DCHECK_EQ([notification object], window); | |
| 169 DCHECK([window isVisible]); | |
| 170 | |
| 171 // If the browser window is closing, we need to remove the page action | 142 // If the browser window is closing, we need to remove the page action |
| 172 // immediately, otherwise the closing animation may overlap with | 143 // immediately, otherwise the closing animation may overlap with |
| 173 // browser destruction. | 144 // browser destruction. |
| 174 [self removePageActionPreviewIfNecessary]; | 145 [self removePageActionPreviewIfNecessary]; |
| 175 [self close]; | 146 [super windowDidResignKey:notification]; |
| 176 } | 147 } |
| 177 | 148 |
| 178 - (IBAction)closeWindow:(id)sender { | 149 - (IBAction)closeWindow:(id)sender { |
| 179 DCHECK([[self window] isVisible]); | 150 DCHECK([[self window] isVisible]); |
| 180 [self close]; | 151 [self close]; |
| 181 } | 152 } |
| 182 | 153 |
| 183 // Extracted to a function here so that it can be overwritten for unit | 154 // Extracted to a function here so that it can be overwritten for unit |
| 184 // testing. | 155 // testing. |
| 185 - (void)removePageActionPreviewIfNecessary { | 156 - (void)removePageActionPreviewIfNecessary { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 257 // position). We cannot have an addChildWindow: and a subsequent | 228 // position). We cannot have an addChildWindow: and a subsequent |
| 258 // showWindow:. Thus, we have our own version. | 229 // showWindow:. Thus, we have our own version. |
| 259 - (void)showWindow:(id)sender { | 230 - (void)showWindow:(id)sender { |
| 260 // Generic extensions get an infobar rather than a bubble. | 231 // Generic extensions get an infobar rather than a bubble. |
| 261 DCHECK(type_ != extension_installed_bubble::kGeneric); | 232 DCHECK(type_ != extension_installed_bubble::kGeneric); |
| 262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 233 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 263 | 234 |
| 264 // Load nib and calculate height based on messages to be shown. | 235 // Load nib and calculate height based on messages to be shown. |
| 265 NSWindow* window = [self initializeWindow]; | 236 NSWindow* window = [self initializeWindow]; |
| 266 int newWindowHeight = [self calculateWindowHeight]; | 237 int newWindowHeight = [self calculateWindowHeight]; |
| 267 [infoBubbleView_ setFrameSize:NSMakeSize( | 238 [self.bubble setFrameSize:NSMakeSize( |
| 268 NSWidth([[window contentView] bounds]), newWindowHeight)]; | 239 NSWidth([[window contentView] bounds]), newWindowHeight)]; |
| 269 NSSize windowDelta = NSMakeSize( | 240 NSSize windowDelta = NSMakeSize( |
| 270 0, newWindowHeight - NSHeight([[window contentView] bounds])); | 241 0, newWindowHeight - NSHeight([[window contentView] bounds])); |
| 271 windowDelta = [[window contentView] convertSize:windowDelta toView:nil]; | 242 windowDelta = [[window contentView] convertSize:windowDelta toView:nil]; |
| 272 NSRect newFrame = [window frame]; | 243 NSRect newFrame = [window frame]; |
| 273 newFrame.size.height += windowDelta.height; | 244 newFrame.size.height += windowDelta.height; |
| 274 [window setFrame:newFrame display:NO]; | 245 [window setFrame:newFrame display:NO]; |
| 275 | 246 |
| 276 // Now that we have resized the window, adjust y pos of the messages. | 247 // Now that we have resized the window, adjust y pos of the messages. |
| 277 [self setMessageFrames:newWindowHeight]; | 248 [self setMessageFrames:newWindowHeight]; |
| 278 | 249 |
| 279 // Find window origin, taking into account bubble size and arrow location. | 250 // Find window origin, taking into account bubble size and arrow location. |
| 280 NSPoint origin = | 251 self.anchorPoint = |
|
Nico
2012/03/14 23:59:46
bleh, property syntax for nontrivial setters :-/
| |
| 281 [parentWindow_ convertBaseToScreen:[self calculateArrowPoint]]; | 252 [self.parentWindow convertBaseToScreen:[self calculateArrowPoint]]; |
| 282 NSSize offsets = NSMakeSize(info_bubble::kBubbleArrowXOffset + | 253 [super showWindow:sender]; |
| 283 info_bubble::kBubbleArrowWidth / 2.0, 0); | |
| 284 offsets = [[window contentView] convertSize:offsets toView:nil]; | |
| 285 if ([infoBubbleView_ arrowLocation] == info_bubble::kTopRight) | |
| 286 origin.x -= NSWidth([window frame]) - offsets.width; | |
| 287 origin.y -= NSHeight([window frame]); | |
| 288 [window setFrameOrigin:origin]; | |
| 289 | |
| 290 [parentWindow_ addChildWindow:window | |
| 291 ordered:NSWindowAbove]; | |
| 292 [window makeKeyAndOrderFront:self]; | |
| 293 } | 254 } |
| 294 | 255 |
| 295 // Finish nib loading, set arrow location and load icon into window. This | 256 // Finish nib loading, set arrow location and load icon into window. This |
| 296 // function is exposed for unit testing. | 257 // function is exposed for unit testing. |
| 297 - (NSWindow*)initializeWindow { | 258 - (NSWindow*)initializeWindow { |
| 298 NSWindow* window = [self window]; // completes nib load | 259 NSWindow* window = [self window]; // completes nib load |
| 299 | 260 |
| 300 if (type_ == extension_installed_bubble::kOmniboxKeyword) { | 261 if (type_ == extension_installed_bubble::kOmniboxKeyword) { |
| 301 [infoBubbleView_ setArrowLocation:info_bubble::kTopLeft]; | 262 [self.bubble setArrowLocation:info_bubble::kTopLeft]; |
| 302 } else { | 263 } else { |
| 303 [infoBubbleView_ setArrowLocation:info_bubble::kTopRight]; | 264 [self.bubble setArrowLocation:info_bubble::kTopRight]; |
| 304 } | 265 } |
| 305 | 266 |
| 306 if (type_ == extension_installed_bubble::kBundle) | 267 if (type_ == extension_installed_bubble::kBundle) |
| 307 return window; | 268 return window; |
| 308 | 269 |
| 309 // Set appropriate icon, resizing if necessary. | 270 // Set appropriate icon, resizing if necessary. |
| 310 if ([icon_ size].width > extension_installed_bubble::kIconSize) { | 271 if ([icon_ size].width > extension_installed_bubble::kIconSize) { |
| 311 [icon_ setSize:NSMakeSize(extension_installed_bubble::kIconSize, | 272 [icon_ setSize:NSMakeSize(extension_installed_bubble::kIconSize, |
| 312 extension_installed_bubble::kIconSize)]; | 273 extension_installed_bubble::kIconSize)]; |
| 313 } | 274 } |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 492 | 453 |
| 493 - (NSRect)getExtensionInstalledInfoMsgFrame { | 454 - (NSRect)getExtensionInstalledInfoMsgFrame { |
| 494 return [extensionInstalledInfoMsg_ frame]; | 455 return [extensionInstalledInfoMsg_ frame]; |
| 495 } | 456 } |
| 496 | 457 |
| 497 - (void)extensionUnloaded:(id)sender { | 458 - (void)extensionUnloaded:(id)sender { |
| 498 extension_ = NULL; | 459 extension_ = NULL; |
| 499 } | 460 } |
| 500 | 461 |
| 501 @end | 462 @end |
| OLD | NEW |