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

Side by Side Diff: chrome/browser/cocoa/content_blocked_bubble_controller.mm

Issue 2822026: Mac: First run bubble. (Closed)
Patch Set: '' Created 10 years, 6 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
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/cocoa/content_blocked_bubble_controller.h" 5 #import "chrome/browser/cocoa/content_blocked_bubble_controller.h"
6 6
7 #include "app/l10n_util.h" 7 #include "app/l10n_util.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/mac_util.h"
10 #include "base/string_util.h"
11 #include "base/sys_string_conversions.h" 9 #include "base/sys_string_conversions.h"
12 #include "chrome/browser/blocked_popup_container.h" 10 #include "chrome/browser/blocked_popup_container.h"
13 #import "chrome/browser/cocoa/content_settings_dialog_controller.h" 11 #import "chrome/browser/cocoa/content_settings_dialog_controller.h"
14 #import "chrome/browser/cocoa/hyperlink_button_cell.h" 12 #import "chrome/browser/cocoa/hyperlink_button_cell.h"
15 #import "chrome/browser/cocoa/info_bubble_view.h" 13 #import "chrome/browser/cocoa/info_bubble_view.h"
14 #import "chrome/browser/cocoa/l10n_util.h"
16 #include "chrome/browser/content_setting_bubble_model.h" 15 #include "chrome/browser/content_setting_bubble_model.h"
17 #include "chrome/browser/host_content_settings_map.h" 16 #include "chrome/browser/host_content_settings_map.h"
18 #include "chrome/common/notification_service.h"
19 #include "chrome/common/notification_type.h"
20 #include "grit/generated_resources.h" 17 #include "grit/generated_resources.h"
21 #include "skia/ext/skia_utils_mac.h" 18 #include "skia/ext/skia_utils_mac.h"
22 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" 19 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
23 20
24 namespace { 21 namespace {
25 22
26 // Must match the tag of the unblock radio button in the xib files. 23 // Must match the tag of the unblock radio button in the xib files.
27 const int kAllowTag = 1; 24 const int kAllowTag = 1;
28 25
29 // Must match the tag of the block radio button in the xib files. 26 // Must match the tag of the block radio button in the xib files.
(...skipping 19 matching lines...) Expand all
49 46
50 // General padding between elements in the geolocation bubble. 47 // General padding between elements in the geolocation bubble.
51 const int kGeoPadding = 8; 48 const int kGeoPadding = 8;
52 49
53 // Padding between host names in the geolocation bubble. 50 // Padding between host names in the geolocation bubble.
54 const int kGeoHostPadding = 4; 51 const int kGeoHostPadding = 4;
55 52
56 // Minimal padding between "Manage" and "Done" buttons. 53 // Minimal padding between "Manage" and "Done" buttons.
57 const int kManageDonePadding = 8; 54 const int kManageDonePadding = 8;
58 55
59 // Like |ReplaceStringPlaceholders(const string16&, const string16&, size_t*)|,
60 // but for a NSString formatString.
61 NSString* ReplaceNSStringPlaceholders(NSString* formatString,
62 const string16& a,
63 size_t* offset) {
64 return base::SysUTF16ToNSString(
65 ReplaceStringPlaceholders(base::SysNSStringToUTF16(formatString),
66 a,
67 offset));
68 }
69
70 void SetControlSize(NSControl* control, NSControlSize controlSize) { 56 void SetControlSize(NSControl* control, NSControlSize controlSize) {
71 CGFloat fontSize = [NSFont systemFontSizeForControlSize:controlSize]; 57 CGFloat fontSize = [NSFont systemFontSizeForControlSize:controlSize];
72 NSCell* cell = [control cell]; 58 NSCell* cell = [control cell];
73 NSFont* font = [NSFont fontWithName:[[cell font] fontName] size:fontSize]; 59 NSFont* font = [NSFont fontWithName:[[cell font] fontName] size:fontSize];
74 [cell setFont:font]; 60 [cell setFont:font];
75 [cell setControlSize:controlSize]; 61 [cell setControlSize:controlSize];
76 } 62 }
77 63
78 // Returns an autoreleased NSTextField that is configured to look like a Label 64 // Returns an autoreleased NSTextField that is configured to look like a Label
79 // looks in Interface Builder. 65 // looks in Interface Builder.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 @"ContentBlockedImages", 115 @"ContentBlockedImages",
130 @"ContentBlockedJavaScript", 116 @"ContentBlockedJavaScript",
131 @"ContentBlockedPlugins", 117 @"ContentBlockedPlugins",
132 @"ContentBlockedPopups", 118 @"ContentBlockedPopups",
133 @"ContentBubbleGeolocation", 119 @"ContentBubbleGeolocation",
134 }; 120 };
135 COMPILE_ASSERT(arraysize(nibPaths) == CONTENT_SETTINGS_NUM_TYPES, 121 COMPILE_ASSERT(arraysize(nibPaths) == CONTENT_SETTINGS_NUM_TYPES,
136 nibPaths_requires_an_entry_for_every_setting_type); 122 nibPaths_requires_an_entry_for_every_setting_type);
137 const int settingsType = model->content_type(); 123 const int settingsType = model->content_type();
138 DCHECK_LT(settingsType, CONTENT_SETTINGS_NUM_TYPES); 124 DCHECK_LT(settingsType, CONTENT_SETTINGS_NUM_TYPES);
139 NSString* nibPath = 125 if ((self = [super initWithWindowNibPath:nibPaths[settingsType]
140 [mac_util::MainAppBundle() pathForResource:nibPaths[settingsType] 126 parentWindow:parentWindow
141 ofType:@"nib"]; 127 anchoredAt:anchoredAt])) {
142 if ((self = [super initWithWindowNibPath:nibPath owner:self])) {
143 parentWindow_ = parentWindow;
144 anchor_ = anchoredAt;
145 contentSettingBubbleModel_.reset(model.release()); 128 contentSettingBubbleModel_.reset(model.release());
146 129 [self showWindow:nil];
147 // Watch to see if the parent window closes, and if so, close this one.
148 NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
149 [center addObserver:self
150 selector:@selector(parentWindowWillClose:)
151 name:NSWindowWillCloseNotification
152 object:parentWindow_];
153 } 130 }
154 return self; 131 return self;
155 } 132 }
156 133
157 - (void)initializeTitle { 134 - (void)initializeTitle {
158 if (!titleLabel_) 135 if (!titleLabel_)
159 return; 136 return;
160 137
161 // Layout title post-localization. 138 // Layout title post-localization.
162 CGFloat deltaY = [GTMUILocalizerAndLayoutTweaker 139 CGFloat deltaY = [GTMUILocalizerAndLayoutTweaker
(...skipping 14 matching lines...) Expand all
177 // http://crbug.com/38432 154 // http://crbug.com/38432
178 const ContentSettingBubbleModel::RadioGroup& radioGroup = 155 const ContentSettingBubbleModel::RadioGroup& radioGroup =
179 contentSettingBubbleModel_->bubble_content().radio_group; 156 contentSettingBubbleModel_->bubble_content().radio_group;
180 157
181 // Select appropriate radio button. 158 // Select appropriate radio button.
182 [allowBlockRadioGroup_ selectCellWithTag: 159 [allowBlockRadioGroup_ selectCellWithTag:
183 radioGroup.default_item == 0 ? kAllowTag : kBlockTag]; 160 radioGroup.default_item == 0 ? kAllowTag : kBlockTag];
184 161
185 // Copy |host_| into radio group label. 162 // Copy |host_| into radio group label.
186 NSCell* radioCell = [allowBlockRadioGroup_ cellWithTag:kAllowTag]; 163 NSCell* radioCell = [allowBlockRadioGroup_ cellWithTag:kAllowTag];
187 [radioCell setTitle:ReplaceNSStringPlaceholders( 164 [radioCell setTitle:cocoa_l10n_util::ReplaceNSStringPlaceholders(
188 [radioCell title], UTF8ToUTF16(radioGroup.url.host()), NULL)]; 165 [radioCell title], UTF8ToUTF16(radioGroup.url.host()), NULL)];
189 166
190 // Layout radio group labels post-localization. 167 // Layout radio group labels post-localization.
191 [GTMUILocalizerAndLayoutTweaker 168 [GTMUILocalizerAndLayoutTweaker
192 wrapRadioGroupForWidth:allowBlockRadioGroup_]; 169 wrapRadioGroupForWidth:allowBlockRadioGroup_];
193 CGFloat radioDeltaY = [GTMUILocalizerAndLayoutTweaker 170 CGFloat radioDeltaY = [GTMUILocalizerAndLayoutTweaker
194 sizeToFitView:allowBlockRadioGroup_].height; 171 sizeToFitView:allowBlockRadioGroup_].height;
195 NSRect windowFrame = [[self window] frame]; 172 NSRect windowFrame = [[self window] frame];
196 windowFrame.size.height += radioDeltaY; 173 windowFrame.size.height += radioDeltaY;
197 [[self window] setFrame:windowFrame display:NO]; 174 [[self window] setFrame:windowFrame display:NO];
(...skipping 13 matching lines...) Expand all
211 [cell.get() setImagePosition:NSNoImage]; 188 [cell.get() setImagePosition:NSNoImage];
212 } 189 }
213 [cell.get() setControlSize:NSSmallControlSize]; 190 [cell.get() setControlSize:NSSmallControlSize];
214 191
215 NSButton* button = [[[NSButton alloc] initWithFrame:frame] autorelease]; 192 NSButton* button = [[[NSButton alloc] initWithFrame:frame] autorelease];
216 // Cell must be set immediately after construction. 193 // Cell must be set immediately after construction.
217 [button setCell:cell.get()]; 194 [button setCell:cell.get()];
218 195
219 // If the link text is too long, clamp it. 196 // If the link text is too long, clamp it.
220 [button sizeToFit]; 197 [button sizeToFit];
221 int maxWidth = NSWidth([bubble_ frame]) - 2 * NSMinX(referenceFrame); 198 int maxWidth = NSWidth([[self bubble] frame]) - 2 * NSMinX(referenceFrame);
222 NSRect buttonFrame = [button frame]; 199 NSRect buttonFrame = [button frame];
223 if (NSWidth(buttonFrame) > maxWidth) { 200 if (NSWidth(buttonFrame) > maxWidth) {
224 buttonFrame.size.width = maxWidth; 201 buttonFrame.size.width = maxWidth;
225 [button setFrame:buttonFrame]; 202 [button setFrame:buttonFrame];
226 } 203 }
227 204
228 [button setTarget:self]; 205 [button setTarget:self];
229 [button setAction:@selector(popupLinkClicked:)]; 206 [button setAction:@selector(popupLinkClicked:)];
230 return button; 207 return button;
231 } 208 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 title = l10n_util::GetStringUTF8(IDS_TAB_LOADING_TITLE); 246 title = l10n_util::GetStringUTF8(IDS_TAB_LOADING_TITLE);
270 247
271 NSRect linkFrame = 248 NSRect linkFrame =
272 NSMakeRect(NSMinX(radioFrame), topLinkY - kLinkLineHeight * row, 249 NSMakeRect(NSMinX(radioFrame), topLinkY - kLinkLineHeight * row,
273 200, kLinkHeight); 250 200, kLinkHeight);
274 NSButton* button = [self 251 NSButton* button = [self
275 hyperlinkButtonWithFrame:linkFrame 252 hyperlinkButtonWithFrame:linkFrame
276 title:base::SysUTF8ToNSString(title) 253 title:base::SysUTF8ToNSString(title)
277 icon:image 254 icon:image
278 referenceFrame:radioFrame]; 255 referenceFrame:radioFrame];
279 [bubble_ addSubview:button]; 256 [[self bubble] addSubview:button];
280 popupLinks_[button] = row; 257 popupLinks_[button] = row;
281 } 258 }
282 } 259 }
283 260
284 - (void)initializeGeoLists { 261 - (void)initializeGeoLists {
285 // Cocoa has its origin in the lower left corner. This means elements are 262 // Cocoa has its origin in the lower left corner. This means elements are
286 // added from bottom to top, which explains why loops run backwards and the 263 // added from bottom to top, which explains why loops run backwards and the
287 // order of operations is the other way than on Linux/Windows. 264 // order of operations is the other way than on Linux/Windows.
288 const ContentSettingBubbleModel::BubbleContent& content = 265 const ContentSettingBubbleModel::BubbleContent& content =
289 contentSettingBubbleModel_->bubble_content(); 266 contentSettingBubbleModel_->bubble_content();
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 // Resize window, autoresizing takes care of the rest. 349 // Resize window, autoresizing takes care of the rest.
373 NSSize size = NSMakeSize(requiredWidth - actualWidth, 0); 350 NSSize size = NSMakeSize(requiredWidth - actualWidth, 0);
374 size = [[[self window] contentView] convertSize:size toView:nil]; 351 size = [[[self window] contentView] convertSize:size toView:nil];
375 NSRect frame = [[self window] frame]; 352 NSRect frame = [[self window] frame];
376 frame.origin.x -= size.width; 353 frame.origin.x -= size.width;
377 frame.size.width += size.width; 354 frame.size.width += size.width;
378 [[self window] setFrame:frame display:NO]; 355 [[self window] setFrame:frame display:NO];
379 } 356 }
380 357
381 - (void)awakeFromNib { 358 - (void)awakeFromNib {
382 DCHECK([self window]); 359 [[self bubble] setBubbleType:info_bubble::kWhiteInfoBubble];
383 DCHECK_EQ(self, [[self window] delegate]); 360 [[self bubble] setArrowLocation:info_bubble::kTopRight];
384
385 [bubble_ setBubbleType:info_bubble::kWhiteInfoBubble];
386 [bubble_ setArrowLocation:info_bubble::kTopRight];
387 361
388 // Adapt window size to bottom buttons. Do this before all other layouting. 362 // Adapt window size to bottom buttons. Do this before all other layouting.
389 [self sizeToFitManageDoneButtons]; 363 [self sizeToFitManageDoneButtons];
390 364
391 [self initializeTitle]; 365 [self initializeTitle];
392 if (allowBlockRadioGroup_) // not bound in cookie bubble xib 366 if (allowBlockRadioGroup_) // not bound in cookie bubble xib
393 [self initializeRadioGroup]; 367 [self initializeRadioGroup];
394 if (contentSettingBubbleModel_->content_type() == 368 if (contentSettingBubbleModel_->content_type() ==
395 CONTENT_SETTINGS_TYPE_POPUPS) 369 CONTENT_SETTINGS_TYPE_POPUPS)
396 [self initializePopupList]; 370 [self initializePopupList];
397 if (contentSettingBubbleModel_->content_type() == 371 if (contentSettingBubbleModel_->content_type() ==
398 CONTENT_SETTINGS_TYPE_GEOLOCATION) 372 CONTENT_SETTINGS_TYPE_GEOLOCATION)
399 [self initializeGeoLists]; 373 [self initializeGeoLists];
400 } 374 }
401 375
402 /////////////////////////////////////////////////////////////////////////////// 376 ///////////////////////////////////////////////////////////////////////////////
403 // Bubble-management related stuff
404
405 // TODO(thakis): All that junk below should be in some superclass that all the
406 // bubble controllers (bookmark bubble, extension installed bubble, page/browser
407 // action bubble, content blocked bubble) derive from -- http://crbug.com/36366
408
409 - (void)dealloc {
410 [[NSNotificationCenter defaultCenter] removeObserver:self];
411 [super dealloc];
412 }
413
414 - (void)parentWindowWillClose:(NSNotification*)notification {
415 [self close];
416 }
417
418 - (void)windowWillClose:(NSNotification*)notification {
419 // We caught a close so we don't need to watch for the parent closing.
420 [[NSNotificationCenter defaultCenter] removeObserver:self];
421 [self autorelease];
422 }
423
424 // We want this to be a child of a browser window. addChildWindow:
425 // (called from this function) will bring the window on-screen;
426 // unfortunately, [NSWindowController showWindow:] will also bring it
427 // on-screen (but will cause unexpected changes to the window's
428 // position). We cannot have an addChildWindow: and a subsequent
429 // showWindow:. Thus, we have our own version.
430 - (void)showWindow:(id)sender {
431 NSWindow* window = [self window]; // completes nib load
432
433 NSPoint origin = anchor_;
434 NSSize offsets = NSMakeSize(info_bubble::kBubbleArrowXOffset +
435 info_bubble::kBubbleArrowWidth / 2.0, 0);
436 offsets = [[parentWindow_ contentView] convertSize:offsets toView:nil];
437 origin.x -= NSWidth([window frame]) - offsets.width;
438 origin.y -= NSHeight([window frame]);
439 [window setFrameOrigin:origin];
440 [parentWindow_ addChildWindow:window ordered:NSWindowAbove];
441 [window makeKeyAndOrderFront:self];
442 }
443
444 - (void)close {
445 [parentWindow_ removeChildWindow:[self window]];
446 [super close];
447 }
448
449 // The controller is the delegate of the window so it receives did resign key
450 // notifications. When key is resigned mirror Windows behavior and close the
451 // window.
452 - (void)windowDidResignKey:(NSNotification*)notification {
453 NSWindow* window = [self window];
454 DCHECK_EQ([notification object], window);
455 if ([window isVisible]) {
456 // If the window isn't visible, it is already closed, and this notification
457 // has been sent as part of the closing operation, so no need to close.
458 [self close];
459 }
460 }
461
462 // By implementing this, ESC causes the window to go away.
463 - (IBAction)cancel:(id)sender {
464 // This is not a "real" cancel as potential changes to the radio group are not
465 // undone. That's ok.
466 [self close];
467 }
468
469 ///////////////////////////////////////////////////////////////////////////////
470 // Actual application logic 377 // Actual application logic
471 378
472 - (IBAction)allowBlockToggled:(id)sender { 379 - (IBAction)allowBlockToggled:(id)sender {
473 NSButtonCell *selectedCell = [sender selectedCell]; 380 NSButtonCell *selectedCell = [sender selectedCell];
474 contentSettingBubbleModel_->OnRadioClicked( 381 contentSettingBubbleModel_->OnRadioClicked(
475 [selectedCell tag] == kAllowTag ? 0 : 1); 382 [selectedCell tag] == kAllowTag ? 0 : 1);
476 } 383 }
477 384
478 - (IBAction)closeBubble:(id)sender { 385 - (IBAction)closeBubble:(id)sender {
479 [self close]; 386 [self close];
480 } 387 }
481 388
482 - (IBAction)manageBlocking:(id)sender { 389 - (IBAction)manageBlocking:(id)sender {
483 contentSettingBubbleModel_->OnManageLinkClicked(); 390 contentSettingBubbleModel_->OnManageLinkClicked();
484 } 391 }
485 392
486 - (void)popupLinkClicked:(id)sender { 393 - (void)popupLinkClicked:(id)sender {
487 content_blocked_bubble::PopupLinks::iterator i(popupLinks_.find(sender)); 394 content_blocked_bubble::PopupLinks::iterator i(popupLinks_.find(sender));
488 DCHECK(i != popupLinks_.end()); 395 DCHECK(i != popupLinks_.end());
489 contentSettingBubbleModel_->OnPopupClicked(i->second); 396 contentSettingBubbleModel_->OnPopupClicked(i->second);
490 } 397 }
491 398
492 - (void)clearGeolocationForCurrentHost:(id)sender { 399 - (void)clearGeolocationForCurrentHost:(id)sender {
493 contentSettingBubbleModel_->OnClearLinkClicked(); 400 contentSettingBubbleModel_->OnClearLinkClicked();
494 [self close]; 401 [self close];
495 } 402 }
496 403
497 @end // ContentBlockedBubbleController 404 @end // ContentBlockedBubbleController
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698