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

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

Issue 1542001: Mac: Fill in geolocation bubble from model. (Closed)
Patch Set: comments Created 10 years, 9 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
« no previous file with comments | « chrome/browser/cocoa/content_blocked_bubble_controller.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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" 9 #include "base/mac_util.h"
10 #include "base/string_util.h" 10 #include "base/string_util.h"
(...skipping 23 matching lines...) Expand all
34 34
35 // Space between two popup links. 35 // Space between two popup links.
36 const int kLinkPadding = 4; 36 const int kLinkPadding = 4;
37 37
38 // Space taken in total by one popup link. 38 // Space taken in total by one popup link.
39 const int kLinkLineHeight = kLinkHeight + kLinkPadding; 39 const int kLinkLineHeight = kLinkHeight + kLinkPadding;
40 40
41 // Space between popup list and surrounding UI elements. 41 // Space between popup list and surrounding UI elements.
42 const int kLinkOuterPadding = 8; 42 const int kLinkOuterPadding = 8;
43 43
44 // Height of each of the labels in the geolocation bubble.
45 const int kGeoLabelHeight = 14;
46
47 // Height of the "Clear" button in the geolocation bubble.
48 const int kGeoClearButtonHeight = 17;
49
50 // General padding between elements in the geolocation bubble.
51 const int kGeoPadding = 8;
52
53 // Padding between host names in the geolocation bubble.
54 const int kGeoHostPadding = 4;
55
56
44 // Like |ReplaceStringPlaceholders(const string16&, const string16&, size_t*)|, 57 // Like |ReplaceStringPlaceholders(const string16&, const string16&, size_t*)|,
45 // but for a NSString formatString. 58 // but for a NSString formatString.
46 NSString* ReplaceNSStringPlaceholders(NSString* formatString, 59 NSString* ReplaceNSStringPlaceholders(NSString* formatString,
47 const string16& a, 60 const string16& a,
48 size_t* offset) { 61 size_t* offset) {
49 return base::SysUTF16ToNSString( 62 return base::SysUTF16ToNSString(
50 ReplaceStringPlaceholders(base::SysNSStringToUTF16(formatString), 63 ReplaceStringPlaceholders(base::SysNSStringToUTF16(formatString),
51 a, 64 a,
52 offset)); 65 offset));
53 } 66 }
54 67
68 void SetControlSize(NSControl* control, NSControlSize controlSize) {
69 CGFloat fontSize = [NSFont systemFontSizeForControlSize:controlSize];
70 NSCell* cell = [control cell];
71 NSFont* font = [NSFont fontWithName:[[cell font] fontName] size:fontSize];
72 [cell setFont:font];
73 [cell setControlSize:controlSize];
74 }
75
76 // Returns an autoreleased NSTextField that is configured to look like a Label
77 // looks in Interface Builder.
78 NSTextField* LabelWithFrame(NSString* text, const NSRect& frame) {
79 NSTextField* label = [[NSTextField alloc] initWithFrame:frame];
80 [label setStringValue:text];
81 [label setSelectable:NO];
82 [label setBezeled:NO];
83 return [label autorelease];
84 }
85
55 } // namespace 86 } // namespace
56 87
57 @interface ContentBlockedBubbleController(Private) 88 @interface ContentBlockedBubbleController(Private)
58 - (id)initWithModel:(ContentSettingBubbleModel*)settingsBubbleModel 89 - (id)initWithModel:(ContentSettingBubbleModel*)settingsBubbleModel
59 parentWindow:(NSWindow*)parentWindow 90 parentWindow:(NSWindow*)parentWindow
60 anchoredAt:(NSPoint)anchoredAt; 91 anchoredAt:(NSPoint)anchoredAt;
61 - (NSButton*)hyperlinkButtonWithFrame:(NSRect)frame 92 - (NSButton*)hyperlinkButtonWithFrame:(NSRect)frame
62 title:(NSString*)title 93 title:(NSString*)title
63 icon:(NSImage*)icon 94 icon:(NSImage*)icon
64 referenceFrame:(NSRect)referenceFrame; 95 referenceFrame:(NSRect)referenceFrame;
65 - (void)initializeTitle; 96 - (void)initializeTitle;
66 - (void)initializeRadioGroup; 97 - (void)initializeRadioGroup;
67 - (void)initializePopupList; 98 - (void)initializePopupList;
99 - (void)initializeGeoLists;
68 - (void)popupLinkClicked:(id)sender; 100 - (void)popupLinkClicked:(id)sender;
101 - (void)clearGeolocationForCurrentHost:(id)sender;
69 @end 102 @end
70 103
71 @implementation ContentBlockedBubbleController 104 @implementation ContentBlockedBubbleController
72 105
73 + (ContentBlockedBubbleController*) 106 + (ContentBlockedBubbleController*)
74 showForModel:(ContentSettingBubbleModel*)contentSettingBubbleModel 107 showForModel:(ContentSettingBubbleModel*)contentSettingBubbleModel
75 parentWindow:(NSWindow*)parentWindow 108 parentWindow:(NSWindow*)parentWindow
76 anchoredAt:(NSPoint)anchor { 109 anchoredAt:(NSPoint)anchor {
77 // Autoreleases itself on bubble close. 110 // Autoreleases itself on bubble close.
78 return [[ContentBlockedBubbleController alloc] 111 return [[ContentBlockedBubbleController alloc]
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 [center addObserver:self 146 [center addObserver:self
114 selector:@selector(parentWindowWillClose:) 147 selector:@selector(parentWindowWillClose:)
115 name:NSWindowWillCloseNotification 148 name:NSWindowWillCloseNotification
116 object:parentWindow_]; 149 object:parentWindow_];
117 } 150 }
118 return self; 151 return self;
119 } 152 }
120 153
121 - (void)initializeTitle { 154 - (void)initializeTitle {
122 if (!titleLabel_) 155 if (!titleLabel_)
123 return; // Make valgrind happy for now. 156 return;
124 157
125 // Layout title post-localization. 158 // Layout title post-localization.
126 CGFloat titleDeltaY = [GTMUILocalizerAndLayoutTweaker 159 CGFloat deltaY = [GTMUILocalizerAndLayoutTweaker
127 sizeToFitFixedWidthTextField:titleLabel_]; 160 sizeToFitFixedWidthTextField:titleLabel_];
128 NSRect windowFrame = [[self window] frame]; 161 NSRect windowFrame = [[self window] frame];
129 windowFrame.size.height += titleDeltaY; 162 windowFrame.size.height += deltaY;
130 [[self window] setFrame:windowFrame display:NO]; 163 [[self window] setFrame:windowFrame display:NO];
131 NSRect titleFrame = [titleLabel_ frame]; 164 NSRect titleFrame = [titleLabel_ frame];
132 titleFrame.origin.y -= titleDeltaY; 165 titleFrame.origin.y -= deltaY;
133 [titleLabel_ setFrame:titleFrame]; 166 [titleLabel_ setFrame:titleFrame];
134 } 167 }
135 168
136 - (void)initializeRadioGroup { 169 - (void)initializeRadioGroup {
137 // Configure the radio group. For now, only deal with the 170 // Configure the radio group. For now, only deal with the
138 // strictly needed case of 1 radio group (containing 2 radio buttons). 171 // strictly needed case of 1 radio group (containing 2 radio buttons).
139 // TODO(joth): Implement the generic case, getting localized strings from the 172 // TODO(joth): Implement the generic case, getting localized strings from the
140 // bubble model instead of the xib, or remove it if it's never needed. 173 // bubble model instead of the xib, or remove it if it's never needed.
141 // http://crbug.com/38432 174 // http://crbug.com/38432
142 const ContentSettingBubbleModel::RadioGroups& radioGroups = 175 const ContentSettingBubbleModel::RadioGroups& radioGroups =
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 NSButton* button = [self 274 NSButton* button = [self
242 hyperlinkButtonWithFrame:linkFrame 275 hyperlinkButtonWithFrame:linkFrame
243 title:base::SysUTF8ToNSString(title) 276 title:base::SysUTF8ToNSString(title)
244 icon:image 277 icon:image
245 referenceFrame:radioFrame]; 278 referenceFrame:radioFrame];
246 [bubble_ addSubview:button]; 279 [bubble_ addSubview:button];
247 popupLinks_[button] = row; 280 popupLinks_[button] = row;
248 } 281 }
249 } 282 }
250 283
284 - (void)initializeGeoLists {
285 // 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
287 // order of operations is the other way than on Linux/Windows.
288 const ContentSettingBubbleModel::BubbleContent& content =
289 contentSettingBubbleModel_->bubble_content();
290 NSRect containerFrame = [contentsContainer_ frame];
291 NSRect frame = NSMakeRect(0, 0, containerFrame.size.width, kGeoLabelHeight);
292
293 // "Clear" button.
294 if (!content.clear_link.empty()) {
295 NSRect buttonFrame = NSMakeRect(0, 0,
296 containerFrame.size.width,
297 kGeoClearButtonHeight);
298 NSButton* button = [[NSButton alloc] initWithFrame:buttonFrame];
299 [button setTitle:base::SysUTF8ToNSString(content.clear_link)];
300 [button setTarget:self];
301 [button setAction:@selector(clearGeolocationForCurrentHost:)];
302 [button setBezelStyle:NSRoundRectBezelStyle];
303 SetControlSize(button, NSSmallControlSize);
304 [button sizeToFit];
305 [contentsContainer_ addSubview:button];
306
307 frame.origin.y = NSMaxY([button frame]) + kGeoPadding;
308 }
309
310 typedef
311 std::vector<ContentSettingBubbleModel::DomainList>::const_reverse_iterator
312 GeolocationGroupIterator;
313 for (GeolocationGroupIterator i = content.domain_lists.rbegin();
314 i != content.domain_lists.rend(); ++i) {
315 // Add all hosts in the current domain list.
316 for (std::set<std::string>::const_reverse_iterator j = i->hosts.rbegin();
317 j != i->hosts.rend(); ++j) {
318 NSTextField* title = LabelWithFrame(base::SysUTF8ToNSString(*j), frame);
319 SetControlSize(title, NSSmallControlSize);
320 [contentsContainer_ addSubview:title];
321
322 frame.origin.y += [GTMUILocalizerAndLayoutTweaker
323 sizeToFitFixedWidthTextField:title];
324 frame.origin.y = NSMaxY(frame) + kGeoHostPadding;
325 }
326 if (!i->hosts.empty())
327 frame.origin.y += kGeoPadding - kGeoHostPadding;
328
329 // Add the domain list's title.
330 NSTextField* title =
331 LabelWithFrame(base::SysUTF8ToNSString(i->title), frame);
332 SetControlSize(title, NSSmallControlSize);
333 [contentsContainer_ addSubview:title];
334
335 frame.origin.y += [GTMUILocalizerAndLayoutTweaker
336 sizeToFitFixedWidthTextField:title];
337 frame.origin.y = NSMaxY(frame) + kGeoPadding;
338 }
339
340 CGFloat containerHeight = frame.origin.y;
341 // Undo last padding.
342 if (!content.domain_lists.empty())
343 containerHeight -= kGeoPadding;
344
345 // Resize container to fit its subviews, and window to fit the container.
346 NSRect windowFrame = [[self window] frame];
347 windowFrame.size.height += containerHeight - containerFrame.size.height;
348 [[self window] setFrame:windowFrame display:NO];
349 containerFrame.size.height = containerHeight;
350 [contentsContainer_ setFrame:containerFrame];
351 }
352
251 - (void)awakeFromNib { 353 - (void)awakeFromNib {
252 DCHECK([self window]); 354 DCHECK([self window]);
253 DCHECK_EQ(self, [[self window] delegate]); 355 DCHECK_EQ(self, [[self window] delegate]);
254 356
255 [bubble_ setBubbleType:kWhiteInfoBubble]; 357 [bubble_ setBubbleType:kWhiteInfoBubble];
256 [bubble_ setArrowLocation:kTopRight]; 358 [bubble_ setArrowLocation:kTopRight];
257 359
258 [self initializeTitle]; 360 [self initializeTitle];
259 if (allowBlockRadioGroup_) // not bound in cookie bubble xib 361 if (allowBlockRadioGroup_) // not bound in cookie bubble xib
260 [self initializeRadioGroup]; 362 [self initializeRadioGroup];
261 if (contentSettingBubbleModel_->content_type() 363 if (contentSettingBubbleModel_->content_type() ==
262 == CONTENT_SETTINGS_TYPE_POPUPS) 364 CONTENT_SETTINGS_TYPE_POPUPS)
263 [self initializePopupList]; 365 [self initializePopupList];
366 if (contentSettingBubbleModel_->content_type() ==
367 CONTENT_SETTINGS_TYPE_GEOLOCATION)
368 [self initializeGeoLists];
264 } 369 }
265 370
266 /////////////////////////////////////////////////////////////////////////////// 371 ///////////////////////////////////////////////////////////////////////////////
267 // Bubble-management related stuff 372 // Bubble-management related stuff
268 373
269 // TODO(thakis): All that junk below should be in some superclass that all the 374 // TODO(thakis): All that junk below should be in some superclass that all the
270 // bubble controllers (bookmark bubble, extension installed bubble, page/browser 375 // bubble controllers (bookmark bubble, extension installed bubble, page/browser
271 // action bubble, content blocked bubble) derive from -- http://crbug.com/36366 376 // action bubble, content blocked bubble) derive from -- http://crbug.com/36366
272 377
273 - (void)dealloc { 378 - (void)dealloc {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 - (IBAction)manageBlocking:(id)sender { 451 - (IBAction)manageBlocking:(id)sender {
347 contentSettingBubbleModel_->OnManageLinkClicked(); 452 contentSettingBubbleModel_->OnManageLinkClicked();
348 } 453 }
349 454
350 - (void)popupLinkClicked:(id)sender { 455 - (void)popupLinkClicked:(id)sender {
351 content_blocked_bubble::PopupLinks::iterator i(popupLinks_.find(sender)); 456 content_blocked_bubble::PopupLinks::iterator i(popupLinks_.find(sender));
352 DCHECK(i != popupLinks_.end()); 457 DCHECK(i != popupLinks_.end());
353 contentSettingBubbleModel_->OnPopupClicked(i->second); 458 contentSettingBubbleModel_->OnPopupClicked(i->second);
354 } 459 }
355 460
461 - (void)clearGeolocationForCurrentHost:(id)sender {
462 contentSettingBubbleModel_->OnClearLinkClicked();
463 [self close];
464 }
465
356 @end // ContentBlockedBubbleController 466 @end // ContentBlockedBubbleController
OLDNEW
« no previous file with comments | « chrome/browser/cocoa/content_blocked_bubble_controller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698