Index: chrome/browser/ui/views/bookmarks/bookmark_menu_controller_views.cc |
=================================================================== |
--- chrome/browser/ui/views/bookmarks/bookmark_menu_controller_views.cc (revision 86142) |
+++ chrome/browser/ui/views/bookmarks/bookmark_menu_controller_views.cc (working copy) |
@@ -11,8 +11,8 @@ |
#include "chrome/browser/bookmarks/bookmark_utils.h" |
#include "chrome/browser/prefs/pref_service.h" |
#include "chrome/browser/profiles/profile.h" |
-#include "chrome/browser/ui/browser.h" |
#include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" |
+#include "chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h" |
#include "chrome/browser/ui/views/event_utils.h" |
#include "chrome/common/pref_names.h" |
#include "content/browser/tab_contents/page_navigator.h" |
@@ -27,27 +27,18 @@ |
using views::MenuItemView; |
-// Max width of a menu. There does not appear to be an OS value for this, yet |
-// both IE and FF restrict the max width of a menu. |
-static const int kMaxMenuWidth = 400; |
- |
-BookmarkMenuController::BookmarkMenuController(Browser* browser, |
- Profile* profile, |
+BookmarkMenuController::BookmarkMenuController(Profile* profile, |
PageNavigator* navigator, |
gfx::NativeWindow parent, |
const BookmarkNode* node, |
int start_child_index) |
- : browser_(browser), |
- profile_(profile), |
- page_navigator_(navigator), |
- parent_(parent), |
+ : menu_delegate_(new BookmarkMenuDelegate(profile, navigator, parent, 1)), |
node_(node), |
- menu_(NULL), |
observer_(NULL), |
for_drop_(false), |
- bookmark_bar_(NULL), |
- next_menu_id_(1) { |
- menu_ = CreateMenu(node, start_child_index); |
+ bookmark_bar_(NULL) { |
+ menu_delegate_->Init(this, NULL, node, start_child_index, |
+ BookmarkMenuDelegate::HIDE_OTHER_FOLDER); |
} |
void BookmarkMenuController::RunMenuAt(BookmarkBarView* bookmark_bar, |
@@ -72,134 +63,69 @@ |
gfx::Rect bounds(screen_loc.x(), screen_loc.y(), button->width(), |
button->height() - 1); |
for_drop_ = for_drop; |
- profile_->GetBookmarkModel()->AddObserver(this); |
- // The constructor creates the initial menu and that is all we should have |
- // at this point. |
- DCHECK(node_to_menu_map_.size() == 1); |
+ menu_delegate_->profile()->GetBookmarkModel()->AddObserver(this); |
if (for_drop) { |
- menu_->RunMenuForDropAt(parent_, bounds, position); |
+ menu()->RunMenuForDropAt(menu_delegate_->parent(), bounds, position); |
} else { |
- menu_->RunMenuAt(parent_, button, bounds, position, false); |
+ menu()->RunMenuAt(menu_delegate_->parent(), button, bounds, position, |
+ false); |
delete this; |
} |
} |
void BookmarkMenuController::Cancel() { |
- menu_->Cancel(); |
+ menu_delegate_->menu()->Cancel(); |
} |
-std::wstring BookmarkMenuController::GetTooltipText( |
- int id, const gfx::Point& screen_loc) { |
- DCHECK(menu_id_to_node_map_.find(id) != menu_id_to_node_map_.end()); |
+MenuItemView* BookmarkMenuController::menu() const { |
+ return menu_delegate_->menu(); |
+} |
- const BookmarkNode* node = menu_id_to_node_map_[id]; |
- if (node->type() == BookmarkNode::URL) |
- return BookmarkBarView::CreateToolTipForURLAndTitle( |
- screen_loc, node->GetURL(), UTF16ToWide(node->GetTitle()), profile_); |
- return std::wstring(); |
+MenuItemView* BookmarkMenuController::context_menu() const { |
+ return menu_delegate_->context_menu(); |
} |
-bool BookmarkMenuController::IsTriggerableEvent(MenuItemView* view, |
+std::wstring BookmarkMenuController::GetTooltipText(int id, |
+ const gfx::Point& p) { |
+ return menu_delegate_->GetTooltipText(id, p); |
+} |
+ |
+bool BookmarkMenuController::IsTriggerableEvent(views::MenuItemView* menu, |
const views::MouseEvent& e) { |
- return event_utils::IsPossibleDispositionEvent(e); |
+ return menu_delegate_->IsTriggerableEvent(menu, e); |
} |
void BookmarkMenuController::ExecuteCommand(int id, int mouse_event_flags) { |
- DCHECK(page_navigator_); |
- DCHECK(menu_id_to_node_map_.find(id) != menu_id_to_node_map_.end()); |
- |
- const BookmarkNode* node = menu_id_to_node_map_[id]; |
- std::vector<const BookmarkNode*> selection; |
- selection.push_back(node); |
- |
- WindowOpenDisposition initial_disposition = |
- event_utils::DispositionFromEventFlags(mouse_event_flags); |
- |
- bookmark_utils::OpenAll(parent_, profile_, page_navigator_, selection, |
- initial_disposition); |
+ menu_delegate_->ExecuteCommand(id, mouse_event_flags); |
} |
bool BookmarkMenuController::GetDropFormats( |
MenuItemView* menu, |
int* formats, |
std::set<ui::OSExchangeData::CustomFormat>* custom_formats) { |
- *formats = ui::OSExchangeData::URL; |
- custom_formats->insert(BookmarkNodeData::GetBookmarkCustomFormat()); |
- return true; |
+ return menu_delegate_->GetDropFormats(menu, formats, custom_formats); |
} |
bool BookmarkMenuController::AreDropTypesRequired(MenuItemView* menu) { |
- return true; |
+ return menu_delegate_->AreDropTypesRequired(menu); |
} |
bool BookmarkMenuController::CanDrop(MenuItemView* menu, |
const ui::OSExchangeData& data) { |
- // Only accept drops of 1 node, which is the case for all data dragged from |
- // bookmark bar and menus. |
- |
- if (!drop_data_.Read(data) || drop_data_.elements.size() != 1 || |
- !profile_->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled)) |
- return false; |
- |
- if (drop_data_.has_single_url()) |
- return true; |
- |
- const BookmarkNode* drag_node = drop_data_.GetFirstNode(profile_); |
- if (!drag_node) { |
- // Dragging a folder from another profile, always accept. |
- return true; |
- } |
- |
- // Drag originated from same profile and is not a URL. Only accept it if |
- // the dragged node is not a parent of the node menu represents. |
- const BookmarkNode* drop_node = menu_id_to_node_map_[menu->GetCommand()]; |
- DCHECK(drop_node); |
- while (drop_node && drop_node != drag_node) |
- drop_node = drop_node->parent(); |
- return (drop_node == NULL); |
+ return menu_delegate_->CanDrop(menu, data); |
} |
int BookmarkMenuController::GetDropOperation( |
MenuItemView* item, |
const views::DropTargetEvent& event, |
DropPosition* position) { |
- // Should only get here if we have drop data. |
- DCHECK(drop_data_.is_valid()); |
- |
- const BookmarkNode* node = menu_id_to_node_map_[item->GetCommand()]; |
- const BookmarkNode* drop_parent = node->parent(); |
- int index_to_drop_at = drop_parent->GetIndexOf(node); |
- if (*position == DROP_AFTER) { |
- index_to_drop_at++; |
- } else if (*position == DROP_ON) { |
- drop_parent = node; |
- index_to_drop_at = node->child_count(); |
- } |
- DCHECK(drop_parent); |
- return bookmark_utils::BookmarkDropOperation( |
- profile_, event, drop_data_, drop_parent, index_to_drop_at); |
+ return menu_delegate_->GetDropOperation(item, event, position); |
} |
int BookmarkMenuController::OnPerformDrop(MenuItemView* menu, |
DropPosition position, |
const views::DropTargetEvent& event) { |
- const BookmarkNode* drop_node = menu_id_to_node_map_[menu->GetCommand()]; |
- DCHECK(drop_node); |
- BookmarkModel* model = profile_->GetBookmarkModel(); |
- DCHECK(model); |
- const BookmarkNode* drop_parent = drop_node->parent(); |
- DCHECK(drop_parent); |
- int index_to_drop_at = drop_parent->GetIndexOf(drop_node); |
- if (position == DROP_AFTER) { |
- index_to_drop_at++; |
- } else if (position == DROP_ON) { |
- DCHECK(drop_node->is_folder()); |
- drop_parent = drop_node; |
- index_to_drop_at = drop_node->child_count(); |
- } |
- |
- int result = bookmark_utils::PerformBookmarkDrop( |
- profile_, drop_data_, drop_parent, index_to_drop_at); |
+ int result = menu_delegate_->OnPerformDrop(menu, position, event); |
if (for_drop_) |
delete this; |
return result; |
@@ -209,20 +135,7 @@ |
int id, |
const gfx::Point& p, |
bool is_mouse_gesture) { |
- DCHECK(menu_id_to_node_map_.find(id) != menu_id_to_node_map_.end()); |
- std::vector<const BookmarkNode*> nodes; |
- nodes.push_back(menu_id_to_node_map_[id]); |
- context_menu_.reset( |
- new BookmarkContextMenu( |
- parent_, |
- profile_, |
- page_navigator_, |
- nodes[0]->parent(), |
- nodes)); |
- context_menu_->set_observer(this); |
- context_menu_->RunMenuAt(p); |
- context_menu_.reset(NULL); |
- return true; |
+ return menu_delegate_->ShowContextMenu(source, id, p, is_mouse_gesture); |
} |
void BookmarkMenuController::DropMenuClosed(MenuItemView* menu) { |
@@ -230,22 +143,16 @@ |
} |
bool BookmarkMenuController::CanDrag(MenuItemView* menu) { |
- return true; |
+ return menu_delegate_->CanDrag(menu); |
} |
void BookmarkMenuController::WriteDragData(MenuItemView* sender, |
ui::OSExchangeData* data) { |
- DCHECK(sender && data); |
- |
- UserMetrics::RecordAction(UserMetricsAction("BookmarkBar_DragFromFolder")); |
- |
- BookmarkNodeData drag_data(menu_id_to_node_map_[sender->GetCommand()]); |
- drag_data.Write(profile_, data); |
+ return menu_delegate_->WriteDragData(sender, data); |
} |
int BookmarkMenuController::GetDragOperations(MenuItemView* sender) { |
- return bookmark_utils::BookmarkDragOperation(profile_, |
- menu_id_to_node_map_[sender->GetCommand()]); |
+ return menu_delegate_->GetDragOperations(sender); |
} |
views::MenuItemView* BookmarkMenuController::GetSiblingMenu( |
@@ -264,167 +171,25 @@ |
if (!node || !node->is_folder()) |
return NULL; |
- MenuItemView* alt_menu = node_to_menu_map_[node]; |
- if (!alt_menu) |
- alt_menu = CreateMenu(node, start_index); |
- |
- menu_ = alt_menu; |
- |
+ menu_delegate_->SetActiveMenu(node, start_index); |
*button = bookmark_bar_->GetMenuButtonForNode(node); |
bookmark_bar_->GetAnchorPositionAndStartIndexForButton( |
*button, anchor, &start_index); |
*has_mnemonics = false; |
- return alt_menu; |
+ return this->menu(); |
} |
int BookmarkMenuController::GetMaxWidthForMenu(MenuItemView* view) { |
- return kMaxMenuWidth; |
+ return menu_delegate_->GetMaxWidthForMenu(view); |
} |
void BookmarkMenuController::BookmarkModelChanged() { |
- menu_->Cancel(); |
+ if (!menu_delegate_->is_mutating_model()) |
+ menu()->Cancel(); |
} |
-void BookmarkMenuController::BookmarkNodeFaviconLoaded( |
- BookmarkModel* model, const BookmarkNode* node) { |
- NodeToMenuIDMap::iterator menu_pair = node_to_menu_id_map_.find(node); |
- if (menu_pair == node_to_menu_id_map_.end()) |
- return; // We're not showing a menu item for the node. |
- |
- // Iterate through the menus looking for the menu containing node. |
- for (NodeToMenuMap::iterator i = node_to_menu_map_.begin(); |
- i != node_to_menu_map_.end(); ++i) { |
- MenuItemView* menu_item = i->second->GetMenuItemByID(menu_pair->second); |
- if (menu_item) { |
- menu_item->SetIcon(model->GetFavicon(node)); |
- return; |
- } |
- } |
-} |
- |
-void BookmarkMenuController::WillRemoveBookmarks( |
- const std::vector<const BookmarkNode*>& bookmarks) { |
- std::set<MenuItemView*> removed_menus; |
- |
- WillRemoveBookmarksImpl(bookmarks, &removed_menus); |
- |
- STLDeleteElements(&removed_menus); |
-} |
- |
-void BookmarkMenuController::DidRemoveBookmarks() { |
- profile_->GetBookmarkModel()->AddObserver(this); |
-} |
- |
-MenuItemView* BookmarkMenuController::CreateMenu(const BookmarkNode* parent, |
- int start_child_index) { |
- MenuItemView* menu = new MenuItemView(this); |
- menu->SetCommand(next_menu_id_++); |
- menu_id_to_node_map_[menu->GetCommand()] = parent; |
- menu->set_has_icons(true); |
- BuildMenu(parent, start_child_index, menu, &next_menu_id_); |
- node_to_menu_map_[parent] = menu; |
- return menu; |
-} |
- |
-void BookmarkMenuController::BuildMenu(const BookmarkNode* parent, |
- int start_child_index, |
- MenuItemView* menu, |
- int* next_menu_id) { |
- DCHECK(!parent->child_count() || |
- start_child_index < parent->child_count()); |
- for (int i = start_child_index; i < parent->child_count(); ++i) { |
- const BookmarkNode* node = parent->GetChild(i); |
- int id = *next_menu_id; |
- |
- (*next_menu_id)++; |
- if (node->is_url()) { |
- SkBitmap icon = profile_->GetBookmarkModel()->GetFavicon(node); |
- if (icon.width() == 0) { |
- icon = *ResourceBundle::GetSharedInstance(). |
- GetBitmapNamed(IDR_DEFAULT_FAVICON); |
- } |
- menu->AppendMenuItemWithIcon(id, UTF16ToWide(node->GetTitle()), icon); |
- node_to_menu_id_map_[node] = id; |
- } else if (node->is_folder()) { |
- SkBitmap* folder_icon = ResourceBundle::GetSharedInstance(). |
- GetBitmapNamed(IDR_BOOKMARK_BAR_FOLDER); |
- MenuItemView* submenu = menu->AppendSubMenuWithIcon(id, |
- UTF16ToWide(node->GetTitle()), *folder_icon); |
- node_to_menu_id_map_[node] = id; |
- BuildMenu(node, 0, submenu, next_menu_id); |
- } else { |
- NOTREACHED(); |
- } |
- menu_id_to_node_map_[id] = node; |
- } |
-} |
- |
BookmarkMenuController::~BookmarkMenuController() { |
- profile_->GetBookmarkModel()->RemoveObserver(this); |
+ menu_delegate_->profile()->GetBookmarkModel()->RemoveObserver(this); |
if (observer_) |
observer_->BookmarkMenuDeleted(this); |
- STLDeleteValues(&node_to_menu_map_); |
} |
- |
-MenuItemView* BookmarkMenuController::GetMenuByID(int id) { |
- for (NodeToMenuMap::const_iterator i = node_to_menu_map_.begin(); |
- i != node_to_menu_map_.end(); ++i) { |
- MenuItemView* menu = i->second->GetMenuItemByID(id); |
- if (menu) |
- return menu; |
- } |
- return NULL; |
-} |
- |
-void BookmarkMenuController::WillRemoveBookmarksImpl( |
- const std::vector<const BookmarkNode*>& bookmarks, |
- std::set<views::MenuItemView*>* removed_menus) { |
- // Remove the observer so that when the remove happens we don't prematurely |
- // cancel the menu. |
- profile_->GetBookmarkModel()->RemoveObserver(this); |
- |
- // Remove the menu items. |
- std::set<MenuItemView*> changed_parent_menus; |
- for (std::vector<const BookmarkNode*>::const_iterator i = bookmarks.begin(); |
- i != bookmarks.end(); ++i) { |
- NodeToMenuIDMap::iterator node_to_menu = node_to_menu_id_map_.find(*i); |
- if (node_to_menu != node_to_menu_id_map_.end()) { |
- MenuItemView* menu = GetMenuByID(node_to_menu->second); |
- DCHECK(menu); // If there an entry in node_to_menu_id_map_, there should |
- // be a menu. |
- removed_menus->insert(menu); |
- changed_parent_menus.insert(menu->GetParentMenuItem()); |
- menu->parent()->RemoveChildView(menu); |
- node_to_menu_id_map_.erase(node_to_menu); |
- } |
- } |
- |
- // All the bookmarks in |bookmarks| should have the same parent. It's possible |
- // to support different parents, but this would need to prune any nodes whose |
- // parent has been removed. As all nodes currently have the same parent, there |
- // is the DCHECK. |
- DCHECK(changed_parent_menus.size() <= 1); |
- |
- for (std::set<MenuItemView*>::const_iterator i = changed_parent_menus.begin(); |
- i != changed_parent_menus.end(); ++i) { |
- (*i)->ChildrenChanged(); |
- } |
- |
- // Remove any descendants of the removed nodes in node_to_menu_id_map_. |
- for (NodeToMenuIDMap::iterator i = node_to_menu_id_map_.begin(); |
- i != node_to_menu_id_map_.end(); ) { |
- bool ancestor_removed = false; |
- for (std::vector<const BookmarkNode*>::const_iterator j = bookmarks.begin(); |
- j != bookmarks.end(); ++j) { |
- if (i->first->HasAncestor(*j)) { |
- ancestor_removed = true; |
- break; |
- } |
- } |
- if (ancestor_removed) { |
- node_to_menu_id_map_.erase(i++); |
- } else { |
- ++i; |
- } |
- } |
-} |