| OLD | NEW | 
|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_install_dialog_controller.
     h" | 5 #import "chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.
     h" | 
| 6 | 6 | 
| 7 #include "base/mac/mac_util.h" | 7 #include "base/mac/mac_util.h" | 
|  | 8 #include "base/memory/scoped_nsobject.h" | 
| 8 #include "base/string_util.h" | 9 #include "base/string_util.h" | 
| 9 #include "base/sys_string_conversions.h" | 10 #include "base/sys_string_conversions.h" | 
| 10 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" | 
| 11 #include "chrome/browser/extensions/extension_install_dialog.h" | 12 #include "chrome/browser/extensions/extension_install_dialog.h" | 
| 12 #include "chrome/browser/ui/browser.h" | 13 #include "chrome/browser/ui/browser.h" | 
| 13 #include "chrome/browser/ui/browser_list.h" | 14 #include "chrome/browser/ui/browser_list.h" | 
| 14 #include "chrome/browser/ui/browser_window.h" | 15 #include "chrome/browser/ui/browser_window.h" | 
| 15 #include "chrome/common/extensions/extension.h" | 16 #include "chrome/common/extensions/extension.h" | 
| 16 #include "grit/generated_resources.h" | 17 #include "grit/generated_resources.h" | 
| 17 #include "skia/ext/skia_utils_mac.h" | 18 #include "skia/ext/skia_utils_mac.h" | 
|  | 19 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" | 
| 18 #include "ui/base/l10n/l10n_util.h" | 20 #include "ui/base/l10n/l10n_util.h" | 
| 19 #include "ui/base/l10n/l10n_util_mac.h" | 21 #include "ui/base/l10n/l10n_util_mac.h" | 
| 20 | 22 | 
|  | 23 @interface ExtensionInstallDialogController () | 
|  | 24 - (bool)isInlineInstall; | 
|  | 25 - (void)appendRatingStar:(const SkBitmap*)skiaImage; | 
|  | 26 @end | 
|  | 27 | 
| 21 namespace { | 28 namespace { | 
| 22 | 29 | 
|  | 30 // Padding above the warnings separator, we must also subtract this when hiding | 
|  | 31 // it. | 
|  | 32 const CGFloat kWarningsSeparatorPadding = 14; | 
|  | 33 | 
| 23 // Maximum height we will adjust controls to when trying to accomodate their | 34 // Maximum height we will adjust controls to when trying to accomodate their | 
| 24 // contents. | 35 // contents. | 
| 25 const CGFloat kMaxControlHeight = 400; | 36 const CGFloat kMaxControlHeight = 400; | 
| 26 | 37 | 
| 27 // Adjust a control's height so that its content its not clipped. Returns the | 38 // Adjust a control's height so that its content its not clipped. Returns the | 
| 28 // amount the control's height had to be adjusted. | 39 // amount the control's height had to be adjusted. | 
| 29 CGFloat AdjustControlHeightToFitContent(NSControl* control) { | 40 CGFloat AdjustControlHeightToFitContent(NSControl* control) { | 
| 30   NSRect currentRect = [control frame]; | 41   NSRect currentRect = [control frame]; | 
| 31   NSRect fitRect = currentRect; | 42   NSRect fitRect = currentRect; | 
| 32   fitRect.size.height = kMaxControlHeight; | 43   fitRect.size.height = kMaxControlHeight; | 
| 33   CGFloat desiredHeight = [[control cell] cellSizeForBounds:fitRect].height; | 44   CGFloat desiredHeight = [[control cell] cellSizeForBounds:fitRect].height; | 
| 34   CGFloat offset = desiredHeight - currentRect.size.height; | 45   CGFloat offset = desiredHeight - currentRect.size.height; | 
| 35 | 46 | 
| 36   [control setFrameSize:NSMakeSize(currentRect.size.width, | 47   [control setFrameSize:NSMakeSize(currentRect.size.width, | 
| 37                                    currentRect.size.height + offset)]; | 48                                    currentRect.size.height + offset)]; | 
| 38   return offset; | 49   return offset; | 
| 39 } | 50 } | 
| 40 | 51 | 
| 41 // Moves the control vertically by the specified amount. | 52 // Moves the control vertically by the specified amount. | 
| 42 void OffsetControlVertically(NSControl* control, CGFloat amount) { | 53 void OffsetControlVertically(NSControl* control, CGFloat amount) { | 
| 43   NSPoint origin = [control frame].origin; | 54   NSPoint origin = [control frame].origin; | 
| 44   origin.y += amount; | 55   origin.y += amount; | 
| 45   [control setFrameOrigin:origin]; | 56   [control setFrameOrigin:origin]; | 
| 46 } | 57 } | 
| 47 | 58 | 
|  | 59 void AppendRatingStarsShim(const SkBitmap* skiaImage, void* data) { | 
|  | 60   ExtensionInstallDialogController* controller = | 
|  | 61       static_cast<ExtensionInstallDialogController*>(data); | 
|  | 62   [controller appendRatingStar:skiaImage]; | 
|  | 63 } | 
|  | 64 | 
| 48 } | 65 } | 
| 49 | 66 | 
| 50 @implementation ExtensionInstallDialogController | 67 @implementation ExtensionInstallDialogController | 
| 51 | 68 | 
| 52 @synthesize iconView = iconView_; | 69 @synthesize iconView = iconView_; | 
| 53 @synthesize titleField = titleField_; | 70 @synthesize titleField = titleField_; | 
| 54 @synthesize subtitleField = subtitleField_; | 71 @synthesize subtitleField = subtitleField_; | 
| 55 @synthesize warningsField = warningsField_; | 72 @synthesize warningsField = warningsField_; | 
| 56 @synthesize warningsBox= warningsBox_; |  | 
| 57 @synthesize cancelButton = cancelButton_; | 73 @synthesize cancelButton = cancelButton_; | 
| 58 @synthesize okButton = okButton_; | 74 @synthesize okButton = okButton_; | 
|  | 75 @synthesize warningsSeparator = warningsSeparator_; | 
|  | 76 @synthesize ratingStars = ratingStars_; | 
|  | 77 @synthesize ratingCountField = ratingCountField_; | 
|  | 78 @synthesize userCountField = userCountField_; | 
| 59 | 79 | 
| 60 - (id)initWithParentWindow:(NSWindow*)window | 80 - (id)initWithParentWindow:(NSWindow*)window | 
| 61                    profile:(Profile*)profile | 81                    profile:(Profile*)profile | 
| 62                  extension:(const Extension*)extension | 82                  extension:(const Extension*)extension | 
| 63                   delegate:(ExtensionInstallUI::Delegate*)delegate | 83                   delegate:(ExtensionInstallUI::Delegate*)delegate | 
| 64                       icon:(SkBitmap*)icon | 84                       icon:(SkBitmap*)icon | 
| 65                     prompt:(const ExtensionInstallUI::Prompt&)prompt { | 85                     prompt:(const ExtensionInstallUI::Prompt&)prompt { | 
| 66   NSString* nibpath = nil; | 86   NSString* nibpath = nil; | 
| 67 | 87 | 
| 68   // We use a different XIB in the case of no permission warnings, that is a | 88   // We use a different XIB in the case of inline installs or no permission | 
| 69   // little bit more nicely laid out. | 89   // warnings, that respectively show webstore ratings data and are a more | 
| 70   if (prompt.GetPermissionCount() == 0) { | 90   // nicely laid out. | 
|  | 91   if (prompt.type() == ExtensionInstallUI::INLINE_INSTALL_PROMPT) { | 
|  | 92     nibpath = [base::mac::MainAppBundle() | 
|  | 93                pathForResource:@"ExtensionInstallPromptInline" | 
|  | 94                         ofType:@"nib"]; | 
|  | 95   } else if (prompt.GetPermissionCount() == 0) { | 
| 71     nibpath = [base::mac::MainAppBundle() | 96     nibpath = [base::mac::MainAppBundle() | 
| 72                pathForResource:@"ExtensionInstallPromptNoWarnings" | 97                pathForResource:@"ExtensionInstallPromptNoWarnings" | 
| 73                         ofType:@"nib"]; | 98                         ofType:@"nib"]; | 
| 74   } else { | 99   } else { | 
| 75    nibpath = [base::mac::MainAppBundle() | 100    nibpath = [base::mac::MainAppBundle() | 
| 76               pathForResource:@"ExtensionInstallPrompt" | 101               pathForResource:@"ExtensionInstallPrompt" | 
| 77                        ofType:@"nib"]; | 102                        ofType:@"nib"]; | 
| 78   } | 103   } | 
| 79 | 104 | 
| 80   if ((self = [super initWithWindowNibPath:nibpath owner:self])) { | 105   if ((self = [super initWithWindowNibPath:nibpath owner:self])) { | 
| 81     parentWindow_ = window; | 106     parentWindow_ = window; | 
| 82     profile_ = profile; | 107     profile_ = profile; | 
| 83     icon_ = *icon; | 108     icon_ = *icon; | 
| 84     delegate_ = delegate; | 109     delegate_ = delegate; | 
| 85 | 110     extension_ = extension; | 
| 86     title_.reset([base::SysUTF16ToNSString( | 111     prompt_.reset(new ExtensionInstallUI::Prompt(prompt)); | 
| 87         prompt.GetHeading(extension->name())) retain]); |  | 
| 88     subtitle_.reset([base::SysUTF16ToNSString( |  | 
| 89         prompt.GetPermissionsHeader()) retain]); |  | 
| 90     button_.reset([base::SysUTF16ToNSString( |  | 
| 91         prompt.GetAcceptButtonLabel()) retain]); |  | 
| 92     NSString* cancel_button_label = prompt.HasAbortButtonLabel() ? |  | 
| 93         base::SysUTF16ToNSString(prompt.GetAbortButtonLabel()) : |  | 
| 94         l10n_util::GetNSString(IDS_CANCEL); |  | 
| 95     cancel_button_.reset([cancel_button_label retain]); |  | 
| 96 |  | 
| 97     // We display the permission warnings as a simple text string, separated by |  | 
| 98     // newlines. |  | 
| 99     if (prompt.GetPermissionCount()) { |  | 
| 100       string16 joined_warnings; |  | 
| 101       for (size_t i = 0; i < prompt.GetPermissionCount(); ++i) { |  | 
| 102         if (i > 0) |  | 
| 103           joined_warnings += UTF8ToUTF16("\n\n"); |  | 
| 104 |  | 
| 105         joined_warnings += prompt.GetPermission(i); |  | 
| 106       } |  | 
| 107 |  | 
| 108       warnings_.reset( |  | 
| 109           [base::SysUTF16ToNSString(joined_warnings) retain]); |  | 
| 110     } |  | 
| 111   } | 112   } | 
| 112   return self; | 113   return self; | 
| 113 } | 114 } | 
| 114 | 115 | 
| 115 - (void)runAsModalSheet { | 116 - (void)runAsModalSheet { | 
| 116   [NSApp beginSheet:[self window] | 117   [NSApp beginSheet:[self window] | 
| 117      modalForWindow:parentWindow_ | 118      modalForWindow:parentWindow_ | 
| 118       modalDelegate:self | 119       modalDelegate:self | 
| 119      didEndSelector:@selector(didEndSheet:returnCode:contextInfo:) | 120      didEndSelector:@selector(didEndSheet:returnCode:contextInfo:) | 
| 120         contextInfo:nil]; | 121         contextInfo:nil]; | 
| 121 } | 122 } | 
| 122 | 123 | 
| 123 - (IBAction)cancel:(id)sender { | 124 - (IBAction)storeLinkClicked:(id)sender { | 
| 124   delegate_->InstallUIAbort(true); | 125   GURL store_url( | 
|  | 126       extension_urls::GetWebstoreItemDetailURLPrefix() + extension_->id()); | 
|  | 127   BrowserList::GetLastActiveWithProfile(profile_)-> | 
|  | 128       OpenURL(store_url, GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK); | 
|  | 129 | 
|  | 130   delegate_->InstallUIAbort(/*user_initiated=*/true); | 
| 125   [NSApp endSheet:[self window]]; | 131   [NSApp endSheet:[self window]]; | 
| 126 } | 132 } | 
| 127 | 133 | 
|  | 134 - (IBAction)cancel:(id)sender { | 
|  | 135   delegate_->InstallUIAbort(/*user_initiated=*/true); | 
|  | 136   [NSApp endSheet:[self window]]; | 
|  | 137 } | 
|  | 138 | 
| 128 - (IBAction)ok:(id)sender { | 139 - (IBAction)ok:(id)sender { | 
| 129   delegate_->InstallUIProceed(); | 140   delegate_->InstallUIProceed(); | 
| 130   [NSApp endSheet:[self window]]; | 141   [NSApp endSheet:[self window]]; | 
| 131 } | 142 } | 
| 132 | 143 | 
| 133 - (void)awakeFromNib { | 144 - (void)awakeFromNib { | 
| 134   [titleField_ setStringValue:title_.get()]; | 145   // Make sure we're the window's delegate as set in the nib. | 
| 135   [subtitleField_ setStringValue:subtitle_.get()]; | 146   DCHECK_EQ(self, static_cast<ExtensionInstallDialogController*>( | 
| 136   [okButton_ setTitle:button_.get()]; | 147                       [[self window] delegate])); | 
| 137   [cancelButton_ setTitle:cancel_button_.get()]; | 148 | 
|  | 149   // Set control labels. | 
|  | 150   [titleField_ setStringValue:base::SysUTF16ToNSString( | 
|  | 151       prompt_->GetHeading(extension_->name()))]; | 
|  | 152   [okButton_ setTitle:base::SysUTF16ToNSString( | 
|  | 153       prompt_->GetAcceptButtonLabel())]; | 
|  | 154   [cancelButton_ setTitle:prompt_->HasAbortButtonLabel() ? | 
|  | 155       base::SysUTF16ToNSString(prompt_->GetAbortButtonLabel()) : | 
|  | 156       l10n_util::GetNSString(IDS_CANCEL)]; | 
|  | 157   if ([self isInlineInstall]) { | 
|  | 158     prompt_->AppendRatingStars(AppendRatingStarsShim, self); | 
|  | 159     [ratingCountField_ setStringValue:base::SysUTF16ToNSString( | 
|  | 160         prompt_->GetRatingCount())]; | 
|  | 161     [userCountField_ setStringValue:base::SysUTF16ToNSString( | 
|  | 162         prompt_->GetUserCount())]; | 
|  | 163   } | 
| 138 | 164 | 
| 139   NSImage* image = gfx::SkBitmapToNSImage(icon_); | 165   NSImage* image = gfx::SkBitmapToNSImage(icon_); | 
| 140   [iconView_ setImage:image]; | 166   [iconView_ setImage:image]; | 
| 141 | 167 | 
| 142   // Reisze |titleField_| to fit title | 168   // Resize |titleField_| to fit the title. | 
| 143   CGFloat originalTitleWidth = [titleField_ frame].size.width; | 169   CGFloat originalTitleWidth = [titleField_ frame].size.width; | 
| 144   [titleField_ sizeToFit]; | 170   [titleField_ sizeToFit]; | 
| 145   CGFloat newTitleWidth = [titleField_ frame].size.width; | 171   CGFloat newTitleWidth = [titleField_ frame].size.width; | 
| 146   if (newTitleWidth > originalTitleWidth) { | 172   if (newTitleWidth > originalTitleWidth) { | 
| 147     NSRect frame = [[self window] frame]; | 173     NSRect frame = [[self window] frame]; | 
| 148     frame.size.width += newTitleWidth - originalTitleWidth; | 174     frame.size.width += newTitleWidth - originalTitleWidth; | 
| 149     [[self window] setFrame:frame display:NO]; | 175     [[self window] setFrame:frame display:NO]; | 
| 150   } | 176   } | 
| 151 | 177 | 
| 152   // Make sure we're the window's delegate as set in the nib. | 178   // Resize |okButton_| and |cancelButton_| to fit the button labels, but keep | 
| 153   DCHECK_EQ(self, static_cast<ExtensionInstallDialogController*>( | 179   // them right-aligned. | 
| 154                       [[self window] delegate])); | 180   NSSize buttonDelta = [GTMUILocalizerAndLayoutTweaker sizeToFitView:okButton_]; | 
|  | 181   if (buttonDelta.width) { | 
|  | 182     [okButton_ setFrame:NSOffsetRect([okButton_ frame], -buttonDelta.width, 0)]; | 
|  | 183     [cancelButton_ setFrame:NSOffsetRect([cancelButton_ frame], | 
|  | 184                                          -buttonDelta.width, 0)]; | 
|  | 185   } | 
|  | 186   buttonDelta = [GTMUILocalizerAndLayoutTweaker sizeToFitView:cancelButton_]; | 
|  | 187   if (buttonDelta.width) { | 
|  | 188     [cancelButton_ setFrame:NSOffsetRect([cancelButton_ frame], | 
|  | 189                                          -buttonDelta.width, 0)]; | 
|  | 190   } | 
| 155 | 191 | 
|  | 192   CGFloat totalOffset = 0.0; | 
| 156   // If there are any warnings, then we have to do some special layout. | 193   // If there are any warnings, then we have to do some special layout. | 
| 157   if ([warnings_.get() length] > 0) { | 194   if (prompt_->GetPermissionCount() > 0) { | 
| 158     [warningsField_ setStringValue:warnings_.get()]; | 195     [subtitleField_ setStringValue:base::SysUTF16ToNSString( | 
|  | 196         prompt_->GetPermissionsHeader())]; | 
|  | 197 | 
|  | 198     // We display the permission warnings as a simple text string, separated by | 
|  | 199     // newlines. | 
|  | 200     NSMutableString* joinedWarnings = [NSMutableString string]; | 
|  | 201     for (size_t i = 0; i < prompt_->GetPermissionCount(); ++i) { | 
|  | 202       if (i > 0) | 
|  | 203         [joinedWarnings appendString:@"\n"]; | 
|  | 204       [joinedWarnings appendString:base::SysUTF16ToNSString( | 
|  | 205           prompt_->GetPermission(i))]; | 
|  | 206     } | 
|  | 207     [warningsField_ setStringValue:joinedWarnings]; | 
| 159 | 208 | 
| 160     // The dialog is laid out in the NIB exactly how we want it assuming that | 209     // The dialog is laid out in the NIB exactly how we want it assuming that | 
| 161     // each label fits on one line. However, for each label, we want to allow | 210     // each label fits on one line. However, for each label, we want to allow | 
| 162     // wrapping onto multiple lines. So we accumulate an offset by measuring how | 211     // wrapping onto multiple lines. So we accumulate an offset by measuring how | 
| 163     // big each label wants to be, and comparing it to how bit it actually is. | 212     // big each label wants to be, and comparing it to how big it actually is. | 
| 164     // Then we shift each label down and resize by the appropriate amount, then | 213     // Then we shift each label down and resize by the appropriate amount, then | 
| 165     // finally resize the window. | 214     // finally resize the window. | 
| 166     CGFloat totalOffset = 0.0; |  | 
| 167 | 215 | 
| 168     // Text fields. | 216     // Additionally, in the store version of the dialog the icon extends past | 
| 169     totalOffset += AdjustControlHeightToFitContent(titleField_); | 217     // the one-line version of the permission field. Therefore when increasing | 
| 170     OffsetControlVertically(titleField_, -totalOffset); | 218     // the window size for multi-line permissions we don't have to add the full | 
|  | 219     // offset, only the part that extends past the icon. | 
|  | 220     CGFloat warningsGrowthSlack = 0; | 
|  | 221     if ([warningsField_ frame].origin.y > [iconView_ frame].origin.y) { | 
|  | 222       warningsGrowthSlack = | 
|  | 223           [warningsField_ frame].origin.y - [iconView_ frame].origin.y; | 
|  | 224     } | 
| 171 | 225 | 
| 172     totalOffset += AdjustControlHeightToFitContent(subtitleField_); | 226     totalOffset += AdjustControlHeightToFitContent(subtitleField_); | 
| 173     OffsetControlVertically(subtitleField_, -totalOffset); | 227     OffsetControlVertically(subtitleField_, -totalOffset); | 
| 174 | 228 | 
| 175     CGFloat warningsOffset = AdjustControlHeightToFitContent(warningsField_); | 229     totalOffset += AdjustControlHeightToFitContent(warningsField_); | 
| 176     OffsetControlVertically(warningsField_, -warningsOffset); | 230     OffsetControlVertically(warningsField_, -totalOffset); | 
| 177     totalOffset += warningsOffset; | 231     totalOffset = MAX(totalOffset - warningsGrowthSlack, 0); | 
|  | 232   } else if ([self isInlineInstall]) { | 
|  | 233     // Inline installs that don't have a permissions section need to hide | 
|  | 234     // controls related to that and shrink the window by the space they take | 
|  | 235     // up. | 
|  | 236     NSRect hiddenRect = NSUnionRect([warningsSeparator_ frame], | 
|  | 237                                     [subtitleField_ frame]); | 
|  | 238     hiddenRect = NSUnionRect(hiddenRect, [warningsField_ frame]); | 
|  | 239     [warningsSeparator_ setHidden:YES]; | 
|  | 240     [subtitleField_ setHidden:YES]; | 
|  | 241     [warningsField_ setHidden:YES]; | 
|  | 242     totalOffset -= hiddenRect.size.height + kWarningsSeparatorPadding; | 
|  | 243   } | 
| 178 | 244 | 
| 179     NSRect warningsBoxRect = [warningsBox_ frame]; | 245   // If necessary, adjust the window size. | 
| 180     warningsBoxRect.origin.y -= totalOffset; | 246   if (totalOffset) { | 
| 181     warningsBoxRect.size.height += warningsOffset; |  | 
| 182     [warningsBox_ setFrame:warningsBoxRect]; |  | 
| 183 |  | 
| 184     // buttons are positioned automatically in the XIB. |  | 
| 185 |  | 
| 186     // Finally, adjust the window size. |  | 
| 187     NSRect currentRect = [[self window] frame]; | 247     NSRect currentRect = [[self window] frame]; | 
| 188     [[self window] setFrame:NSMakeRect(currentRect.origin.x, | 248     [[self window] setFrame:NSMakeRect(currentRect.origin.x, | 
| 189                                        currentRect.origin.y - totalOffset, | 249                                        currentRect.origin.y - totalOffset, | 
| 190                                        currentRect.size.width, | 250                                        currentRect.size.width, | 
| 191                                        currentRect.size.height + totalOffset) | 251                                        currentRect.size.height + totalOffset) | 
| 192                     display:NO]; | 252                    display:NO]; | 
| 193   } | 253   } | 
| 194 } | 254 } | 
| 195 | 255 | 
| 196 - (void)didEndSheet:(NSWindow*)sheet | 256 - (void)didEndSheet:(NSWindow*)sheet | 
| 197          returnCode:(int)returnCode | 257          returnCode:(int)returnCode | 
| 198         contextInfo:(void*)contextInfo { | 258         contextInfo:(void*)contextInfo { | 
| 199   [sheet close]; | 259   [sheet close]; | 
| 200 } | 260 } | 
| 201 | 261 | 
| 202 - (void)windowWillClose:(NSNotification*)notification { | 262 - (void)windowWillClose:(NSNotification*)notification { | 
| 203   [self autorelease]; | 263   [self autorelease]; | 
| 204 } | 264 } | 
| 205 | 265 | 
|  | 266 - (bool)isInlineInstall { | 
|  | 267   return prompt_->type() == ExtensionInstallUI::INLINE_INSTALL_PROMPT; | 
|  | 268 } | 
|  | 269 | 
|  | 270 - (void)appendRatingStar:(const SkBitmap*)skiaImage { | 
|  | 271   NSImage* image = gfx::SkBitmapToNSImageWithColorSpace( | 
|  | 272       *skiaImage, base::mac::GetSystemColorSpace()); | 
|  | 273   NSRect frame = NSMakeRect(0, 0, skiaImage->width(), skiaImage->height()); | 
|  | 274   scoped_nsobject<NSImageView> view([[NSImageView alloc] initWithFrame:frame]); | 
|  | 275   [view setImage:image]; | 
|  | 276 | 
|  | 277   // Add this star after all the other ones | 
|  | 278   CGFloat maxStarRight = 0; | 
|  | 279   if ([[ratingStars_ subviews] count]) { | 
|  | 280     maxStarRight = NSMaxX([[[ratingStars_ subviews] lastObject] frame]); | 
|  | 281   } | 
|  | 282   NSRect starBounds = NSMakeRect(maxStarRight, 0, | 
|  | 283                                  skiaImage->width(), skiaImage->height()); | 
|  | 284   [view setFrame:starBounds]; | 
|  | 285   [ratingStars_ addSubview:view]; | 
|  | 286 } | 
|  | 287 | 
| 206 @end  // ExtensionInstallDialogController | 288 @end  // ExtensionInstallDialogController | 
| 207 | 289 | 
| 208 void ShowExtensionInstallDialog( | 290 void ShowExtensionInstallDialog( | 
| 209     Profile* profile, | 291     Profile* profile, | 
| 210     ExtensionInstallUI::Delegate* delegate, | 292     ExtensionInstallUI::Delegate* delegate, | 
| 211     const Extension* extension, | 293     const Extension* extension, | 
| 212     SkBitmap* icon, | 294     SkBitmap* icon, | 
| 213     const ExtensionInstallUI::Prompt& prompt) { | 295     const ExtensionInstallUI::Prompt& prompt) { | 
| 214   Browser* browser = BrowserList::GetLastActiveWithProfile(profile); | 296   Browser* browser = BrowserList::GetLastActiveWithProfile(profile); | 
| 215   if (!browser) { | 297   if (!browser) { | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 227 | 309 | 
| 228   ExtensionInstallDialogController* controller = | 310   ExtensionInstallDialogController* controller = | 
| 229       [[ExtensionInstallDialogController alloc] | 311       [[ExtensionInstallDialogController alloc] | 
| 230         initWithParentWindow:native_window | 312         initWithParentWindow:native_window | 
| 231                      profile:profile | 313                      profile:profile | 
| 232                    extension:extension | 314                    extension:extension | 
| 233                     delegate:delegate | 315                     delegate:delegate | 
| 234                         icon:icon | 316                         icon:icon | 
| 235                       prompt:prompt]; | 317                       prompt:prompt]; | 
| 236 | 318 | 
|  | 319   // TODO(mihaip): Switch this to be tab-modal (http://crbug.com/95455) | 
| 237   [controller runAsModalSheet]; | 320   [controller runAsModalSheet]; | 
| 238 } | 321 } | 
| OLD | NEW | 
|---|