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

Side by Side Diff: chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm

Issue 9703084: [Mac] Make BookmarkBubbleController is-a BaseBubbleController. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ui/cocoa/bookmarks/bookmark_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) 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/bookmarks/bookmark_bubble_controller.h" 5 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h"
6 6
7 #include "base/mac/bundle_locations.h" 7 #include "base/mac/bundle_locations.h"
8 #include "base/mac/mac_util.h" 8 #include "base/mac/mac_util.h"
9 #include "base/sys_string_conversions.h" 9 #include "base/sys_string_conversions.h"
10 #include "chrome/browser/bookmarks/bookmark_model.h" 10 #include "chrome/browser/bookmarks/bookmark_model.h"
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 // An object to represent the ChooseAnotherFolder item in the pop up. 63 // An object to represent the ChooseAnotherFolder item in the pop up.
64 @interface ChooseAnotherFolder : NSObject 64 @interface ChooseAnotherFolder : NSObject
65 @end 65 @end
66 66
67 @implementation ChooseAnotherFolder 67 @implementation ChooseAnotherFolder
68 @end 68 @end
69 69
70 @interface BookmarkBubbleController (PrivateAPI) 70 @interface BookmarkBubbleController (PrivateAPI)
71 - (void)updateBookmarkNode; 71 - (void)updateBookmarkNode;
72 - (void)fillInFolderList; 72 - (void)fillInFolderList;
73 - (void)parentWindowWillClose:(NSNotification*)notification;
74 @end 73 @end
75 74
76 @implementation BookmarkBubbleController 75 @implementation BookmarkBubbleController
77 76
78 @synthesize node = node_; 77 @synthesize node = node_;
79 78
80 + (id)chooseAnotherFolderObject { 79 + (id)chooseAnotherFolderObject {
81 // Singleton object to act as a representedObject for the "choose another 80 // Singleton object to act as a representedObject for the "choose another
82 // folder" item in the pop up. 81 // folder" item in the pop up.
83 static ChooseAnotherFolder* object = nil; 82 static ChooseAnotherFolder* object = nil;
84 if (!object) { 83 if (!object) {
85 object = [[ChooseAnotherFolder alloc] init]; 84 object = [[ChooseAnotherFolder alloc] init];
86 } 85 }
87 return object; 86 return object;
88 } 87 }
89 88
90 - (id)initWithParentWindow:(NSWindow*)parentWindow 89 - (id)initWithParentWindow:(NSWindow*)parentWindow
91 model:(BookmarkModel*)model 90 model:(BookmarkModel*)model
92 node:(const BookmarkNode*)node 91 node:(const BookmarkNode*)node
93 alreadyBookmarked:(BOOL)alreadyBookmarked { 92 alreadyBookmarked:(BOOL)alreadyBookmarked {
94 NSString* nibPath = 93 if ((self = [super initWithWindowNibPath:@"BookmarkBubble"
95 [base::mac::FrameworkBundle() pathForResource:@"BookmarkBubble" 94 parentWindow:parentWindow
96 ofType:@"nib"]; 95 anchoredAt:NSZeroPoint])) {
97 if ((self = [super initWithWindowNibPath:nibPath owner:self])) {
98 parentWindow_ = parentWindow;
99 model_ = model; 96 model_ = model;
100 node_ = node; 97 node_ = node;
101 alreadyBookmarked_ = alreadyBookmarked; 98 alreadyBookmarked_ = alreadyBookmarked;
102
103 // Watch to see if the parent window closes, and if so, close this one.
104 NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
105 [center addObserver:self
106 selector:@selector(parentWindowWillClose:)
107 name:NSWindowWillCloseNotification
108 object:parentWindow_];
109 } 99 }
110 return self; 100 return self;
111 } 101 }
112 102
113 - (void)awakeFromNib { 103 - (void)awakeFromNib {
104 [super awakeFromNib];
105
114 // Check if NSTextFieldCell supports the method. This check is in place as 106 // Check if NSTextFieldCell supports the method. This check is in place as
115 // only 10.6 and greater support the setUsesSingleLineMode method. 107 // only 10.6 and greater support the setUsesSingleLineMode method.
116 // TODO(kushi.p): Remove this when the project hits a 10.6+ only state. 108 // TODO(kushi.p): Remove this when the project hits a 10.6+ only state.
117 NSTextFieldCell* nameFieldCell_ = [nameTextField_ cell]; 109 NSTextFieldCell* nameFieldCell_ = [nameTextField_ cell];
118 if ([nameFieldCell_ 110 if ([nameFieldCell_
119 respondsToSelector:@selector(setUsesSingleLineMode:)]) { 111 respondsToSelector:@selector(setUsesSingleLineMode:)]) {
120 [nameFieldCell_ setUsesSingleLineMode:YES]; 112 [nameFieldCell_ setUsesSingleLineMode:YES];
121 } 113 }
122 } 114 }
123 115
124 - (void)dealloc {
125 [[NSNotificationCenter defaultCenter] removeObserver:self];
126 [super dealloc];
127 }
128
129 // If this is a new bookmark somewhere visible (e.g. on the bookmark 116 // If this is a new bookmark somewhere visible (e.g. on the bookmark
130 // bar), pulse it. Else, call ourself recursively with our parent 117 // bar), pulse it. Else, call ourself recursively with our parent
131 // until we find something visible to pulse. 118 // until we find something visible to pulse.
132 - (void)startPulsingBookmarkButton:(const BookmarkNode*)node { 119 - (void)startPulsingBookmarkButton:(const BookmarkNode*)node {
133 while (node) { 120 while (node) {
134 if ((node->parent() == model_->bookmark_bar_node()) || 121 if ((node->parent() == model_->bookmark_bar_node()) ||
135 (node == model_->other_node())) { 122 (node == model_->other_node())) {
136 pulsingBookmarkNode_ = node; 123 pulsingBookmarkNode_ = node;
137 NSValue *value = [NSValue valueWithPointer:node]; 124 NSValue *value = [NSValue valueWithPointer:node];
138 NSDictionary *dict = [NSDictionary 125 NSDictionary *dict = [NSDictionary
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 157
171 // Close the bookmark bubble without changing anything. Unlike a 158 // Close the bookmark bubble without changing anything. Unlike a
172 // typical dialog's OK/Cancel, where Cancel is "do nothing", all 159 // typical dialog's OK/Cancel, where Cancel is "do nothing", all
173 // buttons on the bubble have the capacity to change the bookmark 160 // buttons on the bubble have the capacity to change the bookmark
174 // model. This is an IBOutlet-looking entry point to remove the 161 // model. This is an IBOutlet-looking entry point to remove the
175 // dialog without touching the model. 162 // dialog without touching the model.
176 - (void)dismissWithoutEditing:(id)sender { 163 - (void)dismissWithoutEditing:(id)sender {
177 [self close]; 164 [self close];
178 } 165 }
179 166
180 - (void)parentWindowWillClose:(NSNotification*)notification {
181 [self close];
182 }
183
184 - (void)windowWillClose:(NSNotification*)notification { 167 - (void)windowWillClose:(NSNotification*)notification {
185 // We caught a close so we don't need to watch for the parent closing. 168 // We caught a close so we don't need to watch for the parent closing.
186 [[NSNotificationCenter defaultCenter] removeObserver:self];
187 bookmark_observer_.reset(NULL); 169 bookmark_observer_.reset(NULL);
188 chrome_observer_.reset(NULL); 170 chrome_observer_.reset(NULL);
189 [self stopPulsingBookmarkButton]; 171 [self stopPulsingBookmarkButton];
190 [self autorelease]; 172 [super windowWillClose:notification];
191 } 173 }
192 174
193 // We want this to be a child of a browser window. addChildWindow: 175 // We want this to be a child of a browser window. addChildWindow:
194 // (called from this function) will bring the window on-screen; 176 // (called from this function) will bring the window on-screen;
195 // unfortunately, [NSWindowController showWindow:] will also bring it 177 // unfortunately, [NSWindowController showWindow:] will also bring it
Nico 2012/03/15 21:21:34 Is this comment still needed? Maybe just "Override
Robert Sesek 2012/03/16 15:31:08 Done.
196 // on-screen (but will cause unexpected changes to the window's 178 // on-screen (but will cause unexpected changes to the window's
197 // position). We cannot have an addChildWindow: and a subsequent 179 // position). We cannot have an addChildWindow: and a subsequent
198 // showWindow:. Thus, we have our own version. 180 // showWindow:. Thus, we have our own version.
199 - (void)showWindow:(id)sender { 181 - (void)showWindow:(id)sender {
182 NSWindow* window = [self window]; // Force load the NIB.
183 NSWindow* parentWindow = self.parentWindow;
200 BrowserWindowController* bwc = 184 BrowserWindowController* bwc =
201 [BrowserWindowController browserWindowControllerForWindow:parentWindow_]; 185 [BrowserWindowController browserWindowControllerForWindow:parentWindow];
202 [bwc lockBarVisibilityForOwner:self withAnimation:NO delay:NO]; 186 [bwc lockBarVisibilityForOwner:self withAnimation:NO delay:NO];
203 NSWindow* window = [self window]; // completes nib load 187
204 [bubble_ setArrowLocation:info_bubble::kTopRight]; 188 InfoBubbleView* bubble = self.bubble;
189 [bubble setArrowLocation:info_bubble::kTopRight];
190
205 // Insure decent positioning even in the absence of a browser controller, 191 // Insure decent positioning even in the absence of a browser controller,
206 // which will occur for some unit tests. 192 // which will occur for some unit tests.
207 NSPoint arrowtip = bwc ? [bwc bookmarkBubblePoint] : 193 NSPoint arrowTip = bwc ? [bwc bookmarkBubblePoint] :
208 NSMakePoint([window frame].size.width, [window frame].size.height); 194 NSMakePoint([window frame].size.width, [window frame].size.height);
209 NSPoint origin = [parentWindow_ convertBaseToScreen:arrowtip]; 195 arrowTip = [parentWindow convertBaseToScreen:arrowTip];
210 NSPoint bubbleArrowtip = [bubble_ arrowTip]; 196 NSPoint bubbleArrowTip = [bubble arrowTip];
211 bubbleArrowtip = [bubble_ convertPoint:bubbleArrowtip toView:nil]; 197 bubbleArrowTip = [bubble convertPoint:bubbleArrowTip toView:nil];
212 origin.y -= bubbleArrowtip.y; 198 arrowTip.y -= bubbleArrowTip.y;
213 origin.x -= bubbleArrowtip.x; 199 arrowTip.x -= bubbleArrowTip.x;
214 [window setFrameOrigin:origin]; 200 [window setFrameOrigin:arrowTip];
215 [parentWindow_ addChildWindow:window ordered:NSWindowAbove]; 201
216 // Default is IDS_BOOKMARK_BUBBLE_PAGE_BOOKMARK; "Bookmark". 202 // Default is IDS_BOOKMARK_BUBBLE_PAGE_BOOKMARK; "Bookmark".
217 // If adding for the 1st time the string becomes "Bookmark Added!" 203 // If adding for the 1st time the string becomes "Bookmark Added!"
218 if (!alreadyBookmarked_) { 204 if (!alreadyBookmarked_) {
219 NSString* title = 205 NSString* title =
220 l10n_util::GetNSString(IDS_BOOKMARK_BUBBLE_PAGE_BOOKMARKED); 206 l10n_util::GetNSString(IDS_BOOKMARK_BUBBLE_PAGE_BOOKMARKED);
221 [bigTitle_ setStringValue:title]; 207 [bigTitle_ setStringValue:title];
222 } 208 }
223 209
224 [self fillInFolderList]; 210 [self fillInFolderList];
225 211
226 // Ping me when things change out from under us. Unlike a normal 212 // Ping me when things change out from under us. Unlike a normal
227 // dialog, the bookmark bubble's cancel: means "don't add this as a 213 // dialog, the bookmark bubble's cancel: means "don't add this as a
228 // bookmark", not "cancel editing". We must take extra care to not 214 // bookmark", not "cancel editing". We must take extra care to not
229 // touch the bookmark in this selector. 215 // touch the bookmark in this selector.
230 bookmark_observer_.reset(new BookmarkModelObserverForCocoa( 216 bookmark_observer_.reset(new BookmarkModelObserverForCocoa(
231 node_, model_, 217 node_, model_,
232 self, 218 self,
233 @selector(dismissWithoutEditing:))); 219 @selector(dismissWithoutEditing:)));
234 chrome_observer_.reset(new BookmarkBubbleNotificationBridge( 220 chrome_observer_.reset(new BookmarkBubbleNotificationBridge(
235 self, @selector(dismissWithoutEditing:))); 221 self, @selector(dismissWithoutEditing:)));
236 222
237 // Pulse something interesting on the bookmark bar. 223 // Pulse something interesting on the bookmark bar.
238 [self startPulsingBookmarkButton:node_]; 224 [self startPulsingBookmarkButton:node_];
239 225
226 [parentWindow addChildWindow:window ordered:NSWindowAbove];
240 [window makeKeyAndOrderFront:self]; 227 [window makeKeyAndOrderFront:self];
241 } 228 }
242 229
243 - (void)close { 230 - (void)close {
244 [[BrowserWindowController browserWindowControllerForWindow:parentWindow_] 231 [[BrowserWindowController browserWindowControllerForWindow:self.parentWindow]
245 releaseBarVisibilityForOwner:self withAnimation:YES delay:NO]; 232 releaseBarVisibilityForOwner:self withAnimation:YES delay:NO];
246 [parentWindow_ removeChildWindow:[self window]];
247
248 // If you quit while the bubble is open, sometimes we get a
249 // DidResignKey before we get our parent's WindowWillClose and
250 // sometimes not. We protect against a multiple close (or reference
251 // to parentWindow_ at a bad time) by clearing it out once we're
252 // done, and by removing ourself from future notifications.
253 [[NSNotificationCenter defaultCenter]
254 removeObserver:self
255 name:NSWindowWillCloseNotification
256 object:parentWindow_];
257 parentWindow_ = nil;
258 233
259 [super close]; 234 [super close];
260 } 235 }
261 236
262 // Shows the bookmark editor sheet for more advanced editing. 237 // Shows the bookmark editor sheet for more advanced editing.
263 - (void)showEditor { 238 - (void)showEditor {
264 [self ok:self]; 239 [self ok:self];
265 // Send the action up through the responder chain. 240 // Send the action up through the responder chain.
266 [NSApp sendAction:@selector(editBookmarkNode:) to:nil from:self]; 241 [NSApp sendAction:@selector(editBookmarkNode:) to:nil from:self];
267 } 242 }
(...skipping 29 matching lines...) Expand all
297 [self ok:sender]; 272 [self ok:sender];
298 } 273 }
299 274
300 // The controller is the target of the pop up button box action so it can 275 // The controller is the target of the pop up button box action so it can
301 // handle when "choose another folder" was picked. 276 // handle when "choose another folder" was picked.
302 - (IBAction)folderChanged:(id)sender { 277 - (IBAction)folderChanged:(id)sender {
303 DCHECK([sender isEqual:folderPopUpButton_]); 278 DCHECK([sender isEqual:folderPopUpButton_]);
304 // It is possible that due to model change our parent window has been closed 279 // It is possible that due to model change our parent window has been closed
305 // but the popup is still showing and able to notify the controller of a 280 // but the popup is still showing and able to notify the controller of a
306 // folder change. We ignore the sender in this case. 281 // folder change. We ignore the sender in this case.
307 if (!parentWindow_) 282 if (!self.parentWindow)
308 return; 283 return;
309 NSMenuItem* selected = [folderPopUpButton_ selectedItem]; 284 NSMenuItem* selected = [folderPopUpButton_ selectedItem];
310 ChooseAnotherFolder* chooseItem = [[self class] chooseAnotherFolderObject]; 285 ChooseAnotherFolder* chooseItem = [[self class] chooseAnotherFolderObject];
311 if ([[selected representedObject] isEqual:chooseItem]) { 286 if ([[selected representedObject] isEqual:chooseItem]) {
312 content::RecordAction( 287 content::RecordAction(
313 UserMetricsAction("BookmarkBubble_EditFromCombobox")); 288 UserMetricsAction("BookmarkBubble_EditFromCombobox"));
314 [self showEditor]; 289 [self showEditor];
315 } 290 }
316 } 291 }
317 292
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 [item setRepresentedObject:obj]; 350 [item setRepresentedObject:obj];
376 // Finally, select the current parent. 351 // Finally, select the current parent.
377 NSValue* parentValue = [NSValue valueWithPointer:node_->parent()]; 352 NSValue* parentValue = [NSValue valueWithPointer:node_->parent()];
378 NSInteger idx = [menu indexOfItemWithRepresentedObject:parentValue]; 353 NSInteger idx = [menu indexOfItemWithRepresentedObject:parentValue];
379 [folderPopUpButton_ selectItemAtIndex:idx]; 354 [folderPopUpButton_ selectItemAtIndex:idx];
380 } 355 }
381 356
382 @end // BookmarkBubbleController 357 @end // BookmarkBubbleController
383 358
384 359
385 @implementation BookmarkBubbleController(ExposedForUnitTesting) 360 @implementation BookmarkBubbleController (ExposedForUnitTesting)
386 361
387 + (NSString*)chooseAnotherFolderString { 362 + (NSString*)chooseAnotherFolderString {
388 return l10n_util::GetNSStringWithFixup( 363 return l10n_util::GetNSStringWithFixup(
389 IDS_BOOKMARK_BUBBLE_CHOOSER_ANOTHER_FOLDER); 364 IDS_BOOKMARK_BUBBLE_CHOOSER_ANOTHER_FOLDER);
390 } 365 }
391 366
392 // For the given folder node, walk the tree and add folder names to 367 // For the given folder node, walk the tree and add folder names to
393 // the given pop up button. 368 // the given pop up button.
394 - (void)addFolderNodes:(const BookmarkNode*)parent 369 - (void)addFolderNodes:(const BookmarkNode*)parent
395 toPopUpButton:(NSPopUpButton*)button 370 toPopUpButton:(NSPopUpButton*)button
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 NSInteger idx = [menu indexOfItemWithRepresentedObject:parentValue]; 403 NSInteger idx = [menu indexOfItemWithRepresentedObject:parentValue];
429 DCHECK(idx != -1); 404 DCHECK(idx != -1);
430 [folderPopUpButton_ selectItemAtIndex:idx]; 405 [folderPopUpButton_ selectItemAtIndex:idx];
431 } 406 }
432 407
433 - (NSPopUpButton*)folderPopUpButton { 408 - (NSPopUpButton*)folderPopUpButton {
434 return folderPopUpButton_; 409 return folderPopUpButton_;
435 } 410 }
436 411
437 @end // implementation BookmarkBubbleController(ExposedForUnitTesting) 412 @end // implementation BookmarkBubbleController(ExposedForUnitTesting)
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698