OLD | NEW |
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 #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/stl_util.h" | |
8 #include "base/utf_string_conversions.h" | 7 #include "base/utf_string_conversions.h" |
9 #include "chrome/browser/bookmarks/bookmark_model.h" | 8 #include "chrome/browser/bookmarks/bookmark_model.h" |
10 #include "chrome/browser/bookmarks/bookmark_node_data.h" | 9 #include "chrome/browser/bookmarks/bookmark_node_data.h" |
11 #include "chrome/browser/bookmarks/bookmark_utils.h" | 10 #include "chrome/browser/bookmarks/bookmark_utils.h" |
12 #include "chrome/browser/prefs/pref_service.h" | 11 #include "chrome/browser/prefs/pref_service.h" |
13 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
14 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" | 13 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" |
15 #include "chrome/browser/ui/views/event_utils.h" | 14 #include "chrome/browser/ui/views/event_utils.h" |
16 #include "chrome/common/pref_names.h" | 15 #include "chrome/common/pref_names.h" |
17 #include "content/browser/tab_contents/page_navigator.h" | 16 #include "content/browser/tab_contents/page_navigator.h" |
(...skipping 26 matching lines...) Expand all Loading... |
44 menu_(NULL), | 43 menu_(NULL), |
45 for_drop_(false), | 44 for_drop_(false), |
46 parent_menu_item_(NULL), | 45 parent_menu_item_(NULL), |
47 next_menu_id_(first_menu_id), | 46 next_menu_id_(first_menu_id), |
48 real_delegate_(NULL), | 47 real_delegate_(NULL), |
49 is_mutating_model_(false) { | 48 is_mutating_model_(false) { |
50 } | 49 } |
51 | 50 |
52 BookmarkMenuDelegate::~BookmarkMenuDelegate() { | 51 BookmarkMenuDelegate::~BookmarkMenuDelegate() { |
53 profile_->GetBookmarkModel()->RemoveObserver(this); | 52 profile_->GetBookmarkModel()->RemoveObserver(this); |
54 STLDeleteValues(&node_to_menu_map_); | |
55 } | 53 } |
56 | 54 |
57 void BookmarkMenuDelegate::Init(views::MenuDelegate* real_delegate, | 55 void BookmarkMenuDelegate::Init(views::MenuDelegate* real_delegate, |
58 MenuItemView* parent, | 56 MenuItemView* parent, |
59 const BookmarkNode* node, | 57 const BookmarkNode* node, |
60 int start_child_index, | 58 int start_child_index, |
61 ShowOptions show_options) { | 59 ShowOptions show_options) { |
62 profile_->GetBookmarkModel()->AddObserver(this); | 60 profile_->GetBookmarkModel()->AddObserver(this); |
63 real_delegate_ = real_delegate; | 61 real_delegate_ = real_delegate; |
64 if (parent) { | 62 if (parent) { |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 menu_pair->second); | 304 menu_pair->second); |
307 if (menu_item) | 305 if (menu_item) |
308 menu_item->SetIcon(model->GetFavicon(node)); | 306 menu_item->SetIcon(model->GetFavicon(node)); |
309 } | 307 } |
310 } | 308 } |
311 | 309 |
312 void BookmarkMenuDelegate::WillRemoveBookmarks( | 310 void BookmarkMenuDelegate::WillRemoveBookmarks( |
313 const std::vector<const BookmarkNode*>& bookmarks) { | 311 const std::vector<const BookmarkNode*>& bookmarks) { |
314 DCHECK(!is_mutating_model_); | 312 DCHECK(!is_mutating_model_); |
315 is_mutating_model_ = true; | 313 is_mutating_model_ = true; |
316 std::set<MenuItemView*> removed_menus; | 314 |
317 WillRemoveBookmarksImpl(bookmarks, &removed_menus); | 315 // Remove the observer so that when the remove happens we don't prematurely |
318 STLDeleteElements(&removed_menus); | 316 // cancel the menu. The observer ias added back in DidRemoveBookmarks. |
| 317 profile_->GetBookmarkModel()->RemoveObserver(this); |
| 318 |
| 319 // Remove the menu items. |
| 320 std::set<MenuItemView*> changed_parent_menus; |
| 321 for (std::vector<const BookmarkNode*>::const_iterator i = bookmarks.begin(); |
| 322 i != bookmarks.end(); ++i) { |
| 323 NodeToMenuIDMap::iterator node_to_menu = node_to_menu_id_map_.find(*i); |
| 324 if (node_to_menu != node_to_menu_id_map_.end()) { |
| 325 MenuItemView* menu = GetMenuByID(node_to_menu->second); |
| 326 DCHECK(menu); // If there an entry in node_to_menu_id_map_, there should |
| 327 // be a menu. |
| 328 DCHECK(menu->GetParentMenuItem()); |
| 329 changed_parent_menus.insert(menu->GetParentMenuItem()); |
| 330 menu->GetParentMenuItem()->RemoveMenuItemAt( |
| 331 menu->parent()->GetIndexOf(menu)); |
| 332 node_to_menu_id_map_.erase(node_to_menu); |
| 333 } |
| 334 } |
| 335 |
| 336 // All the bookmarks in |bookmarks| should have the same parent. It's possible |
| 337 // to support different parents, but this would need to prune any nodes whose |
| 338 // parent has been removed. As all nodes currently have the same parent, there |
| 339 // is the DCHECK. |
| 340 DCHECK(changed_parent_menus.size() <= 1); |
| 341 |
| 342 for (std::set<MenuItemView*>::const_iterator i = changed_parent_menus.begin(); |
| 343 i != changed_parent_menus.end(); ++i) { |
| 344 (*i)->ChildrenChanged(); |
| 345 } |
| 346 |
| 347 // Remove any descendants of the removed nodes in node_to_menu_id_map_. |
| 348 for (NodeToMenuIDMap::iterator i = node_to_menu_id_map_.begin(); |
| 349 i != node_to_menu_id_map_.end(); ) { |
| 350 bool ancestor_removed = false; |
| 351 for (std::vector<const BookmarkNode*>::const_iterator j = bookmarks.begin(); |
| 352 j != bookmarks.end(); ++j) { |
| 353 if (i->first->HasAncestor(*j)) { |
| 354 ancestor_removed = true; |
| 355 break; |
| 356 } |
| 357 } |
| 358 if (ancestor_removed) { |
| 359 node_to_menu_id_map_.erase(i++); |
| 360 } else { |
| 361 ++i; |
| 362 } |
| 363 } |
319 } | 364 } |
320 | 365 |
321 void BookmarkMenuDelegate::DidRemoveBookmarks() { | 366 void BookmarkMenuDelegate::DidRemoveBookmarks() { |
322 // Balances remove in WillRemoveBookmarksImpl. | 367 // Balances remove in WillRemoveBookmarksImpl. |
323 profile_->GetBookmarkModel()->AddObserver(this); | 368 profile_->GetBookmarkModel()->AddObserver(this); |
324 DCHECK(is_mutating_model_); | 369 DCHECK(is_mutating_model_); |
325 is_mutating_model_ = false; | 370 is_mutating_model_ = false; |
326 } | 371 } |
327 | 372 |
328 MenuItemView* BookmarkMenuDelegate::CreateMenu(const BookmarkNode* parent, | 373 MenuItemView* BookmarkMenuDelegate::CreateMenu(const BookmarkNode* parent, |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 MenuItemView* BookmarkMenuDelegate::GetMenuByID(int id) { | 435 MenuItemView* BookmarkMenuDelegate::GetMenuByID(int id) { |
391 for (NodeToMenuMap::const_iterator i = node_to_menu_map_.begin(); | 436 for (NodeToMenuMap::const_iterator i = node_to_menu_map_.begin(); |
392 i != node_to_menu_map_.end(); ++i) { | 437 i != node_to_menu_map_.end(); ++i) { |
393 MenuItemView* menu = i->second->GetMenuItemByID(id); | 438 MenuItemView* menu = i->second->GetMenuItemByID(id); |
394 if (menu) | 439 if (menu) |
395 return menu; | 440 return menu; |
396 } | 441 } |
397 | 442 |
398 return parent_menu_item_ ? parent_menu_item_->GetMenuItemByID(id) : NULL; | 443 return parent_menu_item_ ? parent_menu_item_->GetMenuItemByID(id) : NULL; |
399 } | 444 } |
400 | |
401 void BookmarkMenuDelegate::WillRemoveBookmarksImpl( | |
402 const std::vector<const BookmarkNode*>& bookmarks, | |
403 std::set<views::MenuItemView*>* removed_menus) { | |
404 // Remove the observer so that when the remove happens we don't prematurely | |
405 // cancel the menu. The observer ias added back in DidRemoveBookmarks. | |
406 profile_->GetBookmarkModel()->RemoveObserver(this); | |
407 | |
408 // Remove the menu items. | |
409 std::set<MenuItemView*> changed_parent_menus; | |
410 for (std::vector<const BookmarkNode*>::const_iterator i = bookmarks.begin(); | |
411 i != bookmarks.end(); ++i) { | |
412 NodeToMenuIDMap::iterator node_to_menu = node_to_menu_id_map_.find(*i); | |
413 if (node_to_menu != node_to_menu_id_map_.end()) { | |
414 MenuItemView* menu = GetMenuByID(node_to_menu->second); | |
415 DCHECK(menu); // If there an entry in node_to_menu_id_map_, there should | |
416 // be a menu. | |
417 removed_menus->insert(menu); | |
418 changed_parent_menus.insert(menu->GetParentMenuItem()); | |
419 menu->parent()->RemoveChildView(menu); | |
420 node_to_menu_id_map_.erase(node_to_menu); | |
421 } | |
422 } | |
423 | |
424 // All the bookmarks in |bookmarks| should have the same parent. It's possible | |
425 // to support different parents, but this would need to prune any nodes whose | |
426 // parent has been removed. As all nodes currently have the same parent, there | |
427 // is the DCHECK. | |
428 DCHECK(changed_parent_menus.size() <= 1); | |
429 | |
430 for (std::set<MenuItemView*>::const_iterator i = changed_parent_menus.begin(); | |
431 i != changed_parent_menus.end(); ++i) { | |
432 (*i)->ChildrenChanged(); | |
433 } | |
434 | |
435 // Remove any descendants of the removed nodes in node_to_menu_id_map_. | |
436 for (NodeToMenuIDMap::iterator i = node_to_menu_id_map_.begin(); | |
437 i != node_to_menu_id_map_.end(); ) { | |
438 bool ancestor_removed = false; | |
439 for (std::vector<const BookmarkNode*>::const_iterator j = bookmarks.begin(); | |
440 j != bookmarks.end(); ++j) { | |
441 if (i->first->HasAncestor(*j)) { | |
442 ancestor_removed = true; | |
443 break; | |
444 } | |
445 } | |
446 if (ancestor_removed) { | |
447 node_to_menu_id_map_.erase(i++); | |
448 } else { | |
449 ++i; | |
450 } | |
451 } | |
452 } | |
OLD | NEW |