Commit c5174283 authored by sky@chromium.org's avatar sky@chromium.org

Refactors code for showing bookmark menus so that it can be used by

both the bookmark bar and wrench menu and wires bookmarks into the
wrench menu.

BUG=81263
TEST=thoroughly test bookmarks in the wrench menu to make sure there
     aren't any crashes/weird behavior.
Review URL: http://codereview.chromium.org/7054020

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@86175 0039d316-1c4b-4281-b951-d872f2087c98
parent 907dfc6e
......@@ -154,7 +154,7 @@ ToolsMenuModel::ToolsMenuModel(ui::SimpleMenuModel::Delegate* delegate,
ToolsMenuModel::~ToolsMenuModel() {}
void ToolsMenuModel::Build(Browser* browser) {
#if !defined(OS_MACOSX)
#if !defined(OS_MACOSX) && !defined(TOOLKIT_VIEWS)
AddCheckItemWithStringId(IDC_SHOW_BOOKMARK_BAR, IDS_SHOW_BOOKMARK_BAR);
AddSeparator();
#endif
......@@ -462,7 +462,7 @@ void WrenchMenuModel::Build() {
AddSeparator();
#if defined(OS_MACOSX)
#if defined(OS_MACOSX) || defined(TOOLKIT_VIEWS)
bookmark_sub_menu_model_.reset(new BookmarkSubMenuModel(this, browser_));
AddSubMenuWithStringId(IDC_BOOKMARKS_MENU, IDS_BOOKMARKS_MENU,
bookmark_sub_menu_model_.get());
......
......@@ -1074,8 +1074,9 @@ void BookmarkBarView::RunMenu(views::View* view, const gfx::Point& pt) {
node = model_->GetBookmarkBarNode()->GetChild(button_index);
}
bookmark_menu_ = new BookmarkMenuController(browser_, profile_,
page_navigator_, GetWindow()->GetNativeWindow(), node, start_index);
bookmark_menu_ = new BookmarkMenuController(
profile_, page_navigator_, GetWindow()->GetNativeWindow(), node,
start_index);
bookmark_menu_->set_observer(this);
bookmark_menu_->RunMenuAt(this, false);
}
......@@ -1386,8 +1387,9 @@ void BookmarkBarView::ShowDropFolderForNode(const BookmarkNode* node) {
start_index = GetFirstHiddenNodeIndex();
drop_info_->is_menu_showing = true;
bookmark_drop_menu_ = new BookmarkMenuController(browser_, profile_,
page_navigator_, GetWindow()->GetNativeWindow(), node, start_index);
bookmark_drop_menu_ = new BookmarkMenuController(
profile_, page_navigator_, GetWindow()->GetNativeWindow(), node,
start_index);
bookmark_drop_menu_->set_observer(this);
bookmark_drop_menu_->RunMenuAt(this, true);
}
......
......@@ -6,19 +6,17 @@
#define CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_MENU_CONTROLLER_VIEWS_H_
#pragma once
#include <map>
#include <set>
#include "chrome/browser/bookmarks/base_bookmark_model_observer.h"
#include "chrome/browser/bookmarks/bookmark_node_data.h"
#include "chrome/browser/ui/views/bookmarks/bookmark_context_menu.h"
#include "ui/gfx/native_widget_types.h"
#include "views/controls/menu/menu_delegate.h"
#include "views/controls/menu/menu_item_view.h"
class BookmarkBarView;
class BookmarkMenuDelegate;
class BookmarkNode;
class Browser;
class PageNavigator;
class Profile;
......@@ -39,8 +37,7 @@ class MenuButton;
// BookmarkMenuController deletes itself as necessary, although the menu can
// be explicitly hidden by way of the Cancel method.
class BookmarkMenuController : public BaseBookmarkModelObserver,
public views::MenuDelegate,
public BookmarkContextMenuObserver {
public views::MenuDelegate {
public:
// The observer is notified prior to the menu being deleted.
class Observer {
......@@ -52,9 +49,8 @@ class BookmarkMenuController : public BaseBookmarkModelObserver,
};
// Creates a BookmarkMenuController showing the children of |node| starting
// at index |start_child_index|.
BookmarkMenuController(Browser* browser,
Profile* profile,
// at |start_child_index|.
BookmarkMenuController(Profile* profile,
PageNavigator* page_navigator,
gfx::NativeWindow parent,
const BookmarkNode* node,
......@@ -74,12 +70,10 @@ class BookmarkMenuController : public BaseBookmarkModelObserver,
const BookmarkNode* node() const { return node_; }
// Returns the menu.
views::MenuItemView* menu() const { return menu_; }
views::MenuItemView* menu() const;
// Returns the context menu, or NULL if the context menu isn't showing.
views::MenuItemView* context_menu() const {
return context_menu_.get() ? context_menu_->menu() : NULL;
}
views::MenuItemView* context_menu() const;
void set_observer(Observer* observer) { observer_ = observer; }
......@@ -120,70 +114,19 @@ class BookmarkMenuController : public BaseBookmarkModelObserver,
// BookmarkModelObserver methods.
virtual void BookmarkModelChanged();
virtual void BookmarkNodeFaviconLoaded(BookmarkModel* model,
const BookmarkNode* node);
// BookmarkContextMenu::Observer methods.
virtual void WillRemoveBookmarks(
const std::vector<const BookmarkNode*>& bookmarks);
virtual void DidRemoveBookmarks();
private:
typedef std::map<const BookmarkNode*, int> NodeToMenuIDMap;
// BookmarkMenuController deletes itself as necessary.
virtual ~BookmarkMenuController();
// Creates a menu and adds it to node_to_menu_id_map_. This uses
// BuildMenu to recursively populate the menu.
views::MenuItemView* CreateMenu(const BookmarkNode* parent,
int start_child_index);
// Creates an entry in menu for each child node of |parent| starting at
// |start_child_index|.
void BuildMenu(const BookmarkNode* parent,
int start_child_index,
views::MenuItemView* menu,
int* next_menu_id);
// Returns the menu whose id is |id|.
views::MenuItemView* GetMenuByID(int id);
// Does the work of processing WillRemoveBookmarks. On exit the set of removed
// menus is added to |removed_menus|. It's up to the caller to delete the
// the menus added to |removed_menus|.
void WillRemoveBookmarksImpl(
const std::vector<const BookmarkNode*>& bookmarks,
std::set<views::MenuItemView*>* removed_menus);
Browser* browser_;
Profile* profile_;
PageNavigator* page_navigator_;
// Parent of menus.
gfx::NativeWindow parent_;
scoped_ptr<BookmarkMenuDelegate> menu_delegate_;
// The node we're showing the contents of.
const BookmarkNode* node_;
// Maps from menu id to BookmarkNode.
std::map<int, const BookmarkNode*> menu_id_to_node_map_;
// Mapping from node to menu id. This only contains entries for nodes of type
// URL.
NodeToMenuIDMap node_to_menu_id_map_;
// Current menu.
views::MenuItemView* menu_;
// Data for the drop.
BookmarkNodeData drop_data_;
// Used when a context menu is shown.
scoped_ptr<BookmarkContextMenu> context_menu_;
// The observer, may be null.
Observer* observer_;
......@@ -194,12 +137,6 @@ class BookmarkMenuController : public BaseBookmarkModelObserver,
// for a folder on the bookmark bar and not for drop.
BookmarkBarView* bookmark_bar_;
typedef std::map<const BookmarkNode*, views::MenuItemView*> NodeToMenuMap;
NodeToMenuMap node_to_menu_map_;
// ID of the next menu item.
int next_menu_id_;
DISALLOW_COPY_AND_ASSIGN(BookmarkMenuController);
};
......
This diff is collapsed.
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_MENU_DELEGATE_H_
#define CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_MENU_DELEGATE_H_
#pragma once
#include <map>
#include <set>
#include "chrome/browser/bookmarks/base_bookmark_model_observer.h"
#include "chrome/browser/bookmarks/bookmark_node_data.h"
#include "chrome/browser/ui/views/bookmarks/bookmark_context_menu.h"
#include "ui/gfx/native_widget_types.h"
#include "views/controls/menu/menu_delegate.h"
class BookmarkNode;
class PageNavigator;
class Profile;
namespace ui {
class OSExchangeData;
}
namespace views {
class MenuItemView;
}
// BookmarkMenuDelegate acts as the (informal) views::MenuDelegate for showing
// bookmarks in a MenuItemView. BookmarkMenuDelegate informally implements
// MenuDelegate as its assumed another class is going to forward the appropriate
// methods to this class. Doing so allows this class to be used for both menus
// on the bookmark bar and the bookmarks in the wrench menu.
class BookmarkMenuDelegate : public BaseBookmarkModelObserver,
public BookmarkContextMenuObserver {
public:
enum ShowOptions {
// Indicates a menu should be added containing the 'other' bookmarks folder
// and all its contents. This only makes sense when showing the contents
// of the bookmark folder.
SHOW_OTHER_FOLDER,
// Don't show the 'other' bookmarks folder.
HIDE_OTHER_FOLDER
};
BookmarkMenuDelegate(Profile* profile,
PageNavigator* navigator,
gfx::NativeWindow parent,
int first_menu_id);
virtual ~BookmarkMenuDelegate();
// Creates the menus from the model.
void Init(views::MenuDelegate* real_delegate,
views::MenuItemView* parent,
const BookmarkNode* node,
int start_child_index,
ShowOptions show_options);
// Returns the id given to the next menu.
int next_menu_id() const { return next_menu_id_; }
// Makes the menu for |node| the active menu. |start_index| is the index of
// the first child of |node| to show in the menu.
void SetActiveMenu(const BookmarkNode* node, int start_index);
// Returns the menu.
views::MenuItemView* menu() const { return menu_; }
// Returns the context menu, or NULL if the context menu isn't showing.
views::MenuItemView* context_menu() const {
return context_menu_.get() ? context_menu_->menu() : NULL;
}
Profile* profile() { return profile_; }
gfx::NativeWindow parent() { return parent_; }
// Returns true if we're in the process of mutating the model. This happens
// when the user deletes menu items using the context menu.
bool is_mutating_model() const { return is_mutating_model_; }
// MenuDelegate like methods (see class description for details).
std::wstring GetTooltipText(int id, const gfx::Point& p);
bool IsTriggerableEvent(views::MenuItemView* menu,
const views::MouseEvent& e);
void ExecuteCommand(int id, int mouse_event_flags);
bool GetDropFormats(
views::MenuItemView* menu,
int* formats,
std::set<ui::OSExchangeData::CustomFormat>* custom_formats);
bool AreDropTypesRequired(views::MenuItemView* menu);
bool CanDrop(views::MenuItemView* menu, const ui::OSExchangeData& data);
int GetDropOperation(views::MenuItemView* item,
const views::DropTargetEvent& event,
views::MenuDelegate::DropPosition* position);
int OnPerformDrop(views::MenuItemView* menu,
views::MenuDelegate::DropPosition position,
const views::DropTargetEvent& event);
bool ShowContextMenu(views::MenuItemView* source,
int id,
const gfx::Point& p,
bool is_mouse_gesture);
bool CanDrag(views::MenuItemView* menu);
void WriteDragData(views::MenuItemView* sender, ui::OSExchangeData* data);
int GetDragOperations(views::MenuItemView* sender);
int GetMaxWidthForMenu(views::MenuItemView* menu);
// BookmarkModelObserver methods.
virtual void BookmarkModelChanged();
virtual void BookmarkNodeFaviconLoaded(BookmarkModel* model,
const BookmarkNode* node);
// BookmarkContextMenu::Observer methods.
virtual void WillRemoveBookmarks(
const std::vector<const BookmarkNode*>& bookmarks);
virtual void DidRemoveBookmarks();
private:
typedef std::map<const BookmarkNode*, int> NodeToMenuIDMap;
typedef std::map<const BookmarkNode*, views::MenuItemView*> NodeToMenuMap;
// Creates a menu and adds it to node_to_menu_id_map_. This uses
// BuildMenu to recursively populate the menu.
views::MenuItemView* CreateMenu(const BookmarkNode* parent,
int start_child_index,
ShowOptions show_options);
// Builds the menu for the other bookmarks folder. This is added as the last
// item to menu_.
void BuildOtherFolderMenu(views::MenuItemView* menu, int* next_menu_id);
// Creates an entry in menu for each child node of |parent| starting at
// |start_child_index|.
void BuildMenu(const BookmarkNode* parent,
int start_child_index,
views::MenuItemView* menu,
int* next_menu_id);
// Returns the menu whose id is |id|.
views::MenuItemView* GetMenuByID(int id);
// Does the work of processing WillRemoveBookmarks. On exit the set of removed
// menus is added to |removed_menus|. It's up to the caller to delete the
// the menus added to |removed_menus|.
void WillRemoveBookmarksImpl(
const std::vector<const BookmarkNode*>& bookmarks,
std::set<views::MenuItemView*>* removed_menus);
Profile* profile_;
PageNavigator* page_navigator_;
// Parent of menus.
gfx::NativeWindow parent_;
// Maps from menu id to BookmarkNode.
std::map<int, const BookmarkNode*> menu_id_to_node_map_;
// Mapping from node to menu id. This only contains entries for nodes of type
// URL.
NodeToMenuIDMap node_to_menu_id_map_;
// Current menu.
views::MenuItemView* menu_;
// Data for the drop.
BookmarkNodeData drop_data_;
// Used when a context menu is shown.
scoped_ptr<BookmarkContextMenu> context_menu_;
// Is the menu being shown for a drop?
bool for_drop_;
NodeToMenuMap node_to_menu_map_;
// ID of the next menu item.
int next_menu_id_;
views::MenuDelegate* real_delegate_;
// Is the model being changed?
bool is_mutating_model_;
DISALLOW_COPY_AND_ASSIGN(BookmarkMenuDelegate);
};
#endif // CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_MENU_DELEGATE_H_
......@@ -9,8 +9,11 @@
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/browser/user_metrics.h"
#include "content/common/notification_observer.h"
......@@ -564,7 +567,9 @@ class WrenchMenu::ZoomView : public WrenchMenuView,
WrenchMenu::WrenchMenu(Browser* browser)
: browser_(browser),
selected_menu_model_(NULL),
selected_index_(0) {
selected_index_(0),
bookmark_menu_(NULL),
first_bookmark_command_id_(0) {
}
void WrenchMenu::Init(ui::MenuModel* model) {
......@@ -574,6 +579,7 @@ void WrenchMenu::Init(ui::MenuModel* model) {
// so we get the taller menu style.
int next_id = 1;
PopulateMenu(root_.get(), model, &next_id);
first_bookmark_command_id_ = next_id + 1;
}
void WrenchMenu::RunMenu(views::MenuButton* host) {
......@@ -589,16 +595,114 @@ void WrenchMenu::RunMenu(views::MenuButton* host) {
root_->RunMenuAt(host->GetWindow()->GetNativeWindow(), host, bounds,
base::i18n::IsRTL() ? MenuItemView::TOPLEFT : MenuItemView::TOPRIGHT,
true);
if (bookmark_menu_delegate_.get()) {
BookmarkModel* model = browser_->profile()->GetBookmarkModel();
if (model)
model->RemoveObserver(this);
}
if (selected_menu_model_)
selected_menu_model_->ActivatedAt(selected_index_);
}
std::wstring WrenchMenu::GetTooltipText(int id,
const gfx::Point& p) {
return is_bookmark_command(id) ?
bookmark_menu_delegate_->GetTooltipText(id, p) : std::wstring();
}
bool WrenchMenu::IsTriggerableEvent(views::MenuItemView* menu,
const views::MouseEvent& e) {
return is_bookmark_command(menu->GetCommand()) ?
bookmark_menu_delegate_->IsTriggerableEvent(menu, e) :
MenuDelegate::IsTriggerableEvent(menu, e);
}
bool WrenchMenu::GetDropFormats(
MenuItemView* menu,
int* formats,
std::set<ui::OSExchangeData::CustomFormat>* custom_formats) {
CreateBookmarkMenu();
return bookmark_menu_delegate_.get() &&
bookmark_menu_delegate_->GetDropFormats(menu, formats, custom_formats);
}
bool WrenchMenu::AreDropTypesRequired(MenuItemView* menu) {
CreateBookmarkMenu();
return bookmark_menu_delegate_.get() &&
bookmark_menu_delegate_->AreDropTypesRequired(menu);
}
bool WrenchMenu::CanDrop(MenuItemView* menu,
const ui::OSExchangeData& data) {
CreateBookmarkMenu();
return bookmark_menu_delegate_.get() &&
bookmark_menu_delegate_->CanDrop(menu, data);
}
int WrenchMenu::GetDropOperation(
MenuItemView* item,
const views::DropTargetEvent& event,
DropPosition* position) {
return is_bookmark_command(item->GetCommand()) ?
bookmark_menu_delegate_->GetDropOperation(item, event, position) :
ui::DragDropTypes::DRAG_NONE;
}
int WrenchMenu::OnPerformDrop(MenuItemView* menu,
DropPosition position,
const views::DropTargetEvent& event) {
if (!is_bookmark_command(menu->GetCommand()))
return ui::DragDropTypes::DRAG_NONE;
int result = bookmark_menu_delegate_->OnPerformDrop(menu, position, event);
return result;
}
bool WrenchMenu::ShowContextMenu(MenuItemView* source,
int id,
const gfx::Point& p,
bool is_mouse_gesture) {
return is_bookmark_command(id) ?
bookmark_menu_delegate_->ShowContextMenu(source, id, p,
is_mouse_gesture) :
false;
}
bool WrenchMenu::CanDrag(MenuItemView* menu) {
return is_bookmark_command(menu->GetCommand()) ?
bookmark_menu_delegate_->CanDrag(menu) : false;
}
void WrenchMenu::WriteDragData(MenuItemView* sender,
ui::OSExchangeData* data) {
DCHECK(is_bookmark_command(sender->GetCommand()));
return bookmark_menu_delegate_->WriteDragData(sender, data);
}
int WrenchMenu::GetDragOperations(MenuItemView* sender) {
return is_bookmark_command(sender->GetCommand()) ?
bookmark_menu_delegate_->GetDragOperations(sender) :
MenuDelegate::GetDragOperations(sender);
}
int WrenchMenu::GetMaxWidthForMenu(MenuItemView* menu) {
return is_bookmark_command(menu->GetCommand()) ?
bookmark_menu_delegate_->GetMaxWidthForMenu(menu) :
MenuDelegate::GetMaxWidthForMenu(menu);
}
bool WrenchMenu::IsItemChecked(int id) const {
if (!is_bookmark_command(id))
return false;
const Entry& entry = id_to_entry_.find(id)->second;
return entry.first->IsItemCheckedAt(entry.second);
}
bool WrenchMenu::IsCommandEnabled(int id) const {
if (is_bookmark_command(id))
return true;
if (id == 0)
return false; // The root item.
......@@ -611,7 +715,13 @@ bool WrenchMenu::IsCommandEnabled(int id) const {
entry.first->IsEnabledAt(entry.second);
}
void WrenchMenu::ExecuteCommand(int id) {
void WrenchMenu::ExecuteCommand(int id, int mouse_event_flags) {
if (is_bookmark_command(id)) {
bookmark_menu_delegate_->ExecuteCommand(id, mouse_event_flags);
return;
}
// Not a bookmark
const Entry& entry = id_to_entry_.find(id)->second;
int command_id = entry.first->GetCommandIdAt(entry.second);
......@@ -626,6 +736,9 @@ void WrenchMenu::ExecuteCommand(int id) {
}
bool WrenchMenu::GetAccelerator(int id, views::Accelerator* accelerator) {
if (is_bookmark_command(id))
return false;
const Entry& entry = id_to_entry_.find(id)->second;
int command_id = entry.first->GetCommandIdAt(entry.second);
if (command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS) {
......@@ -642,6 +755,15 @@ bool WrenchMenu::GetAccelerator(int id, views::Accelerator* accelerator) {
return true;
}
void WrenchMenu::WillShowMenu(MenuItemView* menu) {
if (menu == bookmark_menu_)
CreateBookmarkMenu();
}
void WrenchMenu::BookmarkModelChanged() {
root_->Cancel();
}
WrenchMenu::~WrenchMenu() {
}
......@@ -658,23 +780,35 @@ void WrenchMenu::PopulateMenu(MenuItemView* parent,
if (model->GetTypeAt(index) == MenuModel::TYPE_SUBMENU)
PopulateMenu(item, model->GetSubmenuModelAt(index), next_id);
if (model->GetCommandIdAt(index) == IDC_CUT) {
DCHECK_EQ(MenuModel::TYPE_COMMAND, model->GetTypeAt(index));
DCHECK_LT(i + 2, max);
DCHECK_EQ(IDC_COPY, model->GetCommandIdAt(index + 1));
DCHECK_EQ(IDC_PASTE, model->GetCommandIdAt(index + 2));
item->SetTitle(UTF16ToWide(l10n_util::GetStringUTF16(IDS_EDIT2)));
item->AddChildView(
new CutCopyPasteView(this, model, index, index + 1, index + 2));
i += 2;
} else if (model->GetCommandIdAt(index) == IDC_ZOOM_MINUS) {
DCHECK_EQ(MenuModel::TYPE_COMMAND, model->GetTypeAt(index));
DCHECK_EQ(IDC_ZOOM_PLUS, model->GetCommandIdAt(index + 1));
DCHECK_EQ(IDC_FULLSCREEN, model->GetCommandIdAt(index + 2));
item->SetTitle(UTF16ToWide(l10n_util::GetStringUTF16(IDS_ZOOM_MENU2)));
item->AddChildView(
new ZoomView(this, model, index, index + 1, index + 2));
i += 2;
switch (model->GetCommandIdAt(index)) {
case IDC_CUT:
DCHECK_EQ(MenuModel::TYPE_COMMAND, model->GetTypeAt(index));
DCHECK_LT(i + 2, max);
DCHECK_EQ(IDC_COPY, model->GetCommandIdAt(index + 1));
DCHECK_EQ(IDC_PASTE, model->GetCommandIdAt(index + 2));
item->SetTitle(UTF16ToWide(l10n_util::GetStringUTF16(IDS_EDIT2)));
item->AddChildView(
new CutCopyPasteView(this, model, index, index + 1, index + 2));
i += 2;
break;
case IDC_ZOOM_MINUS:
DCHECK_EQ(MenuModel::TYPE_COMMAND, model->GetTypeAt(index));
DCHECK_EQ(IDC_ZOOM_PLUS, model->GetCommandIdAt(index + 1));
DCHECK_EQ(IDC_FULLSCREEN, model->GetCommandIdAt(index + 2));
item->SetTitle(UTF16ToWide(l10n_util::GetStringUTF16(IDS_ZOOM_MENU2)));
item->AddChildView(
new ZoomView(this, model, index, index + 1, index + 2));
i += 2;
break;
case IDC_BOOKMARKS_MENU:
DCHECK(!bookmark_menu_);
bookmark_menu_ = item;
break;
default:
break;
}
}
}
......@@ -708,3 +842,22 @@ void WrenchMenu::CancelAndEvaluate(MenuModel* model, int index) {
selected_index_ = index;
root_->Cancel();
}
void WrenchMenu::CreateBookmarkMenu() {
if (bookmark_menu_delegate_.get())
return; // Already created the menu.
BookmarkModel* model = browser_->profile()->GetBookmarkModel();
if (!model->IsLoaded())
return;
model->AddObserver(this);
bookmark_menu_delegate_.reset(
new BookmarkMenuDelegate(browser_->profile(),
NULL,
browser_->window()->GetNativeHandle(),
first_bookmark_command_id_));
bookmark_menu_delegate_->Init(
this, bookmark_menu_, model->GetBookmarkBarNode(), 0,
BookmarkMenuDelegate::SHOW_OTHER_FOLDER);
}
......@@ -11,9 +11,11 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/bookmarks/base_bookmark_model_observer.h"
#include "ui/base/models/menu_model.h"
#include "views/controls/menu/menu_delegate.h"
class BookmarkMenuDelegate;
class Browser;
namespace views {
......@@ -24,7 +26,8 @@ class View;
// WrenchMenu adapts the WrenchMenuModel to view's menu related classes.
class WrenchMenu : public base::RefCounted<WrenchMenu>,
public views::MenuDelegate {
public views::MenuDelegate,
public BaseBookmarkModelObserver {
public:
explicit WrenchMenu(Browser* browser);
......@@ -34,10 +37,39 @@ class WrenchMenu : public base::RefCounted<WrenchMenu>,
void RunMenu(views::MenuButton* host);
// MenuDelegate overrides:
virtual bool IsItemChecked(int id) const;
virtual bool IsCommandEnabled(int id) const;
virtual void ExecuteCommand(int id);
virtual bool GetAccelerator(int id, views::Accelerator* accelerator);
virtual std::wstring GetTooltipText(int id, const gfx::Point& p) OVERRIDE;
virtual bool IsTriggerableEvent(views::MenuItemView* menu,
const views::MouseEvent& e) OVERRIDE;
virtual bool GetDropFormats(
views::MenuItemView* menu,
int* formats,
std::set<ui::OSExchangeData::CustomFormat>* custom_formats) OVERRIDE;
virtual bool AreDropTypesRequired(views::MenuItemView* menu) OVERRIDE;
virtual bool CanDrop(views::MenuItemView* menu,
const ui::OSExchangeData& data) OVERRIDE;
virtual int GetDropOperation(views::MenuItemView* item,
const views::DropTargetEvent& event,
DropPosition* position) OVERRIDE;
virtual int OnPerformDrop(views::MenuItemView* menu,
DropPosition position,
const views::DropTargetEvent& event) OVERRIDE;
virtual bool ShowContextMenu(views::MenuItemView* source,
int id,
const gfx::Point& p,
bool is_mouse_gesture) OVERRIDE;
virtual bool CanDrag(views::MenuItemView* menu) OVERRIDE;
virtual void WriteDragData(views::MenuItemView* sender,
ui::OSExchangeData* data) OVERRIDE;
virtual int GetDragOperations(views::MenuItemView* sender) OVERRIDE;
virtual int GetMaxWidthForMenu(views::MenuItemView* menu) OVERRIDE;
virtual bool IsItemChecked(int id) const OVERRIDE;
virtual bool IsCommandEnabled(int id) const OVERRIDE;
virtual void ExecuteCommand(int id, int mouse_event_flags) OVERRIDE;
virtual bool GetAccelerator(int id, views::Accelerator* accelerator) OVERRIDE;
virtual void WillShowMenu(views::MenuItemView* menu) OVERRIDE;
// BaseBookmarkModelObserver overrides:
virtual void BookmarkModelChanged() OVERRIDE;
private:
friend class base::RefCounted<WrenchMenu>;
......@@ -69,6 +101,15 @@ class WrenchMenu : public base::RefCounted<WrenchMenu>,
// activates the menu item in |model| at |index|.
void CancelAndEvaluate(ui::MenuModel* model, int index);
// Creates the bookmark menu if necessary. Does nothing if already created or
// the bookmark model isn't loaded.
void CreateBookmarkMenu();
// Returns true if |id| identifies a bookmark menu item.
bool is_bookmark_command(int id) const {
return bookmark_menu_delegate_.get() && id >= first_bookmark_command_id_;
}
// The views menu.
scoped_ptr<views::MenuItemView> root_;
......@@ -86,6 +127,15 @@ class WrenchMenu : public base::RefCounted<WrenchMenu>,
ui::MenuModel* selected_menu_model_;
int selected_index_;
// Used for managing the bookmark menu items.
scoped_ptr<BookmarkMenuDelegate> bookmark_menu_delegate_;
// Menu corresponding to IDC_BOOKMARKS_MENU.
views::MenuItemView* bookmark_menu_;
// ID to use for the items representing bookmarks in the bookmark menu.
int first_bookmark_command_id_;
DISALLOW_COPY_AND_ASSIGN(WrenchMenu);
};
......
......@@ -2915,6 +2915,8 @@
'browser/ui/views/bookmarks/bookmark_editor_view.h',
'browser/ui/views/bookmarks/bookmark_menu_controller_views.cc',
'browser/ui/views/bookmarks/bookmark_menu_controller_views.h',
'browser/ui/views/bookmarks/bookmark_menu_delegate.cc',
'browser/ui/views/bookmarks/bookmark_menu_delegate.h',
'browser/ui/views/browser_actions_container.cc',
'browser/ui/views/browser_actions_container.h',
'browser/ui/views/browser_bubble.cc',
......@@ -4004,6 +4006,8 @@
['include', '^browser/ui/views/bookmarks/bookmark_context_menu_controller_views.cc'],
['include', '^browser/ui/views/bookmarks/bookmark_context_menu_controller_views.h'],
['include', '^browser/ui/views/bookmarks/bookmark_menu_controller_views.cc'],
['include', '^browser/ui/views/bookmarks/bookmark_menu_delegate.cc'],
['include', '^browser/ui/views/bookmarks/bookmark_menu_delegate.h'],
['include', '^browser/ui/views/browser_actions_container.cc'],
['include', '^browser/ui/views/browser_actions_container.h'],
['include', '^browser/ui/views/browser_bubble.cc'],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment