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_install_view_controller.h" | 5 #import "chrome/browser/ui/cocoa/extensions/extension_install_view_controller.h" |
6 | 6 |
7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
8 #include "base/i18n/rtl.h" | 8 #include "base/i18n/rtl.h" |
9 #include "base/mac/bundle_locations.h" | 9 #include "base/mac/bundle_locations.h" |
10 #include "base/mac/mac_util.h" | 10 #include "base/mac/mac_util.h" |
11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
12 #include "base/strings/sys_string_conversions.h" | 12 #include "base/strings/sys_string_conversions.h" |
13 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
14 #include "chrome/browser/extensions/bundle_installer.h" | 14 #include "chrome/browser/extensions/bundle_installer.h" |
15 #include "chrome/browser/profiles/profile.h" | 15 #include "chrome/browser/profiles/profile.h" |
16 #include "chrome/browser/ui/browser.h" | 16 #include "chrome/browser/ui/browser.h" |
17 #import "chrome/browser/ui/chrome_style.h" | 17 #import "chrome/browser/ui/chrome_style.h" |
| 18 #include "chrome/browser/ui/cocoa/extensions/bundle_util.h" |
18 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" | 19 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" |
19 #include "chrome/common/extensions/extension_constants.h" | 20 #include "chrome/common/extensions/extension_constants.h" |
20 #include "chrome/grit/generated_resources.h" | 21 #include "chrome/grit/generated_resources.h" |
21 #include "content/public/browser/page_navigator.h" | 22 #include "content/public/browser/page_navigator.h" |
22 #include "extensions/common/extension.h" | 23 #include "extensions/common/extension.h" |
23 #include "extensions/common/extension_urls.h" | 24 #include "extensions/common/extension_urls.h" |
24 #include "skia/ext/skia_utils_mac.h" | 25 #include "skia/ext/skia_utils_mac.h" |
25 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTw
eaker.h" | 26 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTw
eaker.h" |
26 #import "ui/base/cocoa/controls/hyperlink_button_cell.h" | 27 #import "ui/base/cocoa/controls/hyperlink_button_cell.h" |
27 #include "ui/base/l10n/l10n_util.h" | 28 #include "ui/base/l10n/l10n_util.h" |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 // Maximum height we will adjust controls to when trying to accomodate their | 96 // Maximum height we will adjust controls to when trying to accomodate their |
96 // contents. | 97 // contents. |
97 const CGFloat kMaxControlHeight = 250; | 98 const CGFloat kMaxControlHeight = 250; |
98 | 99 |
99 NSString* const kTitleKey = @"title"; | 100 NSString* const kTitleKey = @"title"; |
100 NSString* const kChildrenKey = @"children"; | 101 NSString* const kChildrenKey = @"children"; |
101 NSString* const kCellAttributesKey = @"cellAttributes"; | 102 NSString* const kCellAttributesKey = @"cellAttributes"; |
102 NSString* const kPermissionsDetailIndex = @"permissionsDetailIndex"; | 103 NSString* const kPermissionsDetailIndex = @"permissionsDetailIndex"; |
103 NSString* const kPermissionsDetailType = @"permissionsDetailType"; | 104 NSString* const kPermissionsDetailType = @"permissionsDetailType"; |
104 | 105 |
| 106 // Computes the |control|'s desired height to fit its contents, constrained to |
| 107 // be kMaxControlHeight at most. |
| 108 CGFloat ComputeDesiredControlHeight(NSControl* control) { |
| 109 NSRect rect = [control frame]; |
| 110 rect.size.height = kMaxControlHeight; |
| 111 return [[control cell] cellSizeForBounds:rect].height; |
| 112 } |
| 113 |
105 // Adjust the |control|'s height so that its content is not clipped. | 114 // Adjust the |control|'s height so that its content is not clipped. |
106 // This also adds the change in height to the |totalOffset| and shifts the | 115 // This also adds the change in height to the |total_offset| and shifts the |
107 // control down by that amount. | 116 // control down by that amount. |
108 void OffsetControlVerticallyToFitContent(NSControl* control, | 117 void OffsetControlVerticallyToFitContent(NSControl* control, |
109 CGFloat* totalOffset) { | 118 CGFloat* total_offset) { |
110 // Adjust the control's height so that its content is not clipped. | 119 // Adjust the control's height so that its content is not clipped. |
111 NSRect currentRect = [control frame]; | 120 NSRect current_rect = [control frame]; |
112 NSRect fitRect = currentRect; | 121 CGFloat desired_height = ComputeDesiredControlHeight(control); |
113 fitRect.size.height = kMaxControlHeight; | 122 CGFloat offset = desired_height - NSHeight(current_rect); |
114 CGFloat desiredHeight = [[control cell] cellSizeForBounds:fitRect].height; | |
115 CGFloat offset = desiredHeight - NSHeight(currentRect); | |
116 | 123 |
117 [control setFrameSize:NSMakeSize(NSWidth(currentRect), | 124 [control setFrameSize:NSMakeSize(NSWidth(current_rect), |
118 NSHeight(currentRect) + offset)]; | 125 NSHeight(current_rect) + offset)]; |
119 | 126 |
120 *totalOffset += offset; | 127 *total_offset += offset; |
121 | 128 |
122 // Move the control vertically by the new total offset. | 129 // Move the control vertically by the new total offset. |
123 NSPoint origin = [control frame].origin; | 130 NSPoint origin = [control frame].origin; |
124 origin.y -= *totalOffset; | 131 origin.y -= *total_offset; |
125 [control setFrameOrigin:origin]; | 132 [control setFrameOrigin:origin]; |
126 } | 133 } |
127 | 134 |
128 // Gets the desired height of |outlineView|. Simply using the view's frame | 135 // Adjust the |view|'s height so that its subviews are not clipped. |
| 136 // This also adds the change in height to the |total_offset| and shifts the |
| 137 // control down by that amount. |
| 138 void OffsetViewVerticallyToFitContent(NSView* view, CGFloat* total_offset) { |
| 139 // Adjust the view's height so that its subviews are not clipped. |
| 140 CGFloat desired_height = 0; |
| 141 for (NSView* subview in [view subviews]) { |
| 142 int required_height = NSMaxY([subview frame]); |
| 143 if (required_height > desired_height) |
| 144 desired_height = required_height; |
| 145 } |
| 146 NSRect current_rect = [view frame]; |
| 147 CGFloat offset = desired_height - NSHeight(current_rect); |
| 148 |
| 149 [view setFrameSize:NSMakeSize(NSWidth(current_rect), |
| 150 NSHeight(current_rect) + offset)]; |
| 151 |
| 152 *total_offset += offset; |
| 153 |
| 154 // Move the view vertically by the new total offset. |
| 155 NSPoint origin = [view frame].origin; |
| 156 origin.y -= *total_offset; |
| 157 [view setFrameOrigin:origin]; |
| 158 } |
| 159 |
| 160 // Gets the desired height of |outline_view|. Simply using the view's frame |
129 // doesn't work if an animation is pending. | 161 // doesn't work if an animation is pending. |
130 CGFloat GetDesiredOutlineViewHeight(NSOutlineView* outlineView) { | 162 CGFloat GetDesiredOutlineViewHeight(NSOutlineView* outline_view) { |
131 CGFloat height = 0; | 163 CGFloat height = 0; |
132 for (NSInteger i = 0; i < [outlineView numberOfRows]; ++i) | 164 for (NSInteger i = 0; i < [outline_view numberOfRows]; ++i) |
133 height += NSHeight([outlineView rectOfRow:i]); | 165 height += NSHeight([outline_view rectOfRow:i]); |
134 return height; | 166 return height; |
135 } | 167 } |
136 | 168 |
137 void OffsetOutlineViewVerticallyToFitContent(NSOutlineView* outlineView, | 169 void OffsetOutlineViewVerticallyToFitContent(NSOutlineView* outline_view, |
138 CGFloat* totalOffset) { | 170 CGFloat* total_offset) { |
139 NSScrollView* scrollView = [outlineView enclosingScrollView]; | 171 NSScrollView* scroll_view = [outline_view enclosingScrollView]; |
140 NSRect frame = [scrollView frame]; | 172 NSRect frame = [scroll_view frame]; |
141 CGFloat desiredHeight = GetDesiredOutlineViewHeight(outlineView); | 173 CGFloat desired_height = GetDesiredOutlineViewHeight(outline_view); |
142 if (desiredHeight > kMaxControlHeight) | 174 if (desired_height > kMaxControlHeight) |
143 desiredHeight = kMaxControlHeight; | 175 desired_height = kMaxControlHeight; |
144 CGFloat offset = desiredHeight - NSHeight(frame); | 176 CGFloat offset = desired_height - NSHeight(frame); |
145 frame.size.height += offset; | 177 frame.size.height += offset; |
146 | 178 |
147 *totalOffset += offset; | 179 *total_offset += offset; |
148 | 180 |
149 // Move the control vertically by the new total offset. | 181 // Move the control vertically by the new total offset. |
150 frame.origin.y -= *totalOffset; | 182 frame.origin.y -= *total_offset; |
151 [scrollView setFrame:frame]; | 183 [scroll_view setFrame:frame]; |
152 } | 184 } |
153 | 185 |
154 void AppendRatingStarsShim(const gfx::ImageSkia* skiaImage, void* data) { | 186 void AppendRatingStarsShim(const gfx::ImageSkia* skia_image, void* data) { |
155 ExtensionInstallViewController* controller = | 187 ExtensionInstallViewController* controller = |
156 static_cast<ExtensionInstallViewController*>(data); | 188 static_cast<ExtensionInstallViewController*>(data); |
157 [controller appendRatingStar:skiaImage]; | 189 [controller appendRatingStar:skia_image]; |
158 } | 190 } |
159 | 191 |
160 void DrawBulletInFrame(NSRect frame) { | 192 void DrawBulletInFrame(NSRect frame) { |
161 NSRect rect; | 193 NSRect rect; |
162 rect.size.width = std::min(NSWidth(frame), NSHeight(frame)) * 0.25; | 194 rect.size.width = std::min(NSWidth(frame), NSHeight(frame)) * 0.25; |
163 rect.size.height = NSWidth(rect); | 195 rect.size.height = NSWidth(rect); |
164 rect.origin.x = frame.origin.x + (NSWidth(frame) - NSWidth(rect)) / 2.0; | 196 rect.origin.x = frame.origin.x + (NSWidth(frame) - NSWidth(rect)) / 2.0; |
165 rect.origin.y = frame.origin.y + (NSHeight(frame) - NSHeight(rect)) / 2.0; | 197 rect.origin.y = frame.origin.y + (NSHeight(frame) - NSHeight(rect)) / 2.0; |
166 rect = NSIntegralRect(rect); | 198 rect = NSIntegralRect(rect); |
167 | 199 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 prompt_->AppendRatingStars(AppendRatingStarsShim, self); | 295 prompt_->AppendRatingStars(AppendRatingStarsShim, self); |
264 [ratingCountField_ setStringValue:base::SysUTF16ToNSString( | 296 [ratingCountField_ setStringValue:base::SysUTF16ToNSString( |
265 prompt_->GetRatingCount())]; | 297 prompt_->GetRatingCount())]; |
266 [userCountField_ setStringValue:base::SysUTF16ToNSString( | 298 [userCountField_ setStringValue:base::SysUTF16ToNSString( |
267 prompt_->GetUserCount())]; | 299 prompt_->GetUserCount())]; |
268 [[storeLinkButton_ cell] setUnderlineOnHover:YES]; | 300 [[storeLinkButton_ cell] setUnderlineOnHover:YES]; |
269 [[storeLinkButton_ cell] setTextColor: | 301 [[storeLinkButton_ cell] setTextColor: |
270 gfx::SkColorToCalibratedNSColor(chrome_style::GetLinkColor())]; | 302 gfx::SkColorToCalibratedNSColor(chrome_style::GetLinkColor())]; |
271 } | 303 } |
272 | 304 |
273 // The bundle install dialog has no icon. | 305 [iconView_ setImage:prompt_->icon().ToNSImage()]; |
274 if (![self isBundleInstall]) | |
275 [iconView_ setImage:prompt_->icon().ToNSImage()]; | |
276 | 306 |
277 // The dialog is laid out in the NIB exactly how we want it assuming that | 307 // The dialog is laid out in the NIB exactly how we want it assuming that |
278 // each label fits on one line. However, for each label, we want to allow | 308 // each label fits on one line. However, for each label, we want to allow |
279 // wrapping onto multiple lines. So we accumulate an offset by measuring how | 309 // wrapping onto multiple lines. So we accumulate an offset by measuring how |
280 // big each label wants to be, and comparing it to how big it actually is. | 310 // big each label wants to be, and comparing it to how big it actually is. |
281 // Then we shift each label down and resize by the appropriate amount, then | 311 // Then we shift each label down and resize by the appropriate amount, then |
282 // finally resize the window. | 312 // finally resize the window. |
283 CGFloat totalOffset = 0.0; | 313 CGFloat totalOffset = 0.0; |
284 | 314 |
285 OffsetControlVerticallyToFitContent(titleField_, &totalOffset); | 315 OffsetControlVerticallyToFitContent(titleField_, &totalOffset); |
(...skipping 16 matching lines...) Expand all Loading... |
302 NSMaxX(okButtonRect) - NSWidth(cancelButtonRect); | 332 NSMaxX(okButtonRect) - NSWidth(cancelButtonRect); |
303 [cancelButton_ setFrame:cancelButtonRect]; | 333 [cancelButton_ setFrame:cancelButtonRect]; |
304 } | 334 } |
305 buttonDelta = [GTMUILocalizerAndLayoutTweaker sizeToFitView:cancelButton_]; | 335 buttonDelta = [GTMUILocalizerAndLayoutTweaker sizeToFitView:cancelButton_]; |
306 if (buttonDelta.width) { | 336 if (buttonDelta.width) { |
307 [cancelButton_ setFrame:NSOffsetRect([cancelButton_ frame], | 337 [cancelButton_ setFrame:NSOffsetRect([cancelButton_ frame], |
308 -buttonDelta.width, 0)]; | 338 -buttonDelta.width, 0)]; |
309 } | 339 } |
310 | 340 |
311 if ([self isBundleInstall]) { | 341 if ([self isBundleInstall]) { |
312 // We display the list of extension names as a simple text string, seperated | |
313 // by newlines. | |
314 BundleInstaller::ItemList items = prompt_->bundle()->GetItemsWithState( | 342 BundleInstaller::ItemList items = prompt_->bundle()->GetItemsWithState( |
315 BundleInstaller::Item::STATE_PENDING); | 343 BundleInstaller::Item::STATE_PENDING); |
| 344 PopulateBundleItemsList(items, itemsField_); |
316 | 345 |
317 NSMutableString* joinedItems = [NSMutableString string]; | 346 // Adjust the view to fit the list of extensions. |
318 for (size_t i = 0; i < items.size(); ++i) { | 347 OffsetViewVerticallyToFitContent(itemsField_, &totalOffset); |
319 if (i > 0) | |
320 [joinedItems appendString:@"\n"]; | |
321 [joinedItems appendString:base::SysUTF16ToNSString( | |
322 items[i].GetNameForDisplay())]; | |
323 } | |
324 [itemsField_ setStringValue:joinedItems]; | |
325 | |
326 // Adjust the controls to fit the list of extensions. | |
327 OffsetControlVerticallyToFitContent(itemsField_, &totalOffset); | |
328 } | 348 } |
329 | 349 |
330 // If there are any warnings, retained devices or retained files, then we | 350 // If there are any warnings, retained devices or retained files, then we |
331 // have to do some special layout. | 351 // have to do some special layout. |
332 if (prompt_->ShouldShowPermissions() || prompt_->GetRetainedFileCount() > 0) { | 352 if (prompt_->ShouldShowPermissions() || prompt_->GetRetainedFileCount() > 0) { |
333 NSSize spacing = [outlineView_ intercellSpacing]; | 353 NSSize spacing = [outlineView_ intercellSpacing]; |
334 spacing.width += 2; | 354 spacing.width += 2; |
335 spacing.height += 2; | 355 spacing.height += 2; |
336 [outlineView_ setIntercellSpacing:spacing]; | 356 [outlineView_ setIntercellSpacing:spacing]; |
337 [[[[outlineView_ tableColumns] objectAtIndex:0] dataCell] setWraps:YES]; | 357 [[[[outlineView_ tableColumns] objectAtIndex:0] dataCell] setWraps:YES]; |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
814 } | 834 } |
815 | 835 |
816 - (void)accessibilityPerformAction:(NSString*)action { | 836 - (void)accessibilityPerformAction:(NSString*)action { |
817 if ([action isEqualToString:NSAccessibilityPressAction]) | 837 if ([action isEqualToString:NSAccessibilityPressAction]) |
818 [self handleLinkClicked]; | 838 [self handleLinkClicked]; |
819 else | 839 else |
820 [super accessibilityPerformAction:action]; | 840 [super accessibilityPerformAction:action]; |
821 } | 841 } |
822 | 842 |
823 @end | 843 @end |
OLD | NEW |