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

Side by Side Diff: chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.cc

Issue 1005873012: Makes bookmark menu lazily create menus and removes limits (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: review feedback Created 5 years, 8 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) 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
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
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
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 auto iter = menu_id_to_node_map_.find(menu->GetCommand());
350 if ((iter != menu_id_to_node_map_.end()) && iter->second->child_count() &&
351 !menu->GetSubmenu()->GetMenuItemCount())
352 BuildMenu(iter->second, 0, menu);
353 }
354
350 void BookmarkMenuDelegate::BookmarkModelChanged() { 355 void BookmarkMenuDelegate::BookmarkModelChanged() {
351 } 356 }
352 357
353 void BookmarkMenuDelegate::BookmarkNodeFaviconChanged( 358 void BookmarkMenuDelegate::BookmarkNodeFaviconChanged(
354 BookmarkModel* model, 359 BookmarkModel* model,
355 const BookmarkNode* node) { 360 const BookmarkNode* node) {
356 NodeToMenuMap::iterator menu_pair = node_to_menu_map_.find(node); 361 NodeToMenuMap::iterator menu_pair = node_to_menu_map_.find(node);
357 if (menu_pair == node_to_menu_map_.end()) 362 if (menu_pair == node_to_menu_map_.end())
358 return; // We're not showing a menu item for the node. 363 return; // We're not showing a menu item for the node.
359 364
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 GetBookmarkModel()->AddObserver(this); 428 GetBookmarkModel()->AddObserver(this);
424 DCHECK(is_mutating_model_); 429 DCHECK(is_mutating_model_);
425 is_mutating_model_ = false; 430 is_mutating_model_ = false;
426 } 431 }
427 432
428 MenuItemView* BookmarkMenuDelegate::CreateMenu(const BookmarkNode* parent, 433 MenuItemView* BookmarkMenuDelegate::CreateMenu(const BookmarkNode* parent,
429 int start_child_index, 434 int start_child_index,
430 ShowOptions show_options) { 435 ShowOptions show_options) {
431 MenuItemView* menu = new MenuItemView(real_delegate_); 436 MenuItemView* menu = new MenuItemView(real_delegate_);
432 menu->SetCommand(next_menu_id_++); 437 menu->SetCommand(next_menu_id_++);
433 menu_id_to_node_map_[menu->GetCommand()] = parent; 438 AddMenuToMaps(menu, parent);
434 menu->set_has_icons(true); 439 menu->set_has_icons(true);
435 bool show_permanent = show_options == SHOW_PERMANENT_FOLDERS; 440 bool show_permanent = show_options == SHOW_PERMANENT_FOLDERS;
436 if (show_permanent && parent == GetBookmarkModel()->bookmark_bar_node()) { 441 if (show_permanent && parent == GetBookmarkModel()->bookmark_bar_node()) {
437 BuildMenuForManagedNode(menu, &next_menu_id_); 442 BuildMenuForManagedNode(menu);
438 BuildMenuForSupervisedNode(menu, &next_menu_id_); 443 BuildMenuForSupervisedNode(menu);
439 } 444 }
440 BuildMenu(parent, start_child_index, menu, &next_menu_id_); 445 BuildMenu(parent, start_child_index, menu);
441 if (show_permanent) 446 if (show_permanent)
442 BuildMenusForPermanentNodes(menu, &next_menu_id_); 447 BuildMenusForPermanentNodes(menu);
443 return menu; 448 return menu;
444 } 449 }
445 450
446 void BookmarkMenuDelegate::BuildMenusForPermanentNodes( 451 void BookmarkMenuDelegate::BuildMenusForPermanentNodes(
447 views::MenuItemView* menu, 452 views::MenuItemView* menu) {
448 int* next_menu_id) {
449 BookmarkModel* model = GetBookmarkModel(); 453 BookmarkModel* model = GetBookmarkModel();
450 bool added_separator = false; 454 bool added_separator = false;
451 BuildMenuForPermanentNode(model->other_node(), IDR_BOOKMARK_BAR_FOLDER, menu, 455 BuildMenuForPermanentNode(model->other_node(), IDR_BOOKMARK_BAR_FOLDER, menu,
452 next_menu_id, &added_separator); 456 &added_separator);
453 BuildMenuForPermanentNode(model->mobile_node(), IDR_BOOKMARK_BAR_FOLDER, menu, 457 BuildMenuForPermanentNode(model->mobile_node(), IDR_BOOKMARK_BAR_FOLDER, menu,
454 next_menu_id, &added_separator); 458 &added_separator);
455 } 459 }
456 460
457 void BookmarkMenuDelegate::BuildMenuForPermanentNode( 461 void BookmarkMenuDelegate::BuildMenuForPermanentNode(
458 const BookmarkNode* node, 462 const BookmarkNode* node,
459 int icon_resource_id, 463 int icon_resource_id,
460 MenuItemView* menu, 464 MenuItemView* menu,
461 int* next_menu_id,
462 bool* added_separator) { 465 bool* added_separator) {
463 if (!node->IsVisible() || node->GetTotalNodeCount() == 1) 466 if (!node->IsVisible() || node->GetTotalNodeCount() == 1)
464 return; // No children, don't create a menu. 467 return; // No children, don't create a menu.
465 468
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) { 469 if (!*added_separator) {
473 *added_separator = true; 470 *added_separator = true;
474 menu->AppendSeparator(); 471 menu->AppendSeparator();
475 } 472 }
476 473
477 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); 474 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
478 gfx::ImageSkia* folder_icon = rb->GetImageSkiaNamed(icon_resource_id); 475 gfx::ImageSkia* folder_icon = rb->GetImageSkiaNamed(icon_resource_id);
479 MenuItemView* submenu = menu->AppendSubMenuWithIcon( 476 AddMenuToMaps(menu->AppendSubMenuWithIcon(next_menu_id_++, node->GetTitle(),
480 id, node->GetTitle(), *folder_icon); 477 *folder_icon),
481 BuildMenu(node, 0, submenu, next_menu_id); 478 node);
482 menu_id_to_node_map_[id] = node;
483 } 479 }
484 480
485 void BookmarkMenuDelegate::BuildMenuForManagedNode(MenuItemView* menu, 481 void BookmarkMenuDelegate::BuildMenuForManagedNode(MenuItemView* menu) {
486 int* next_menu_id) {
487 // Don't add a separator for this menu. 482 // Don't add a separator for this menu.
488 bool added_separator = true; 483 bool added_separator = true;
489 const BookmarkNode* node = GetChromeBookmarkClient()->managed_node(); 484 const BookmarkNode* node = GetChromeBookmarkClient()->managed_node();
490 BuildMenuForPermanentNode(node, IDR_BOOKMARK_BAR_FOLDER_MANAGED, menu, 485 BuildMenuForPermanentNode(node, IDR_BOOKMARK_BAR_FOLDER_MANAGED, menu,
491 next_menu_id, &added_separator); 486 &added_separator);
492 } 487 }
493 488
494 void BookmarkMenuDelegate::BuildMenuForSupervisedNode(MenuItemView* menu, 489 void BookmarkMenuDelegate::BuildMenuForSupervisedNode(MenuItemView* menu) {
495 int* next_menu_id) {
496 // Don't add a separator for this menu. 490 // Don't add a separator for this menu.
497 bool added_separator = true; 491 bool added_separator = true;
498 const BookmarkNode* node = GetChromeBookmarkClient()->supervised_node(); 492 const BookmarkNode* node = GetChromeBookmarkClient()->supervised_node();
499 BuildMenuForPermanentNode(node, IDR_BOOKMARK_BAR_FOLDER_SUPERVISED, menu, 493 BuildMenuForPermanentNode(node, IDR_BOOKMARK_BAR_FOLDER_SUPERVISED, menu,
500 next_menu_id, &added_separator); 494 &added_separator);
501 } 495 }
502 496
503 void BookmarkMenuDelegate::BuildMenu(const BookmarkNode* parent, 497 void BookmarkMenuDelegate::BuildMenu(const BookmarkNode* parent,
504 int start_child_index, 498 int start_child_index,
505 MenuItemView* menu, 499 MenuItemView* menu) {
506 int* next_menu_id) {
507 node_to_menu_map_[parent] = menu;
508 DCHECK(parent->empty() || start_child_index < parent->child_count()); 500 DCHECK(parent->empty() || start_child_index < parent->child_count());
509 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); 501 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
510 for (int i = start_child_index; i < parent->child_count(); ++i) { 502 for (int i = start_child_index; i < parent->child_count(); ++i) {
511 const BookmarkNode* node = parent->GetChild(i); 503 const BookmarkNode* node = parent->GetChild(i);
512 const int id = *next_menu_id; 504 const int id = next_menu_id_++;
513 // Don't create the item if its menu ID will be outside the range allowed. 505 MenuItemView* child_menu_item;
514 if (IsOutsideMenuIdRange(id))
515 break;
516
517 (*next_menu_id)++;
518
519 menu_id_to_node_map_[id] = node;
520 if (node->is_url()) { 506 if (node->is_url()) {
521 const gfx::Image& image = GetBookmarkModel()->GetFavicon(node); 507 const gfx::Image& image = GetBookmarkModel()->GetFavicon(node);
522 const gfx::ImageSkia* icon = image.IsEmpty() ? 508 const gfx::ImageSkia* icon = image.IsEmpty() ?
523 rb->GetImageSkiaNamed(IDR_DEFAULT_FAVICON) : image.ToImageSkia(); 509 rb->GetImageSkiaNamed(IDR_DEFAULT_FAVICON) : image.ToImageSkia();
524 node_to_menu_map_[node] = 510 child_menu_item =
525 menu->AppendMenuItemWithIcon(id, node->GetTitle(), *icon); 511 menu->AppendMenuItemWithIcon(id, node->GetTitle(), *icon);
526 } else if (node->is_folder()) { 512 } else {
513 DCHECK(node->is_folder());
527 gfx::ImageSkia* folder_icon = 514 gfx::ImageSkia* folder_icon =
528 rb->GetImageSkiaNamed(IDR_BOOKMARK_BAR_FOLDER); 515 rb->GetImageSkiaNamed(IDR_BOOKMARK_BAR_FOLDER);
529 MenuItemView* submenu = menu->AppendSubMenuWithIcon( 516 child_menu_item =
530 id, node->GetTitle(), *folder_icon); 517 menu->AppendSubMenuWithIcon(id, node->GetTitle(), *folder_icon);
531 BuildMenu(node, 0, submenu, next_menu_id);
532 } else {
533 NOTREACHED();
534 } 518 }
519 AddMenuToMaps(child_menu_item, node);
535 } 520 }
536 } 521 }
537 522
538 bool BookmarkMenuDelegate::IsOutsideMenuIdRange(int menu_id) const { 523 void BookmarkMenuDelegate::AddMenuToMaps(MenuItemView* menu,
539 return menu_id < min_menu_id_ || menu_id > max_menu_id_; 524 const BookmarkNode* node) {
525 menu_id_to_node_map_[menu->GetCommand()] = node;
526 node_to_menu_map_[node] = menu;
540 } 527 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698