| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 #include "base/mac_util.h" | 5 #include "base/mac_util.h" |
| 6 #include "base/sys_string_conversions.h" | 6 #include "base/sys_string_conversions.h" |
| 7 #include "chrome/browser/bookmarks/bookmark_editor.h" | 7 #include "chrome/browser/bookmarks/bookmark_editor.h" |
| 8 #include "chrome/browser/bookmarks/bookmark_model.h" | 8 #include "chrome/browser/bookmarks/bookmark_model.h" |
| 9 #include "chrome/browser/browser.h" | 9 #include "chrome/browser/browser.h" |
| 10 #include "chrome/browser/browser_list.h" | 10 #include "chrome/browser/browser_list.h" |
| 11 #import "chrome/browser/cocoa/bookmark_bar_bridge.h" | 11 #import "chrome/browser/cocoa/bookmark_bar_bridge.h" |
| 12 #import "chrome/browser/cocoa/bookmark_bar_controller.h" | 12 #import "chrome/browser/cocoa/bookmark_bar_controller.h" |
| 13 #import "chrome/browser/cocoa/bookmark_bar_view.h" | |
| 14 #import "chrome/browser/cocoa/bookmark_button_cell.h" | 13 #import "chrome/browser/cocoa/bookmark_button_cell.h" |
| 15 #import "chrome/browser/cocoa/bookmark_editor_controller.h" | 14 #import "chrome/browser/cocoa/bookmark_editor_controller.h" |
| 16 #import "chrome/browser/cocoa/bookmark_name_folder_controller.h" | 15 #import "chrome/browser/cocoa/bookmark_name_folder_controller.h" |
| 16 #import "chrome/browser/cocoa/bookmark_menu_cocoa_controller.h" |
| 17 #include "chrome/browser/cocoa/nsimage_cache.h" |
| 17 #include "chrome/browser/profile.h" | 18 #include "chrome/browser/profile.h" |
| 18 #include "chrome/common/pref_names.h" | 19 #include "chrome/common/pref_names.h" |
| 19 #include "chrome/common/pref_service.h" | 20 #include "chrome/common/pref_service.h" |
| 20 #include "skia/ext/skia_utils_mac.h" | 21 #include "skia/ext/skia_utils_mac.h" |
| 21 | 22 |
| 22 @interface BookmarkBarController(Private) | 23 @interface BookmarkBarController(Private) |
| 23 - (void)applyContentAreaOffset:(BOOL)apply immediately:(BOOL)immediately; | 24 - (void)applyContentAreaOffset:(BOOL)apply immediately:(BOOL)immediately; |
| 24 - (void)showBookmarkBar:(BOOL)enable immediately:(BOOL)immediately; | 25 - (void)showBookmarkBar:(BOOL)enable immediately:(BOOL)immediately; |
| 26 - (void)addNode:(const BookmarkNode*)child toMenu:(NSMenu*)menu; |
| 27 - (void)addFolderNode:(const BookmarkNode*)node toMenu:(NSMenu*)menu; |
| 28 - (void)tagEmptyMenu:(NSMenu*)menu; |
| 29 - (void)clearMenuTagMap; |
| 25 @end | 30 @end |
| 26 | 31 |
| 27 namespace { | 32 namespace { |
| 28 | 33 |
| 29 // TODO(jrg): this is the right proportional height but overlaps the | 34 // TODO(jrg): this is the right proportional height but overlaps the |
| 30 // "blue outline" of the omnibox. Fix. | 35 // "blue outline" of the omnibox. Fix. |
| 31 | 36 |
| 32 // Our height, when opened. | 37 // Our height, when opened. |
| 33 const int kBookmarkBarHeight = 30; | 38 const int kBookmarkBarHeight = 30; |
| 34 // How much to adjust our parent view. | 39 // How much to adjust our parent view. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 55 bookmarkModel_ = profile->GetBookmarkModel(); | 60 bookmarkModel_ = profile->GetBookmarkModel(); |
| 56 parentView_ = parentView; | 61 parentView_ = parentView; |
| 57 webContentView_ = webContentView; | 62 webContentView_ = webContentView; |
| 58 infoBarsView_ = infoBarsView; | 63 infoBarsView_ = infoBarsView; |
| 59 buttons_.reset([[NSMutableArray alloc] init]); | 64 buttons_.reset([[NSMutableArray alloc] init]); |
| 60 delegate_ = delegate; | 65 delegate_ = delegate; |
| 61 } | 66 } |
| 62 return self; | 67 return self; |
| 63 } | 68 } |
| 64 | 69 |
| 70 - (void)dealloc { |
| 71 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 72 [super dealloc]; |
| 73 } |
| 74 |
| 65 - (void)awakeFromNib { | 75 - (void)awakeFromNib { |
| 66 // We default to NOT open, which means height=0. | 76 // We default to NOT open, which means height=0. |
| 67 DCHECK([[self view] isHidden]); // Hidden so it's OK to change. | 77 DCHECK([[self view] isHidden]); // Hidden so it's OK to change. |
| 68 NSRect frame = [[self view] frame]; | 78 NSRect frame = [[self view] frame]; |
| 69 frame.size.height = 0; | 79 frame.size.height = 0; |
| 70 frame.size.width = [parentView_ frame].size.width; | 80 frame.size.width = [parentView_ frame].size.width; |
| 71 [[self view] setFrame:frame]; | 81 [[self view] setFrame:frame]; |
| 72 | 82 |
| 73 // Make sure the nodes stay bottom-aligned. | 83 // Make sure the nodes stay bottom-aligned. |
| 74 [[self view] setAutoresizingMask:(NSViewWidthSizable | | 84 [[self view] setAutoresizingMask:(NSViewWidthSizable | |
| 75 NSViewMinYMargin)]; | 85 NSViewMinYMargin)]; |
| 76 // Be sure to enable the bar before trying to show it... | 86 // Be sure to enable the bar before trying to show it... |
| 77 barIsEnabled_ = YES; | 87 barIsEnabled_ = YES; |
| 78 if (profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar)) | 88 if (profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar)) |
| 79 [self showBookmarkBar:YES immediately:YES]; | 89 [self showBookmarkBar:YES immediately:YES]; |
| 80 | 90 |
| 81 // Don't pass ourself along (as 'self') until our init is completely | 91 // Don't pass ourself along (as 'self') until our init is completely |
| 82 // done. Thus, this call is (almost) last. | 92 // done. Thus, this call is (almost) last. |
| 83 bridge_.reset(new BookmarkBarBridge(self, bookmarkModel_)); | 93 bridge_.reset(new BookmarkBarBridge(self, bookmarkModel_)); |
| 94 |
| 95 // When resized we may need to add new buttons, or remove them (if |
| 96 // no longer visible), or add/remove the "off the side" menu. |
| 97 [[self view] setPostsFrameChangedNotifications:YES]; |
| 98 [[NSNotificationCenter defaultCenter] |
| 99 addObserver:self |
| 100 selector:@selector(frameDidChange) |
| 101 name:NSViewFrameDidChangeNotification |
| 102 object:[self view]]; |
| 103 } |
| 104 |
| 105 // Check if we should enable the off-the-side button. |
| 106 // TODO(jrg): when we are smarter about creating buttons (e.g. don't |
| 107 // bother creating buttons which aren't visible), we'll have to be |
| 108 // smarter here too. |
| 109 - (void)checkEnableOffTheSideButton { |
| 110 NSButton* button = [buttons_ lastObject]; |
| 111 if ((!button) || |
| 112 (NSMaxX([button frame]) <= |
| 113 NSMaxX([[button superview] frame]))) { |
| 114 [offTheSideButton_ setEnabled:NO]; |
| 115 } else { |
| 116 [offTheSideButton_ setEnabled:YES]; |
| 117 } |
| 118 } |
| 119 |
| 120 - (BOOL)offTheSideButtonIsEnabled { |
| 121 return [offTheSideButton_ isEnabled]; |
| 122 } |
| 123 |
| 124 // Called when our controlled frame has changed size. |
| 125 // TODO(jrg): be smarter (e.g. add/remove buttons as appropriate). |
| 126 - (void)frameDidChange { |
| 127 [self checkEnableOffTheSideButton]; |
| 84 } | 128 } |
| 85 | 129 |
| 86 // Show or hide the bar based on the value of |show|. Handles | 130 // Show or hide the bar based on the value of |show|. Handles |
| 87 // animating the resize of the content view. if |immediately| is YES, | 131 // animating the resize of the content view. if |immediately| is YES, |
| 88 // make changes immediately instead of using an animator. If the bar | 132 // make changes immediately instead of using an animator. If the bar |
| 89 // is disabled, do absolutely nothing. The routine which enables the | 133 // is disabled, do absolutely nothing. The routine which enables the |
| 90 // bar will show it if relevant using other mechanisms (the pref) to | 134 // bar will show it if relevant using other mechanisms (the pref) to |
| 91 // determine desired state. | 135 // determine desired state. |
| 92 - (void)showBookmarkBar:(BOOL)show immediately:(BOOL)immediately { | 136 - (void)showBookmarkBar:(BOOL)show immediately:(BOOL)immediately { |
| 93 if (barIsEnabled_ && (barShouldBeShown_ != show)) { | 137 if (barIsEnabled_ && (barShouldBeShown_ != show)) { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 [[cell representedObject] pointerValue]); | 255 [[cell representedObject] pointerValue]); |
| 212 DCHECK(node); | 256 DCHECK(node); |
| 213 return node; | 257 return node; |
| 214 } | 258 } |
| 215 | 259 |
| 216 - (IBAction)openBookmark:(id)sender { | 260 - (IBAction)openBookmark:(id)sender { |
| 217 BookmarkNode* node = [self nodeFromButton:sender]; | 261 BookmarkNode* node = [self nodeFromButton:sender]; |
| 218 [delegate_ openBookmarkURL:node->GetURL() disposition:CURRENT_TAB]; | 262 [delegate_ openBookmarkURL:node->GetURL() disposition:CURRENT_TAB]; |
| 219 } | 263 } |
| 220 | 264 |
| 265 // Given a NSMenuItem tag, return the appropriate bookmark node id. |
| 266 - (int64)nodeIdFromMenuTag:(int32)tag { |
| 267 return menuTagMap_[tag]; |
| 268 } |
| 269 |
| 270 // Create and return a new tag for the given node id. |
| 271 - (int32)menuTagFromNodeId:(int64)menuid { |
| 272 int tag = seedId_++; |
| 273 menuTagMap_[tag] = menuid; |
| 274 return tag; |
| 275 } |
| 276 |
| 277 - (void)clearMenuTagMap { |
| 278 seedId_ = 0; |
| 279 menuTagMap_.clear(); |
| 280 } |
| 281 |
| 282 // Recursively add the given bookmark node and all its children to |
| 283 // menu, one menu item per node. |
| 284 - (void)addNode:(const BookmarkNode*)child toMenu:(NSMenu*)menu { |
| 285 NSString* title = [BookmarkMenuCocoaController menuTitleForNode:child]; |
| 286 NSMenuItem* item = [[[NSMenuItem alloc] initWithTitle:title |
| 287 action:nil |
| 288 keyEquivalent:@""] autorelease]; |
| 289 [menu addItem:item]; |
| 290 if (child->is_folder()) { |
| 291 NSMenu* submenu = [[[NSMenu alloc] initWithTitle:title] autorelease]; |
| 292 [menu setSubmenu:submenu forItem:item]; |
| 293 if (child->GetChildCount()) { |
| 294 [self addFolderNode:child toMenu:submenu]; // potentially recursive |
| 295 } else { |
| 296 [self tagEmptyMenu:submenu]; |
| 297 } |
| 298 } else { |
| 299 [item setTarget:self]; |
| 300 [item setAction:@selector(openBookmarkMenuItem:)]; |
| 301 [item setTag:[self menuTagFromNodeId:child->id()]]; |
| 302 // Add a tooltip |
| 303 std::string url_string = child->GetURL().possibly_invalid_spec(); |
| 304 NSString* tooltip = [NSString stringWithFormat:@"%@\n%s", |
| 305 base::SysWideToNSString(child->GetTitle()), |
| 306 url_string.c_str()]; |
| 307 [item setToolTip:tooltip]; |
| 308 |
| 309 } |
| 310 } |
| 311 |
| 312 // Empty menus are odd; if empty, add something to look at. |
| 313 // Matches windows behavior. |
| 314 // TODO(jrg): localize. |
| 315 - (void)tagEmptyMenu:(NSMenu*)menu { |
| 316 [menu addItem:[[[NSMenuItem alloc] initWithTitle:@"(empty)" |
| 317 action:NULL |
| 318 keyEquivalent:@""] autorelease]]; |
| 319 } |
| 320 |
| 321 // Add the children of the given bookmark node (and their children...) |
| 322 // to menu, one menu item per node. |
| 323 - (void)addFolderNode:(const BookmarkNode*)node toMenu:(NSMenu*)menu { |
| 324 for (int i = 0; i < node->GetChildCount(); i++) { |
| 325 const BookmarkNode* child = node->GetChild(i); |
| 326 [self addNode:child toMenu:menu]; |
| 327 } |
| 328 } |
| 329 |
| 330 // Return an autoreleased NSMenu that represents the given bookmark |
| 331 // folder node. |
| 332 - (NSMenu *)menuForFolderNode:(const BookmarkNode*)node { |
| 333 if (!node->is_folder()) |
| 334 return nil; |
| 335 NSString* title = base::SysWideToNSString(node->GetTitle()); |
| 336 NSMenu* menu = [[[NSMenu alloc] initWithTitle:title] autorelease]; |
| 337 [self addFolderNode:node toMenu:menu]; |
| 338 |
| 339 if (![menu numberOfItems]) { |
| 340 [self tagEmptyMenu:menu]; |
| 341 } |
| 342 return menu; |
| 343 } |
| 344 |
| 345 // Called from a Folder bookmark button. |
| 346 - (IBAction)openFolderMenuFromButton:(id)sender { |
| 347 NSMenu* menu = [self menuForFolderNode:[self nodeFromButton:sender]]; |
| 348 if (menu) { |
| 349 [NSMenu popUpContextMenu:menu |
| 350 withEvent:[NSApp currentEvent] |
| 351 forView:sender]; |
| 352 } |
| 353 } |
| 354 |
| 355 // TODO(jrg): cache the menu so we don't need to build it every time. |
| 356 // TODO(jrg): if we get smarter such that we don't even bother |
| 357 // creating buttons which aren't visible, we'll need to be smarter |
| 358 // here. |
| 359 - (IBAction)openOffTheSideMenuFromButton:(id)sender { |
| 360 scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@""]); |
| 361 for (NSButton* each_button in buttons_.get()) { |
| 362 if (NSMaxX([each_button frame]) > |
| 363 NSMaxX([[each_button superview] frame])) { |
| 364 [self addNode:[self nodeFromButton:each_button] toMenu:menu.get()]; |
| 365 } |
| 366 } |
| 367 |
| 368 // TODO(jrg): once we disable the button when the menu should be |
| 369 // empty, remove this 'helper'. |
| 370 if (![menu numberOfItems]) { |
| 371 [self tagEmptyMenu:menu]; |
| 372 } |
| 373 |
| 374 [NSMenu popUpContextMenu:menu |
| 375 withEvent:[NSApp currentEvent] |
| 376 forView:sender]; |
| 377 } |
| 378 |
| 221 // As a convention we set the menu's delegate to be the button's cell | 379 // As a convention we set the menu's delegate to be the button's cell |
| 222 // so we can easily obtain bookmark info. Convention applied in | 380 // so we can easily obtain bookmark info. Convention applied in |
| 223 // -[BookmarkButtonCell menu]. | 381 // -[BookmarkButtonCell menu]. |
| 224 | 382 |
| 225 - (IBAction)openBookmarkInNewForegroundTab:(id)sender { | 383 - (IBAction)openBookmarkInNewForegroundTab:(id)sender { |
| 226 BookmarkNode* node = [self nodeFromMenuItem:sender]; | 384 BookmarkNode* node = [self nodeFromMenuItem:sender]; |
| 227 [delegate_ openBookmarkURL:node->GetURL() disposition:NEW_FOREGROUND_TAB]; | 385 [delegate_ openBookmarkURL:node->GetURL() disposition:NEW_FOREGROUND_TAB]; |
| 228 } | 386 } |
| 229 | 387 |
| 230 - (IBAction)openBookmarkInNewWindow:(id)sender { | 388 - (IBAction)openBookmarkInNewWindow:(id)sender { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 | 440 |
| 283 - (IBAction)openAllBookmarks:(id)sender { | 441 - (IBAction)openAllBookmarks:(id)sender { |
| 284 // TODO(jrg): | 442 // TODO(jrg): |
| 285 // Is there an easier way to get a non-const root node for the bookmark bar? | 443 // Is there an easier way to get a non-const root node for the bookmark bar? |
| 286 // I can't iterate over them unless it's non-const. | 444 // I can't iterate over them unless it's non-const. |
| 287 | 445 |
| 288 BookmarkNode* node = (BookmarkNode*)bookmarkModel_->GetBookmarkBarNode(); | 446 BookmarkNode* node = (BookmarkNode*)bookmarkModel_->GetBookmarkBarNode(); |
| 289 [self openBookmarkNodesRecursive:node]; | 447 [self openBookmarkNodesRecursive:node]; |
| 290 } | 448 } |
| 291 | 449 |
| 450 // May be called from the bar or from a folder button. |
| 451 // If called from a button, that button becomes the parent. |
| 292 - (IBAction)addPage:(id)sender { | 452 - (IBAction)addPage:(id)sender { |
| 453 const BookmarkNode* parent = [self nodeFromMenuItem:sender]; |
| 454 if (!parent) |
| 455 parent = bookmarkModel_->GetBookmarkBarNode(); |
| 293 BookmarkEditor::Show([[[self view] window] contentView], | 456 BookmarkEditor::Show([[[self view] window] contentView], |
| 294 profile_, | 457 profile_, |
| 295 bookmarkModel_->GetBookmarkBarNode(), | 458 parent, |
| 296 nil, | 459 nil, |
| 297 BookmarkEditor::SHOW_TREE, | 460 BookmarkEditor::SHOW_TREE, |
| 298 nil); | 461 nil); |
| 299 } | 462 } |
| 300 | 463 |
| 301 // Might be from the context menu over the bar OR over a button. | 464 // Might be from the context menu over the bar OR over a button. |
| 302 - (IBAction)addOrRenameFolder:(id)sender { | 465 - (IBAction)addOrRenameFolder:(id)sender { |
| 303 // node is NULL if we were invoked from the bar, and that's fine. | 466 // node is NULL if we were invoked from the bar, and that's fine. |
| 304 BookmarkNode* node = [self nodeFromMenuItem:sender]; | 467 BookmarkNode* node = [self nodeFromMenuItem:sender]; |
| 305 BookmarkNameFolderController* controller = | 468 BookmarkNameFolderController* controller = |
| 306 [[BookmarkNameFolderController alloc] | 469 [[BookmarkNameFolderController alloc] |
| 307 initWithParentWindow:[[self view] window] | 470 initWithParentWindow:[[self view] window] |
| 308 profile:profile_ | 471 profile:profile_ |
| 309 node:node]; | 472 node:node]; |
| 310 [controller runModal]; | 473 [controller runModal]; |
| 311 | 474 |
| 312 // runModal will run the window as a sheet. The | 475 // runModal will run the window as a sheet. The |
| 313 // BookmarkNameFolderController will release itself when the sheet | 476 // BookmarkNameFolderController will release itself when the sheet |
| 314 // ends. | 477 // ends. |
| 315 } | 478 } |
| 316 | 479 |
| 317 // Delete all bookmarks from the bookmark bar. | 480 - (NSView*)buttonView { |
| 481 return buttonView_; |
| 482 } |
| 483 |
| 484 // Delete all bookmarks from the bookmark bar, and reset knowledge of |
| 485 // bookmarks. |
| 318 - (void)clearBookmarkBar { | 486 - (void)clearBookmarkBar { |
| 319 [buttons_ makeObjectsPerformSelector:@selector(removeFromSuperview)]; | 487 [buttons_ makeObjectsPerformSelector:@selector(removeFromSuperview)]; |
| 320 [buttons_ removeAllObjects]; | 488 [buttons_ removeAllObjects]; |
| 489 [self clearMenuTagMap]; |
| 321 } | 490 } |
| 322 | 491 |
| 323 // Return an autoreleased NSCell suitable for a bookmark button. | 492 // Return an autoreleased NSCell suitable for a bookmark button. |
| 324 // TODO(jrg): move much of the cell config into the BookmarkButtonCell class. | 493 // TODO(jrg): move much of the cell config into the BookmarkButtonCell class. |
| 325 - (NSCell*)cellForBookmarkNode:(const BookmarkNode*)node { | 494 - (NSCell*)cellForBookmarkNode:(const BookmarkNode*)node { |
| 326 NSString* title = base::SysWideToNSString(node->GetTitle()); | 495 NSString* title = base::SysWideToNSString(node->GetTitle()); |
| 327 NSButtonCell *cell = [[[BookmarkButtonCell alloc] initTextCell:nil] | 496 NSButtonCell *cell = [[[BookmarkButtonCell alloc] initTextCell:nil] |
| 328 autorelease]; | 497 autorelease]; |
| 329 DCHECK(cell); | 498 DCHECK(cell); |
| 330 [cell setRepresentedObject:[NSValue valueWithPointer:node]]; | 499 [cell setRepresentedObject:[NSValue valueWithPointer:node]]; |
| 331 | 500 |
| 332 // The favicon may be NULL if we haven't loaded it yet. Bookmarks | 501 NSImage* image = NULL; |
| 333 // (and their icons) are loaded on the IO thread to speed launch. | 502 if (node->is_folder()) { |
| 334 const SkBitmap& favicon = bookmarkModel_->GetFavIcon(node); | 503 image = nsimage_cache::ImageNamed(@"bookmark_bar_folder.png"); |
| 335 if (!favicon.isNull()) { | 504 } else { |
| 336 NSImage* image = gfx::SkBitmapToNSImage(favicon); | 505 const SkBitmap& favicon = bookmarkModel_->GetFavIcon(node); |
| 337 if (image) { | 506 if (!favicon.isNull()) { |
| 338 [cell setImage:image]; | 507 image = gfx::SkBitmapToNSImage(favicon); |
| 339 [cell setImagePosition:NSImageLeft]; | |
| 340 } | 508 } |
| 341 } | 509 } |
| 510 if (image) { |
| 511 [cell setImage:image]; |
| 512 [cell setImagePosition:NSImageLeft]; |
| 513 } |
| 342 [cell setTitle:title]; | 514 [cell setTitle:title]; |
| 343 [cell setMenu:buttonContextMenu_]; | 515 [cell setMenu:buttonContextMenu_]; |
| 344 return cell; | 516 return cell; |
| 345 } | 517 } |
| 346 | 518 |
| 347 // Return an appropriate width for the given bookmark button cell. | 519 // Return an appropriate width for the given bookmark button cell. |
| 348 // The "+1" is needed because, sometimes, Cocoa is off by one. | 520 // The "+1" is needed because, sometimes, Cocoa is off by one. |
| 349 // Example: for a bookmark named "Moma" or "SFGate", it is one pixel | 521 // Example: for a bookmark named "Moma" or "SFGate", it is one pixel |
| 350 // too small. For a bookmark named "SFGateFooWoo", it is just fine. | 522 // too small. For a bookmark named "SFGateFooWoo", it is just fine. |
| 351 - (CGFloat)widthForBookmarkButtonCell:(NSCell*)cell { | 523 - (CGFloat)widthForBookmarkButtonCell:(NSCell*)cell { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 for (NSButton* each_button in buttons_.get()) { | 562 for (NSButton* each_button in buttons_.get()) { |
| 391 NSRect each_frame = [each_button frame]; | 563 NSRect each_frame = [each_button frame]; |
| 392 if (each_frame.origin.x > frame.origin.x) { | 564 if (each_frame.origin.x > frame.origin.x) { |
| 393 each_frame.origin.x += delta; | 565 each_frame.origin.x += delta; |
| 394 [each_button setFrame:each_frame]; | 566 [each_button setFrame:each_frame]; |
| 395 } | 567 } |
| 396 } | 568 } |
| 397 } | 569 } |
| 398 } | 570 } |
| 399 | 571 |
| 572 - (IBAction)openBookmarkMenuItem:(id)sender { |
| 573 int64 tag = [self nodeIdFromMenuTag:[sender tag]]; |
| 574 const BookmarkNode* node = bookmarkModel_->GetNodeByID(tag); |
| 575 [delegate_ openBookmarkURL:node->GetURL() disposition:CURRENT_TAB]; |
| 576 } |
| 577 |
| 400 // Add all items from the given model to our bookmark bar. | 578 // Add all items from the given model to our bookmark bar. |
| 401 // TODO(jrg): lots of things! | 579 // TODO(jrg): lots of things! |
| 402 // - bookmark folders (e.g. menu from the button) | 580 // - bookmark folders (e.g. menu from the button) |
| 403 // - button and menu on the right for when bookmarks don't all fit on the | 581 // - button and menu on the right for when bookmarks don't all fit on the |
| 404 // screen | 582 // screen |
| 405 // - ... | 583 // - ... |
| 406 // | 584 // |
| 407 // TODO(jrg): write a "build bar" so there is a nice spot for things | 585 // TODO(jrg): write a "build bar" so there is a nice spot for things |
| 408 // like the contextual menu which is invoked when not over a | 586 // like the contextual menu which is invoked when not over a |
| 409 // bookmark. On Safari that menu has a "new folder" option. | 587 // bookmark. On Safari that menu has a "new folder" option. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 420 [buttons_ addObject:button]; | 598 [buttons_ addObject:button]; |
| 421 | 599 |
| 422 // [NSButton setCell:] warns to NOT use setCell: other than in the | 600 // [NSButton setCell:] warns to NOT use setCell: other than in the |
| 423 // initializer of a control. However, we are using a basic | 601 // initializer of a control. However, we are using a basic |
| 424 // NSButton whose initializer does not take an NSCell as an | 602 // NSButton whose initializer does not take an NSCell as an |
| 425 // object. To honor the assumed semantics, we do nothing with | 603 // object. To honor the assumed semantics, we do nothing with |
| 426 // NSButton between alloc/init and setCell:. | 604 // NSButton between alloc/init and setCell:. |
| 427 [button setCell:cell]; | 605 [button setCell:cell]; |
| 428 | 606 |
| 429 if (child->is_folder()) { | 607 if (child->is_folder()) { |
| 430 // For now just disable the button if it's a folder. | 608 [button setTarget:self]; |
| 431 // TODO(jrg): recurse. | 609 [button setAction:@selector(openFolderMenuFromButton:)]; |
| 432 [button setEnabled:NO]; | |
| 433 } else { | 610 } else { |
| 434 // Make the button do something | 611 // Make the button do something |
| 435 [button setTarget:self]; | 612 [button setTarget:self]; |
| 436 [button setAction:@selector(openBookmark:)]; | 613 [button setAction:@selector(openBookmark:)]; |
| 437 // Add a tooltip. | 614 // Add a tooltip. |
| 438 NSString* title = base::SysWideToNSString(child->GetTitle()); | 615 NSString* title = base::SysWideToNSString(child->GetTitle()); |
| 439 std::string url_string = child->GetURL().possibly_invalid_spec(); | 616 std::string url_string = child->GetURL().possibly_invalid_spec(); |
| 440 NSString* tooltip = [NSString stringWithFormat:@"%@\n%s", title, | 617 NSString* tooltip = [NSString stringWithFormat:@"%@\n%s", title, |
| 441 url_string.c_str()]; | 618 url_string.c_str()]; |
| 442 [button setToolTip:tooltip]; | 619 [button setToolTip:tooltip]; |
| 443 } | 620 } |
| 444 // Finally, add it to the bookmark bar. | 621 // Finally, add it to the bookmark bar. |
| 445 [[self view] addSubview:button]; | 622 [buttonView_ addSubview:button]; |
| 446 } | 623 } |
| 447 } | 624 } |
| 448 | 625 |
| 449 // TODO(jrg): for now this is brute force. | 626 // TODO(jrg): for now this is brute force. |
| 450 - (void)loaded:(BookmarkModel*)model { | 627 - (void)loaded:(BookmarkModel*)model { |
| 451 DCHECK(model == bookmarkModel_); | 628 DCHECK(model == bookmarkModel_); |
| 452 // Do nothing if not active or too early | 629 // Do nothing if not active or too early |
| 453 if ((barShouldBeShown_ == NO) || !model->IsLoaded()) | 630 if ((barShouldBeShown_ == NO) || !model->IsLoaded()) |
| 454 return; | 631 return; |
| 455 // Else brute force nuke and build. | 632 // Else brute force nuke and build. |
| 456 const BookmarkNode* node = model->GetBookmarkBarNode(); | 633 const BookmarkNode* node = model->GetBookmarkBarNode(); |
| 457 [self clearBookmarkBar]; | 634 [self clearBookmarkBar]; |
| 458 [self addNodesToBar:node]; | 635 [self addNodesToBar:node]; |
| 636 [self checkEnableOffTheSideButton]; |
| 459 } | 637 } |
| 460 | 638 |
| 461 - (void)beingDeleted:(BookmarkModel*)model { | 639 - (void)beingDeleted:(BookmarkModel*)model { |
| 462 [self clearBookmarkBar]; | 640 [self clearBookmarkBar]; |
| 463 } | 641 } |
| 464 | 642 |
| 465 // TODO(jrg): for now this is brute force. | 643 // TODO(jrg): for now this is brute force. |
| 466 - (void)nodeMoved:(BookmarkModel*)model | 644 - (void)nodeMoved:(BookmarkModel*)model |
| 467 oldParent:(const BookmarkNode*)oldParent oldIndex:(int)oldIndex | 645 oldParent:(const BookmarkNode*)oldParent oldIndex:(int)oldIndex |
| 468 newParent:(const BookmarkNode*)newParent newIndex:(int)newIndex { | 646 newParent:(const BookmarkNode*)newParent newIndex:(int)newIndex { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 | 702 |
| 525 - (void)setDelegate:(id<BookmarkURLOpener>)delegate { | 703 - (void)setDelegate:(id<BookmarkURLOpener>)delegate { |
| 526 delegate_ = delegate; | 704 delegate_ = delegate; |
| 527 } | 705 } |
| 528 | 706 |
| 529 - (NSArray*)buttons { | 707 - (NSArray*)buttons { |
| 530 return buttons_.get(); | 708 return buttons_.get(); |
| 531 } | 709 } |
| 532 | 710 |
| 533 @end | 711 @end |
| OLD | NEW |