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

Side by Side Diff: chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm

Issue 10829170: Cocoa: Show OAuth issues in extension install dialog (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: test Created 8 years, 4 months 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
OLDNEW
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_dialog_controller. h" 5 #import "chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller. 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/memory/scoped_nsobject.h" 10 #include "base/memory/scoped_nsobject.h"
(...skipping 11 matching lines...) Expand all
22 #include "ui/base/l10n/l10n_util_mac.h" 22 #include "ui/base/l10n/l10n_util_mac.h"
23 23
24 using content::OpenURLParams; 24 using content::OpenURLParams;
25 using content::Referrer; 25 using content::Referrer;
26 using extensions::BundleInstaller; 26 using extensions::BundleInstaller;
27 27
28 @interface ExtensionInstallDialogController () 28 @interface ExtensionInstallDialogController ()
29 - (BOOL)isBundleInstall; 29 - (BOOL)isBundleInstall;
30 - (BOOL)isInlineInstall; 30 - (BOOL)isInlineInstall;
31 - (void)appendRatingStar:(const gfx::ImageSkia*)skiaImage; 31 - (void)appendRatingStar:(const gfx::ImageSkia*)skiaImage;
32 - (void)onOutlineViewRowCountDidChange;
32 @end 33 @end
33 34
34 namespace { 35 namespace {
35 36
36 // Padding above the warnings separator, we must also subtract this when hiding 37 // Padding above the warnings separator, we must also subtract this when hiding
37 // it. 38 // it.
38 const CGFloat kWarningsSeparatorPadding = 14; 39 const CGFloat kWarningsSeparatorPadding = 14;
39 40
40 // Maximum height we will adjust controls to when trying to accomodate their 41 // Maximum height we will adjust controls to when trying to accomodate their
41 // contents. 42 // contents.
42 const CGFloat kMaxControlHeight = 400; 43 const CGFloat kMaxControlHeight = 400;
43 44
45 const NSString* kTitleKey = @"title";
46 const NSString* kIsGroupItemKey = @"isGroupItem";
47 const NSString* kChildrenKey = @"children";
48 const NSString* kCanExpandKey = @"canExpand";
49
44 // Adjust the |control|'s height so that its content is not clipped. 50 // Adjust the |control|'s height so that its content is not clipped.
45 // This also adds the change in height to the |totalOffset| and shifts the 51 // This also adds the change in height to the |totalOffset| and shifts the
46 // control down by that amount. 52 // control down by that amount.
47 void OffsetControlVerticallyToFitContent(NSControl* control, 53 void OffsetControlVerticallyToFitContent(NSControl* control,
48 CGFloat* totalOffset) { 54 CGFloat* totalOffset) {
49 // Adjust the control's height so that its content is not clipped. 55 // Adjust the control's height so that its content is not clipped.
50 NSRect currentRect = [control frame]; 56 NSRect currentRect = [control frame];
51 NSRect fitRect = currentRect; 57 NSRect fitRect = currentRect;
52 fitRect.size.height = kMaxControlHeight; 58 fitRect.size.height = kMaxControlHeight;
53 CGFloat desiredHeight = [[control cell] cellSizeForBounds:fitRect].height; 59 CGFloat desiredHeight = [[control cell] cellSizeForBounds:fitRect].height;
54 CGFloat offset = desiredHeight - currentRect.size.height; 60 CGFloat offset = desiredHeight - currentRect.size.height;
55 61
56 [control setFrameSize:NSMakeSize(currentRect.size.width, 62 [control setFrameSize:NSMakeSize(currentRect.size.width,
57 currentRect.size.height + offset)]; 63 currentRect.size.height + offset)];
58 64
59 *totalOffset += offset; 65 *totalOffset += offset;
60 66
61 // Move the control vertically by the new total offset. 67 // Move the control vertically by the new total offset.
62 NSPoint origin = [control frame].origin; 68 NSPoint origin = [control frame].origin;
63 origin.y -= *totalOffset; 69 origin.y -= *totalOffset;
64 [control setFrameOrigin:origin]; 70 [control setFrameOrigin:origin];
65 } 71 }
66 72
73 // Gets the desired height of |outlineView|. Simply using the view's frame
74 // doesn't work if an animation is pending.
75 CGFloat GetDesiredOutlineViewHeight(NSOutlineView* outlineView) {
76 CGFloat height = 0;
77 for (NSInteger i = 0; i < [outlineView numberOfRows]; ++i)
78 height += [outlineView rectOfRow:i].size.height;
79 return height;
80 }
81
82 void OffsetOutlineViewVerticallyToFitContent(NSOutlineView* outlineView,
83 CGFloat* totalOffset) {
84 NSScrollView* scrollView = [outlineView enclosingScrollView];
85 NSRect frame = [scrollView frame];
86 CGFloat desiredHeight = GetDesiredOutlineViewHeight(outlineView);
87 CGFloat offset = desiredHeight - frame.size.height;
88 frame.size.height += offset;
89
90 *totalOffset += offset;
91
92 // Move the control vertically by the new total offset.
93 frame.origin.y -= *totalOffset;
94 [scrollView setFrame:frame];
95 }
96
67 void AppendRatingStarsShim(const gfx::ImageSkia* skiaImage, void* data) { 97 void AppendRatingStarsShim(const gfx::ImageSkia* skiaImage, void* data) {
68 ExtensionInstallDialogController* controller = 98 ExtensionInstallDialogController* controller =
69 static_cast<ExtensionInstallDialogController*>(data); 99 static_cast<ExtensionInstallDialogController*>(data);
70 [controller appendRatingStar:skiaImage]; 100 [controller appendRatingStar:skiaImage];
71 } 101 }
72 102
103 NSDictionary* BuildItem(NSString* title, BOOL isGroupItem, NSArray* children) {
104 BOOL canExpand = YES;
105 if (!children) {
106 // Add a dummy child even though this is a leaf node. This will cause
107 // the outline view to show a disclosure triangle for this item.
108 // This is later overriden in willDisplayOutlineCell: to draw a bullet
109 // instead. (The bullet could be placed in the title instead but then
110 // the bullet wouldn't line up with disclosure triangles of sibling nodes.)
111 children = [NSArray arrayWithObject:[NSDictionary dictionary]];
112 canExpand = false;
113 }
114
115 return [NSDictionary dictionaryWithObjectsAndKeys:
116 title, kTitleKey,
117 [NSNumber numberWithBool:isGroupItem], kIsGroupItemKey,
118 children, kChildrenKey,
119 [NSNumber numberWithBool:canExpand], kCanExpandKey,
120 nil];
121 }
122
123 NSDictionary* BuildIssue(const IssueAdviceInfoEntry& issue) {
124 if (issue.details.empty())
125 return BuildItem(SysUTF16ToNSString(issue.description), NO, nil);
126
127 NSMutableArray* details = [NSMutableArray array];
128 for (size_t j = 0; j < issue.details.size(); ++j) {
129 [details addObject:BuildItem(
130 SysUTF16ToNSString(issue.details[j]), NO, nil)];
131 }
132 return BuildItem(SysUTF16ToNSString(issue.description), NO, details);
133 }
134
135 NSArray* BuildWarnings(const ExtensionInstallPrompt::Prompt& prompt) {
136 NSMutableArray* warnings = [NSMutableArray array];
137
138 if (prompt.GetPermissionCount() > 0) {
139 NSMutableArray* children = [NSMutableArray array];
140 for (size_t i = 0; i < prompt.GetPermissionCount(); ++i) {
141 [children addObject:BuildItem(
142 SysUTF16ToNSString(prompt.GetPermission(i)), NO, nil)];
143 }
144 [warnings addObject:BuildItem(
145 SysUTF16ToNSString(prompt.GetPermissionsHeading()), YES, children)];
146 }
147
148 if (prompt.GetOAuthIssueCount() > 0) {
149 NSMutableArray* children = [NSMutableArray array];
150 for (size_t i = 0; i < prompt.GetOAuthIssueCount(); ++i)
151 [children addObject:BuildIssue(prompt.GetOAuthIssue(i))];
152 [warnings addObject:BuildItem(
153 SysUTF16ToNSString(prompt.GetOAuthHeading()), YES, children)];
154 }
155
156 return warnings;
157 }
158
159 void DrawBulletInFrame(NSRect frame) {
160 NSRect rect;
161 rect.size.width = std::min(frame.size.width, frame.size.height) * 0.38;
162 rect.size.height = rect.size.width;
163 rect.origin.x = frame.origin.x + (frame.size.width - rect.size.width) / 2.0;
164 rect.origin.y = frame.origin.y + (frame.size.height - rect.size.height) / 2.0;
165 rect = NSIntegralRect(rect);
166
167 [[NSColor colorWithCalibratedWhite:0.0 alpha:0.42] set];
168 [[NSBezierPath bezierPathWithOvalInRect:rect] fill];
169 }
170
73 } 171 }
74 172
75 @implementation ExtensionInstallDialogController 173 @implementation ExtensionInstallDialogController
76 174
77 @synthesize iconView = iconView_; 175 @synthesize iconView = iconView_;
78 @synthesize titleField = titleField_; 176 @synthesize titleField = titleField_;
79 @synthesize itemsField = itemsField_; 177 @synthesize itemsField = itemsField_;
80 @synthesize subtitleField = subtitleField_;
81 @synthesize warningsField = warningsField_;
82 @synthesize cancelButton = cancelButton_; 178 @synthesize cancelButton = cancelButton_;
83 @synthesize okButton = okButton_; 179 @synthesize okButton = okButton_;
180 @synthesize outlineView = outlineView_;
84 @synthesize warningsSeparator = warningsSeparator_; 181 @synthesize warningsSeparator = warningsSeparator_;
85 @synthesize ratingStars = ratingStars_; 182 @synthesize ratingStars = ratingStars_;
86 @synthesize ratingCountField = ratingCountField_; 183 @synthesize ratingCountField = ratingCountField_;
87 @synthesize userCountField = userCountField_; 184 @synthesize userCountField = userCountField_;
88 185
89 - (id)initWithParentWindow:(NSWindow*)window 186 - (id)initWithParentWindow:(NSWindow*)window
90 navigator:(content::PageNavigator*)navigator 187 navigator:(content::PageNavigator*)navigator
91 delegate:(ExtensionInstallPrompt::Delegate*)delegate 188 delegate:(ExtensionInstallPrompt::Delegate*)delegate
92 prompt:(const ExtensionInstallPrompt::Prompt&)prompt { 189 prompt:(const ExtensionInstallPrompt::Prompt&)prompt {
93 NSString* nibpath = nil; 190 NSString* nibpath = nil;
191 warnings_.reset([BuildWarnings(prompt) retain]);
94 192
95 // We use a different XIB in the case of bundle installs, inline installs or 193 // We use a different XIB in the case of bundle installs, inline installs or
96 // no permission warnings. These are laid out nicely for the data they 194 // no permission warnings. These are laid out nicely for the data they
97 // display. 195 // display.
98 if (prompt.type() == ExtensionInstallPrompt::BUNDLE_INSTALL_PROMPT) { 196 if (prompt.type() == ExtensionInstallPrompt::BUNDLE_INSTALL_PROMPT) {
99 nibpath = [base::mac::FrameworkBundle() 197 nibpath = [base::mac::FrameworkBundle()
100 pathForResource:@"ExtensionInstallPromptBundle" 198 pathForResource:@"ExtensionInstallPromptBundle"
101 ofType:@"nib"]; 199 ofType:@"nib"];
102 } else if (prompt.type() == ExtensionInstallPrompt::INLINE_INSTALL_PROMPT) { 200 } else if (prompt.type() == ExtensionInstallPrompt::INLINE_INSTALL_PROMPT) {
103 nibpath = [base::mac::FrameworkBundle() 201 nibpath = [base::mac::FrameworkBundle()
104 pathForResource:@"ExtensionInstallPromptInline" 202 pathForResource:@"ExtensionInstallPromptInline"
105 ofType:@"nib"]; 203 ofType:@"nib"];
106 } else if (prompt.GetPermissionCount() == 0) { 204 } else if (prompt.GetPermissionCount() == 0 &&
205 prompt.GetOAuthIssueCount() == 0) {
107 nibpath = [base::mac::FrameworkBundle() 206 nibpath = [base::mac::FrameworkBundle()
108 pathForResource:@"ExtensionInstallPromptNoWarnings" 207 pathForResource:@"ExtensionInstallPromptNoWarnings"
109 ofType:@"nib"]; 208 ofType:@"nib"];
110 } else { 209 } else {
111 nibpath = [base::mac::FrameworkBundle() 210 nibpath = [base::mac::FrameworkBundle()
112 pathForResource:@"ExtensionInstallPrompt" 211 pathForResource:@"ExtensionInstallPrompt"
113 ofType:@"nib"]; 212 ofType:@"nib"];
114 } 213 }
115 214
116 if ((self = [super initWithWindowNibPath:nibpath owner:self])) { 215 if ((self = [super initWithWindowNibPath:nibpath owner:self])) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 [cancelButton_ setFrame:NSOffsetRect([cancelButton_ frame], 292 [cancelButton_ setFrame:NSOffsetRect([cancelButton_ frame],
194 -buttonDelta.width, 0)]; 293 -buttonDelta.width, 0)];
195 } 294 }
196 buttonDelta = [GTMUILocalizerAndLayoutTweaker sizeToFitView:cancelButton_]; 295 buttonDelta = [GTMUILocalizerAndLayoutTweaker sizeToFitView:cancelButton_];
197 if (buttonDelta.width) { 296 if (buttonDelta.width) {
198 [cancelButton_ setFrame:NSOffsetRect([cancelButton_ frame], 297 [cancelButton_ setFrame:NSOffsetRect([cancelButton_ frame],
199 -buttonDelta.width, 0)]; 298 -buttonDelta.width, 0)];
200 } 299 }
201 300
202 if ([self isBundleInstall]) { 301 if ([self isBundleInstall]) {
203 [subtitleField_ setStringValue:base::SysUTF16ToNSString(
204 prompt_->GetPermissionsHeading())];
205
206 // We display the list of extension names as a simple text string, seperated 302 // We display the list of extension names as a simple text string, seperated
207 // by newlines. 303 // by newlines.
208 BundleInstaller::ItemList items = prompt_->bundle()->GetItemsWithState( 304 BundleInstaller::ItemList items = prompt_->bundle()->GetItemsWithState(
209 BundleInstaller::Item::STATE_PENDING); 305 BundleInstaller::Item::STATE_PENDING);
210 306
211 NSMutableString* joinedItems = [NSMutableString string]; 307 NSMutableString* joinedItems = [NSMutableString string];
212 for (size_t i = 0; i < items.size(); ++i) { 308 for (size_t i = 0; i < items.size(); ++i) {
213 if (i > 0) 309 if (i > 0)
214 [joinedItems appendString:@"\n"]; 310 [joinedItems appendString:@"\n"];
215 [joinedItems appendString:base::SysUTF16ToNSString( 311 [joinedItems appendString:base::SysUTF16ToNSString(
216 items[i].GetNameForDisplay())]; 312 items[i].GetNameForDisplay())];
217 } 313 }
218 [itemsField_ setStringValue:joinedItems]; 314 [itemsField_ setStringValue:joinedItems];
219 315
220 // Adjust the controls to fit the list of extensions. 316 // Adjust the controls to fit the list of extensions.
221 OffsetControlVerticallyToFitContent(itemsField_, &totalOffset); 317 OffsetControlVerticallyToFitContent(itemsField_, &totalOffset);
222 } 318 }
223 319
224 // If there are any warnings, then we have to do some special layout. 320 // If there are any warnings or OAuth issues, then we have to do some special
225 if (prompt_->GetPermissionCount() > 0) { 321 // layout.
226 [subtitleField_ setStringValue:base::SysUTF16ToNSString( 322 if (prompt_->GetPermissionCount() > 0 || prompt_->GetOAuthIssueCount() > 0) {
227 prompt_->GetPermissionsHeading())]; 323 NSSize spacing = [outlineView_ intercellSpacing];
228 324 spacing.width += 2;
229 // We display the permission warnings as a simple text string, separated by 325 spacing.height += 2;
230 // newlines. 326 [outlineView_ setIntercellSpacing:spacing];
231 NSMutableString* joinedWarnings = [NSMutableString string]; 327 [[[[outlineView_ tableColumns] objectAtIndex:0] dataCell] setWraps:YES];
232 for (size_t i = 0; i < prompt_->GetPermissionCount(); ++i) { 328 for (id item in warnings_.get()) {
233 if (i > 0) 329 if ([[item objectForKey:kIsGroupItemKey] boolValue])
234 [joinedWarnings appendString:@"\n"]; 330 [outlineView_ expandItem:item expandChildren:NO];
235 [joinedWarnings appendString:base::SysUTF16ToNSString(
236 prompt_->GetPermission(i))];
237 } 331 }
238 [warningsField_ setStringValue:joinedWarnings]; 332 // Adjust the outline view to fit the warnings.
239 333 OffsetOutlineViewVerticallyToFitContent(outlineView_, &totalOffset);
240 // In the store version of the dialog the icon extends past the one-line
241 // version of the permission field. Therefore when increasing the window
242 // size for multi-line permissions we don't have to add the full offset,
243 // only the part that extends past the icon.
244 CGFloat warningsGrowthSlack = 0;
245 if (![self isBundleInstall] &&
246 [warningsField_ frame].origin.y > [iconView_ frame].origin.y) {
247 warningsGrowthSlack =
248 [warningsField_ frame].origin.y - [iconView_ frame].origin.y;
249 }
250
251 // Adjust the controls to fit the permission warnings.
252 OffsetControlVerticallyToFitContent(subtitleField_, &totalOffset);
253 OffsetControlVerticallyToFitContent(warningsField_, &totalOffset);
254
255 totalOffset = MAX(totalOffset - warningsGrowthSlack, 0);
256 } else if ([self isInlineInstall] || [self isBundleInstall]) { 334 } else if ([self isInlineInstall] || [self isBundleInstall]) {
257 // Inline and bundle installs that don't have a permissions section need to 335 // Inline and bundle installs that don't have a permissions section need to
258 // hide controls related to that and shrink the window by the space they 336 // hide controls related to that and shrink the window by the space they
259 // take up. 337 // take up.
260 NSRect hiddenRect = NSUnionRect([warningsSeparator_ frame], 338 NSRect hiddenRect = NSUnionRect([warningsSeparator_ frame],
261 [subtitleField_ frame]); 339 [[outlineView_ enclosingScrollView] frame]);
262 hiddenRect = NSUnionRect(hiddenRect, [warningsField_ frame]);
263 [warningsSeparator_ setHidden:YES]; 340 [warningsSeparator_ setHidden:YES];
264 [subtitleField_ setHidden:YES]; 341 [[outlineView_ enclosingScrollView] setHidden:YES];
265 [warningsField_ setHidden:YES];
266 totalOffset -= hiddenRect.size.height + kWarningsSeparatorPadding; 342 totalOffset -= hiddenRect.size.height + kWarningsSeparatorPadding;
267 } 343 }
268 344
269 // If necessary, adjust the window size. 345 // If necessary, adjust the window size.
270 if (totalOffset) { 346 if (totalOffset) {
271 NSRect currentRect = [[self window] frame]; 347 NSRect currentRect = [[self window] frame];
272 [[self window] setFrame:NSMakeRect(currentRect.origin.x, 348 [[self window] setFrame:NSMakeRect(currentRect.origin.x,
273 currentRect.origin.y - totalOffset, 349 currentRect.origin.y - totalOffset,
274 currentRect.size.width, 350 currentRect.size.width,
275 currentRect.size.height + totalOffset) 351 currentRect.size.height + totalOffset)
(...skipping 30 matching lines...) Expand all
306 CGFloat maxStarRight = 0; 382 CGFloat maxStarRight = 0;
307 if ([[ratingStars_ subviews] count]) { 383 if ([[ratingStars_ subviews] count]) {
308 maxStarRight = NSMaxX([[[ratingStars_ subviews] lastObject] frame]); 384 maxStarRight = NSMaxX([[[ratingStars_ subviews] lastObject] frame]);
309 } 385 }
310 NSRect starBounds = NSMakeRect(maxStarRight, 0, 386 NSRect starBounds = NSMakeRect(maxStarRight, 0,
311 skiaImage->width(), skiaImage->height()); 387 skiaImage->width(), skiaImage->height());
312 [view setFrame:starBounds]; 388 [view setFrame:starBounds];
313 [ratingStars_ addSubview:view]; 389 [ratingStars_ addSubview:view];
314 } 390 }
315 391
392 - (void)onOutlineViewRowCountDidChange {
393 // Force the outline view to update.
394 [outlineView_ reloadData];
395
396 CGFloat totalOffset = 0.0;
397 OffsetOutlineViewVerticallyToFitContent(outlineView_, &totalOffset);
398 if (totalOffset) {
399 NSRect currentRect = [[self window] frame];
400 [[self window] setFrame:NSMakeRect(currentRect.origin.x,
401 currentRect.origin.y - totalOffset,
402 currentRect.size.width,
403 currentRect.size.height + totalOffset)
404 display:YES];
405 }
406 }
407
408 - (id)outlineView:(NSOutlineView*)outlineView
409 child:(NSInteger)index
410 ofItem:(id)item {
411 if (!item)
412 return [warnings_ objectAtIndex:index];
413 if ([item isKindOfClass:[NSDictionary class]])
414 return [[item objectForKey:kChildrenKey] objectAtIndex:index];
415 NOTREACHED();
416 return nil;
417 }
418
419 - (BOOL)outlineView:(NSOutlineView*)outlineView
420 isItemExpandable:(id)item {
421 return [self outlineView:outlineView numberOfChildrenOfItem:item] > 0;
422 }
423
424 - (NSInteger)outlineView:(NSOutlineView*)outlineView
425 numberOfChildrenOfItem:(id)item {
426 if (!item)
427 return [warnings_ count];
428 if ([item isKindOfClass:[NSDictionary class]])
429 return [[item objectForKey:kChildrenKey] count];
430 NOTREACHED();
431 return 0;
432 }
433
434 - (id)outlineView:(NSOutlineView*)outlineView
435 objectValueForTableColumn:(NSTableColumn *)tableColumn
436 byItem:(id)item {
437 if ([item isKindOfClass:[NSDictionary class]])
438 return [item objectForKey:kTitleKey];
439 NOTREACHED();
440 return nil;
441 }
442
443 - (BOOL)outlineView:(NSOutlineView *)outlineView
444 shouldExpandItem:(id)item {
445 return [[item objectForKey:kCanExpandKey] boolValue];
446 }
447
448 - (void)outlineViewItemDidExpand:sender {
449 // Call via run loop to avoid animation glitches.
450 [self performSelector:@selector(onOutlineViewRowCountDidChange)
451 withObject:nil
452 afterDelay:0];
453 }
454
455 - (void)outlineViewItemDidCollapse:sender {
456 // Call via run loop to avoid animation glitches.
457 [self performSelector:@selector(onOutlineViewRowCountDidChange)
458 withObject:nil
459 afterDelay:0];
460 }
461
462 - (CGFloat)outlineView:(NSOutlineView *)outlineView
463 heightOfRowByItem:(id)item {
464 // Prevent reentrancy due to the frameOfCellAtColumn:row: call below.
465 if (isComputingRowHeight)
466 return 1;
467 isComputingRowHeight = YES;
468
469 NSCell* cell = [[[outlineView_ tableColumns] objectAtIndex:0] dataCell];
470 [cell setStringValue:[item objectForKey:kTitleKey]];
471 NSRect bounds = NSZeroRect;
472 NSInteger row = [outlineView_ rowForItem:item];
473 bounds.size.width = [outlineView_ frameOfCellAtColumn:0
474 row:row].size.width;
475 bounds.size.height = kMaxControlHeight;
476
477 isComputingRowHeight = NO;
478 return [cell cellSizeForBounds:bounds].height;
479 }
480
481 - (BOOL)outlineView:(NSOutlineView*)outlineView
482 shouldShowOutlineCellForItem:(id)item {
483 // The top most group header items are always expanded so hide their
484 // disclosure trianggles.
485 return ![[item objectForKey:kIsGroupItemKey] boolValue];
486 }
487
488 - (void)outlineView:(NSOutlineView*)outlineView
489 willDisplayCell:(id)cell
490 forTableColumn:(NSTableColumn *)tableColumn
491 item:(id)item {
492 if ([[item objectForKey:kIsGroupItemKey] boolValue])
493 [cell setFont:[NSFont boldSystemFontOfSize:11.0]];
494 else
495 [cell setFont:[NSFont systemFontOfSize:11.0]];
496 }
497
498 - (void)outlineView:(NSOutlineView *)outlineView
499 willDisplayOutlineCell:(id)cell
500 forTableColumn:(NSTableColumn *)tableColumn
501 item:(id)item {
502 // Replace disclosure triangles with bullet lists for leaf nodes.
503 if (![[item objectForKey:kCanExpandKey] boolValue]) {
504 [cell setImagePosition:NSNoImage];
505 DrawBulletInFrame([outlineView_ frameOfOutlineCellAtRow:
506 [outlineView_ rowForItem:item]]);
507 } else {
508 // Reset image to default value.
509 [cell setImagePosition:NSImageOverlaps];
510 }
511 }
512
316 @end // ExtensionInstallDialogController 513 @end // ExtensionInstallDialogController
317 514
318 void ShowExtensionInstallDialogImpl( 515 void ShowExtensionInstallDialogImpl(
319 gfx::NativeWindow parent, 516 gfx::NativeWindow parent,
320 content::PageNavigator* navigator, 517 content::PageNavigator* navigator,
321 ExtensionInstallPrompt::Delegate* delegate, 518 ExtensionInstallPrompt::Delegate* delegate,
322 const ExtensionInstallPrompt::Prompt& prompt) { 519 const ExtensionInstallPrompt::Prompt& prompt) {
323 ExtensionInstallDialogController* controller = 520 ExtensionInstallDialogController* controller =
324 [[ExtensionInstallDialogController alloc] 521 [[ExtensionInstallDialogController alloc]
325 initWithParentWindow:parent 522 initWithParentWindow:parent
326 navigator:navigator 523 navigator:navigator
327 delegate:delegate 524 delegate:delegate
328 prompt:prompt]; 525 prompt:prompt];
329 526
330 // TODO(mihaip): Switch this to be tab-modal (http://crbug.com/95455) 527 // TODO(mihaip): Switch this to be tab-modal (http://crbug.com/95455)
331 [controller runAsModalSheet]; 528 [controller runAsModalSheet];
332 } 529 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698