Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 #include "chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h" | 5 #include "chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h" |
| 6 | 6 |
| 7 #include "base/prefs/pref_service.h" | 7 #include "base/prefs/pref_service.h" |
| 8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "chrome/app/chrome_command_ids.h" | |
| 9 #include "chrome/browser/bookmarks/bookmark_model_factory.h" | 10 #include "chrome/browser/bookmarks/bookmark_model_factory.h" |
| 10 #include "chrome/browser/bookmarks/chrome_bookmark_client.h" | 11 #include "chrome/browser/bookmarks/chrome_bookmark_client.h" |
| 11 #include "chrome/browser/bookmarks/chrome_bookmark_client_factory.h" | 12 #include "chrome/browser/bookmarks/chrome_bookmark_client_factory.h" |
| 12 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
| 13 #include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h" | 14 #include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h" |
| 14 #include "chrome/browser/ui/bookmarks/bookmark_utils.h" | 15 #include "chrome/browser/ui/bookmarks/bookmark_utils.h" |
| 15 #include "chrome/browser/ui/browser.h" | 16 #include "chrome/browser/ui/browser.h" |
| 16 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" | 17 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" |
| 17 #include "chrome/browser/ui/views/event_utils.h" | 18 #include "chrome/browser/ui/views/event_utils.h" |
| 18 #include "chrome/common/pref_names.h" | 19 #include "chrome/common/pref_names.h" |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 35 using bookmarks::BookmarkNodeData; | 36 using bookmarks::BookmarkNodeData; |
| 36 using content::PageNavigator; | 37 using content::PageNavigator; |
| 37 using views::MenuItemView; | 38 using views::MenuItemView; |
| 38 | 39 |
| 39 // Max width of a menu. There does not appear to be an OS value for this, yet | 40 // Max width of a menu. There does not appear to be an OS value for this, yet |
| 40 // both IE and FF restrict the max width of a menu. | 41 // both IE and FF restrict the max width of a menu. |
| 41 static const int kMaxMenuWidth = 400; | 42 static const int kMaxMenuWidth = 400; |
| 42 | 43 |
| 43 BookmarkMenuDelegate::BookmarkMenuDelegate(Browser* browser, | 44 BookmarkMenuDelegate::BookmarkMenuDelegate(Browser* browser, |
| 44 PageNavigator* navigator, | 45 PageNavigator* navigator, |
| 45 views::Widget* parent, | 46 views::Widget* parent) |
| 46 int first_menu_id, | |
| 47 int max_menu_id) | |
| 48 : browser_(browser), | 47 : browser_(browser), |
| 49 profile_(browser->profile()), | 48 profile_(browser->profile()), |
| 50 page_navigator_(navigator), | 49 page_navigator_(navigator), |
| 51 parent_(parent), | 50 parent_(parent), |
| 52 menu_(NULL), | 51 menu_(NULL), |
| 53 parent_menu_item_(NULL), | 52 parent_menu_item_(NULL), |
| 54 next_menu_id_(first_menu_id), | 53 next_menu_id_(IDC_FIRST_BOOKMARK_MENU), |
| 55 min_menu_id_(first_menu_id), | |
| 56 max_menu_id_(max_menu_id), | |
| 57 real_delegate_(NULL), | 54 real_delegate_(NULL), |
| 58 is_mutating_model_(false), | 55 is_mutating_model_(false), |
| 59 location_(BOOKMARK_LAUNCH_LOCATION_NONE) {} | 56 location_(BOOKMARK_LAUNCH_LOCATION_NONE) { |
| 57 } | |
| 60 | 58 |
| 61 BookmarkMenuDelegate::~BookmarkMenuDelegate() { | 59 BookmarkMenuDelegate::~BookmarkMenuDelegate() { |
| 62 GetBookmarkModel()->RemoveObserver(this); | 60 GetBookmarkModel()->RemoveObserver(this); |
| 63 } | 61 } |
| 64 | 62 |
| 65 void BookmarkMenuDelegate::Init(views::MenuDelegate* real_delegate, | 63 void BookmarkMenuDelegate::Init(views::MenuDelegate* real_delegate, |
| 66 MenuItemView* parent, | 64 MenuItemView* parent, |
| 67 const BookmarkNode* node, | 65 const BookmarkNode* node, |
| 68 int start_child_index, | 66 int start_child_index, |
| 69 ShowOptions show_options, | 67 ShowOptions show_options, |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 84 bool show_managed = show_forced_folders && !client->managed_node()->empty(); | 82 bool show_managed = show_forced_folders && !client->managed_node()->empty(); |
| 85 bool show_supervised = | 83 bool show_supervised = |
| 86 show_forced_folders && !client->supervised_node()->empty(); | 84 show_forced_folders && !client->supervised_node()->empty(); |
| 87 bool has_children = (start_child_index < node->child_count()) || | 85 bool has_children = (start_child_index < node->child_count()) || |
| 88 show_managed || show_supervised; | 86 show_managed || show_supervised; |
| 89 int initial_count = parent->GetSubmenu() ? | 87 int initial_count = parent->GetSubmenu() ? |
| 90 parent->GetSubmenu()->GetMenuItemCount() : 0; | 88 parent->GetSubmenu()->GetMenuItemCount() : 0; |
| 91 if (has_children && initial_count > 0) | 89 if (has_children && initial_count > 0) |
| 92 parent->AppendSeparator(); | 90 parent->AppendSeparator(); |
| 93 if (show_managed) | 91 if (show_managed) |
| 94 BuildMenuForManagedNode(parent, &next_menu_id_); | 92 BuildMenuForManagedNode(parent); |
| 95 if (show_supervised) | 93 if (show_supervised) |
| 96 BuildMenuForSupervisedNode(parent, &next_menu_id_); | 94 BuildMenuForSupervisedNode(parent); |
| 97 BuildMenu(node, start_child_index, parent, &next_menu_id_); | 95 BuildMenu(node, start_child_index, parent); |
| 98 if (show_options == SHOW_PERMANENT_FOLDERS) | 96 if (show_options == SHOW_PERMANENT_FOLDERS) |
| 99 BuildMenusForPermanentNodes(parent, &next_menu_id_); | 97 BuildMenusForPermanentNodes(parent); |
| 100 } else { | 98 } else { |
| 101 menu_ = CreateMenu(node, start_child_index, show_options); | 99 menu_ = CreateMenu(node, start_child_index, show_options); |
| 102 } | 100 } |
| 103 } | 101 } |
| 104 | 102 |
| 105 void BookmarkMenuDelegate::SetPageNavigator(PageNavigator* navigator) { | 103 void BookmarkMenuDelegate::SetPageNavigator(PageNavigator* navigator) { |
| 106 page_navigator_ = navigator; | 104 page_navigator_ = navigator; |
| 107 if (context_menu_.get()) | 105 if (context_menu_.get()) |
| 108 context_menu_->SetPageNavigator(navigator); | 106 context_menu_->SetPageNavigator(navigator); |
| 109 } | 107 } |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 340 | 338 |
| 341 int BookmarkMenuDelegate::GetDragOperations(MenuItemView* sender) { | 339 int BookmarkMenuDelegate::GetDragOperations(MenuItemView* sender) { |
| 342 return chrome::GetBookmarkDragOperation( | 340 return chrome::GetBookmarkDragOperation( |
| 343 profile_, menu_id_to_node_map_[sender->GetCommand()]); | 341 profile_, menu_id_to_node_map_[sender->GetCommand()]); |
| 344 } | 342 } |
| 345 | 343 |
| 346 int BookmarkMenuDelegate::GetMaxWidthForMenu(MenuItemView* menu) { | 344 int BookmarkMenuDelegate::GetMaxWidthForMenu(MenuItemView* menu) { |
| 347 return kMaxMenuWidth; | 345 return kMaxMenuWidth; |
| 348 } | 346 } |
| 349 | 347 |
| 348 void BookmarkMenuDelegate::WillShowMenu(MenuItemView* menu) { | |
| 349 const int command = menu->GetCommand(); | |
| 350 if (menu_id_to_node_map_.find(command) == menu_id_to_node_map_.end()) | |
|
Peter Kasting
2015/03/30 21:35:24
Nit: Shorter and slightly more efficient:
auto
sky
2015/03/31 15:17:39
Done.
| |
| 351 return; | |
| 352 const bookmarks::BookmarkNode* node = menu_id_to_node_map_[command]; | |
| 353 if (node->child_count() && menu->GetSubmenu()->GetMenuItemCount() == 0) | |
| 354 BuildMenu(node, 0, menu); | |
| 355 } | |
| 356 | |
| 350 void BookmarkMenuDelegate::BookmarkModelChanged() { | 357 void BookmarkMenuDelegate::BookmarkModelChanged() { |
| 351 } | 358 } |
| 352 | 359 |
| 353 void BookmarkMenuDelegate::BookmarkNodeFaviconChanged( | 360 void BookmarkMenuDelegate::BookmarkNodeFaviconChanged( |
| 354 BookmarkModel* model, | 361 BookmarkModel* model, |
| 355 const BookmarkNode* node) { | 362 const BookmarkNode* node) { |
| 356 NodeToMenuMap::iterator menu_pair = node_to_menu_map_.find(node); | 363 NodeToMenuMap::iterator menu_pair = node_to_menu_map_.find(node); |
| 357 if (menu_pair == node_to_menu_map_.end()) | 364 if (menu_pair == node_to_menu_map_.end()) |
| 358 return; // We're not showing a menu item for the node. | 365 return; // We're not showing a menu item for the node. |
| 359 | 366 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 423 GetBookmarkModel()->AddObserver(this); | 430 GetBookmarkModel()->AddObserver(this); |
| 424 DCHECK(is_mutating_model_); | 431 DCHECK(is_mutating_model_); |
| 425 is_mutating_model_ = false; | 432 is_mutating_model_ = false; |
| 426 } | 433 } |
| 427 | 434 |
| 428 MenuItemView* BookmarkMenuDelegate::CreateMenu(const BookmarkNode* parent, | 435 MenuItemView* BookmarkMenuDelegate::CreateMenu(const BookmarkNode* parent, |
| 429 int start_child_index, | 436 int start_child_index, |
| 430 ShowOptions show_options) { | 437 ShowOptions show_options) { |
| 431 MenuItemView* menu = new MenuItemView(real_delegate_); | 438 MenuItemView* menu = new MenuItemView(real_delegate_); |
| 432 menu->SetCommand(next_menu_id_++); | 439 menu->SetCommand(next_menu_id_++); |
| 433 menu_id_to_node_map_[menu->GetCommand()] = parent; | 440 AddMenuToMaps(menu, parent); |
| 434 menu->set_has_icons(true); | 441 menu->set_has_icons(true); |
| 435 bool show_permanent = show_options == SHOW_PERMANENT_FOLDERS; | 442 bool show_permanent = show_options == SHOW_PERMANENT_FOLDERS; |
| 436 if (show_permanent && parent == GetBookmarkModel()->bookmark_bar_node()) { | 443 if (show_permanent && parent == GetBookmarkModel()->bookmark_bar_node()) { |
| 437 BuildMenuForManagedNode(menu, &next_menu_id_); | 444 BuildMenuForManagedNode(menu); |
| 438 BuildMenuForSupervisedNode(menu, &next_menu_id_); | 445 BuildMenuForSupervisedNode(menu); |
| 439 } | 446 } |
| 440 BuildMenu(parent, start_child_index, menu, &next_menu_id_); | 447 BuildMenu(parent, start_child_index, menu); |
| 441 if (show_permanent) | 448 if (show_permanent) |
| 442 BuildMenusForPermanentNodes(menu, &next_menu_id_); | 449 BuildMenusForPermanentNodes(menu); |
| 443 return menu; | 450 return menu; |
| 444 } | 451 } |
| 445 | 452 |
| 446 void BookmarkMenuDelegate::BuildMenusForPermanentNodes( | 453 void BookmarkMenuDelegate::BuildMenusForPermanentNodes( |
| 447 views::MenuItemView* menu, | 454 views::MenuItemView* menu) { |
| 448 int* next_menu_id) { | |
| 449 BookmarkModel* model = GetBookmarkModel(); | 455 BookmarkModel* model = GetBookmarkModel(); |
| 450 bool added_separator = false; | 456 bool added_separator = false; |
| 451 BuildMenuForPermanentNode(model->other_node(), IDR_BOOKMARK_BAR_FOLDER, menu, | 457 BuildMenuForPermanentNode(model->other_node(), IDR_BOOKMARK_BAR_FOLDER, menu, |
| 452 next_menu_id, &added_separator); | 458 &added_separator); |
| 453 BuildMenuForPermanentNode(model->mobile_node(), IDR_BOOKMARK_BAR_FOLDER, menu, | 459 BuildMenuForPermanentNode(model->mobile_node(), IDR_BOOKMARK_BAR_FOLDER, menu, |
| 454 next_menu_id, &added_separator); | 460 &added_separator); |
| 455 } | 461 } |
| 456 | 462 |
| 457 void BookmarkMenuDelegate::BuildMenuForPermanentNode( | 463 void BookmarkMenuDelegate::BuildMenuForPermanentNode( |
| 458 const BookmarkNode* node, | 464 const BookmarkNode* node, |
| 459 int icon_resource_id, | 465 int icon_resource_id, |
| 460 MenuItemView* menu, | 466 MenuItemView* menu, |
| 461 int* next_menu_id, | |
| 462 bool* added_separator) { | 467 bool* added_separator) { |
| 463 if (!node->IsVisible() || node->GetTotalNodeCount() == 1) | 468 if (!node->IsVisible() || node->GetTotalNodeCount() == 1) |
| 464 return; // No children, don't create a menu. | 469 return; // No children, don't create a menu. |
| 465 | 470 |
| 466 int id = *next_menu_id; | |
| 467 // Don't create the submenu if its menu ID will be outside the range allowed. | |
| 468 if (IsOutsideMenuIdRange(id)) | |
| 469 return; | |
| 470 (*next_menu_id)++; | |
| 471 | |
| 472 if (!*added_separator) { | 471 if (!*added_separator) { |
| 473 *added_separator = true; | 472 *added_separator = true; |
| 474 menu->AppendSeparator(); | 473 menu->AppendSeparator(); |
| 475 } | 474 } |
| 476 | 475 |
| 477 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); | 476 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); |
| 478 gfx::ImageSkia* folder_icon = rb->GetImageSkiaNamed(icon_resource_id); | 477 gfx::ImageSkia* folder_icon = rb->GetImageSkiaNamed(icon_resource_id); |
| 479 MenuItemView* submenu = menu->AppendSubMenuWithIcon( | 478 AddMenuToMaps(menu->AppendSubMenuWithIcon(next_menu_id_++, node->GetTitle(), |
| 480 id, node->GetTitle(), *folder_icon); | 479 *folder_icon), |
| 481 BuildMenu(node, 0, submenu, next_menu_id); | 480 node); |
|
Peter Kasting
2015/03/30 21:35:24
Just so I'm sure, the removal of this BuildMenu()
sky
2015/03/31 15:17:39
That's right.
| |
| 482 menu_id_to_node_map_[id] = node; | |
| 483 } | 481 } |
| 484 | 482 |
| 485 void BookmarkMenuDelegate::BuildMenuForManagedNode(MenuItemView* menu, | 483 void BookmarkMenuDelegate::BuildMenuForManagedNode(MenuItemView* menu) { |
| 486 int* next_menu_id) { | |
| 487 // Don't add a separator for this menu. | 484 // Don't add a separator for this menu. |
| 488 bool added_separator = true; | 485 bool added_separator = true; |
| 489 const BookmarkNode* node = GetChromeBookmarkClient()->managed_node(); | 486 const BookmarkNode* node = GetChromeBookmarkClient()->managed_node(); |
| 490 BuildMenuForPermanentNode(node, IDR_BOOKMARK_BAR_FOLDER_MANAGED, menu, | 487 BuildMenuForPermanentNode(node, IDR_BOOKMARK_BAR_FOLDER_MANAGED, menu, |
| 491 next_menu_id, &added_separator); | 488 &added_separator); |
| 492 } | 489 } |
| 493 | 490 |
| 494 void BookmarkMenuDelegate::BuildMenuForSupervisedNode(MenuItemView* menu, | 491 void BookmarkMenuDelegate::BuildMenuForSupervisedNode(MenuItemView* menu) { |
| 495 int* next_menu_id) { | |
| 496 // Don't add a separator for this menu. | 492 // Don't add a separator for this menu. |
| 497 bool added_separator = true; | 493 bool added_separator = true; |
| 498 const BookmarkNode* node = GetChromeBookmarkClient()->supervised_node(); | 494 const BookmarkNode* node = GetChromeBookmarkClient()->supervised_node(); |
| 499 BuildMenuForPermanentNode(node, IDR_BOOKMARK_BAR_FOLDER_SUPERVISED, menu, | 495 BuildMenuForPermanentNode(node, IDR_BOOKMARK_BAR_FOLDER_SUPERVISED, menu, |
| 500 next_menu_id, &added_separator); | 496 &added_separator); |
| 501 } | 497 } |
| 502 | 498 |
| 503 void BookmarkMenuDelegate::BuildMenu(const BookmarkNode* parent, | 499 void BookmarkMenuDelegate::BuildMenu(const BookmarkNode* parent, |
| 504 int start_child_index, | 500 int start_child_index, |
| 505 MenuItemView* menu, | 501 MenuItemView* menu) { |
| 506 int* next_menu_id) { | |
| 507 node_to_menu_map_[parent] = menu; | |
| 508 DCHECK(parent->empty() || start_child_index < parent->child_count()); | 502 DCHECK(parent->empty() || start_child_index < parent->child_count()); |
| 509 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); | 503 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); |
| 510 for (int i = start_child_index; i < parent->child_count(); ++i) { | 504 for (int i = start_child_index; i < parent->child_count(); ++i) { |
| 511 const BookmarkNode* node = parent->GetChild(i); | 505 const BookmarkNode* node = parent->GetChild(i); |
|
Peter Kasting
2015/03/30 21:35:24
Nit: Shorter, avoids violating the "don't handle D
sky
2015/03/31 15:17:39
The calls to add the menus are slightly different,
| |
| 512 const int id = *next_menu_id; | 506 const int id = next_menu_id_++; |
| 513 // Don't create the item if its menu ID will be outside the range allowed. | |
| 514 if (IsOutsideMenuIdRange(id)) | |
| 515 break; | |
| 516 | 507 |
| 517 (*next_menu_id)++; | 508 MenuItemView* child_menu_item = nullptr; |
| 518 | |
| 519 menu_id_to_node_map_[id] = node; | |
| 520 if (node->is_url()) { | 509 if (node->is_url()) { |
| 521 const gfx::Image& image = GetBookmarkModel()->GetFavicon(node); | 510 const gfx::Image& image = GetBookmarkModel()->GetFavicon(node); |
| 522 const gfx::ImageSkia* icon = image.IsEmpty() ? | 511 const gfx::ImageSkia* icon = image.IsEmpty() ? |
| 523 rb->GetImageSkiaNamed(IDR_DEFAULT_FAVICON) : image.ToImageSkia(); | 512 rb->GetImageSkiaNamed(IDR_DEFAULT_FAVICON) : image.ToImageSkia(); |
| 524 node_to_menu_map_[node] = | 513 child_menu_item = |
| 525 menu->AppendMenuItemWithIcon(id, node->GetTitle(), *icon); | 514 menu->AppendMenuItemWithIcon(id, node->GetTitle(), *icon); |
| 526 } else if (node->is_folder()) { | 515 } else if (node->is_folder()) { |
| 527 gfx::ImageSkia* folder_icon = | 516 gfx::ImageSkia* folder_icon = |
| 528 rb->GetImageSkiaNamed(IDR_BOOKMARK_BAR_FOLDER); | 517 rb->GetImageSkiaNamed(IDR_BOOKMARK_BAR_FOLDER); |
| 529 MenuItemView* submenu = menu->AppendSubMenuWithIcon( | 518 child_menu_item = |
| 530 id, node->GetTitle(), *folder_icon); | 519 menu->AppendSubMenuWithIcon(id, node->GetTitle(), *folder_icon); |
| 531 BuildMenu(node, 0, submenu, next_menu_id); | |
| 532 } else { | 520 } else { |
| 533 NOTREACHED(); | 521 NOTREACHED(); |
| 534 } | 522 } |
| 523 AddMenuToMaps(child_menu_item, node); | |
| 535 } | 524 } |
| 536 } | 525 } |
| 537 | 526 |
| 538 bool BookmarkMenuDelegate::IsOutsideMenuIdRange(int menu_id) const { | 527 void BookmarkMenuDelegate::AddMenuToMaps(MenuItemView* menu, |
| 539 return menu_id < min_menu_id_ || menu_id > max_menu_id_; | 528 const BookmarkNode* node) { |
| 529 menu_id_to_node_map_[menu->GetCommand()] = node; | |
| 530 node_to_menu_map_[node] = menu; | |
| 540 } | 531 } |
| OLD | NEW |