summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_win.cc111
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_win.h22
-rw-r--r--chrome/browser/autocomplete/search_provider.cc6
-rw-r--r--chrome/browser/external_tab_container.cc5
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_external_win.cc3
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_external_win.h1
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_win.cc145
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_win.h46
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_win.cc11
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_win.h5
-rw-r--r--chrome/browser/views/bookmark_bar_view.h2
-rw-r--r--chrome/browser/views/bookmark_editor_view.cc41
-rw-r--r--chrome/browser/views/bookmark_editor_view.h19
-rw-r--r--chrome/browser/views/bookmark_table_view.h1
-rw-r--r--chrome/browser/views/frame/browser_view.cc15
-rw-r--r--chrome/browser/views/tabs/tab_renderer.h1
-rw-r--r--chrome/browser/views/tabs/tab_strip.h1
-rw-r--r--chrome/browser/views/toolbar_view.cc47
-rw-r--r--chrome/browser/views/toolbar_view.h4
-rw-r--r--views/controls/menu/menu_2.cc4
-rw-r--r--views/controls/menu/menu_2.h4
-rw-r--r--views/controls/menu/native_menu_win.cc7
-rw-r--r--views/controls/textfield/native_textfield_win.cc67
-rw-r--r--views/controls/textfield/native_textfield_win.h22
24 files changed, 342 insertions, 248 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc
index 7aac332..0bc4f6c 100644
--- a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc
@@ -41,6 +41,7 @@
#include "skia/ext/skia_utils_win.h"
#include "views/drag_utils.h"
#include "views/focus/focus_util_win.h"
+#include "views/widget/widget.h"
#pragma comment(lib, "oleacc.lib") // Needed for accessibility support.
@@ -468,33 +469,6 @@ AutocompleteEditViewWin::AutocompleteEditViewWin(
cf.crTextColor = GetSysColor(COLOR_GRAYTEXT);
SetDefaultCharFormat(cf);
- // Set up context menu.
- context_menu_.reset(views::Menu::Create(this, views::Menu::TOPLEFT, m_hWnd));
- if (popup_window_mode_) {
- context_menu_->AppendMenuItemWithLabel(IDS_COPY,
- l10n_util::GetString(IDS_COPY));
- } else {
- context_menu_->AppendMenuItemWithLabel(IDS_UNDO,
- l10n_util::GetString(IDS_UNDO));
- context_menu_->AppendSeparator();
- context_menu_->AppendMenuItemWithLabel(IDS_CUT,
- l10n_util::GetString(IDS_CUT));
- context_menu_->AppendMenuItemWithLabel(IDS_COPY,
- l10n_util::GetString(IDS_COPY));
- context_menu_->AppendMenuItemWithLabel(IDS_PASTE,
- l10n_util::GetString(IDS_PASTE));
- // GetContextualLabel() will override this next label with the
- // IDS_PASTE_AND_SEARCH label as needed.
- context_menu_->AppendMenuItemWithLabel(
- IDS_PASTE_AND_GO, l10n_util::GetString(IDS_PASTE_AND_GO));
- context_menu_->AppendSeparator();
- context_menu_->AppendMenuItemWithLabel(
- IDS_SELECT_ALL, l10n_util::GetString(IDS_SELECT_ALL));
- context_menu_->AppendSeparator();
- context_menu_->AppendMenuItemWithLabel(
- IDS_EDIT_SEARCH_ENGINES, l10n_util::GetString(IDS_EDIT_SEARCH_ENGINES));
- }
-
// By default RichEdit has a drop target. Revoke it so that we can install our
// own. Revoke takes care of deleting the existing one.
RevokeDragDrop(m_hWnd);
@@ -954,12 +928,16 @@ void AutocompleteEditViewWin::HandleExternalMsg(UINT msg,
SendMessage(msg, flags, MAKELPARAM(client_point.x, client_point.y));
}
-bool AutocompleteEditViewWin::IsCommandEnabled(int id) const {
- switch (id) {
+bool AutocompleteEditViewWin::IsCommandIdChecked(int command_id) const {
+ return false;
+}
+
+bool AutocompleteEditViewWin::IsCommandIdEnabled(int command_id) const {
+ switch (command_id) {
case IDS_UNDO: return !!CanUndo();
- case IDS_CUT: return !!CanCut();
- case IDS_COPY: return !!CanCopy();
- case IDS_PASTE: return !!CanPaste();
+ case IDC_CUT: return !!CanCut();
+ case IDC_COPY: return !!CanCopy();
+ case IDC_PASTE: return !!CanPaste();
case IDS_PASTE_AND_GO: return CanPasteAndGo(GetClipboardText());
case IDS_SELECT_ALL: return !!CanSelectAll();
case IDS_EDIT_SEARCH_ENGINES:
@@ -968,21 +946,28 @@ bool AutocompleteEditViewWin::IsCommandEnabled(int id) const {
}
}
-bool AutocompleteEditViewWin::GetContextualLabel(int id,
- std::wstring* out) const {
- if ((id != IDS_PASTE_AND_GO) ||
- // No need to change the default IDS_PASTE_AND_GO label unless this is a
- // search.
- !model_->is_paste_and_search())
- return false;
+bool AutocompleteEditViewWin::GetAcceleratorForCommandId(
+ int command_id,
+ views::Accelerator* accelerator) {
+ return parent_view_->GetWidget()->GetAccelerator(command_id, accelerator);
+}
- out->assign(l10n_util::GetString(IDS_PASTE_AND_SEARCH));
- return true;
+bool AutocompleteEditViewWin::IsLabelForCommandIdDynamic(int command_id) const {
+ // No need to change the default IDS_PASTE_AND_GO label unless this is a
+ // search.
+ return command_id == IDS_PASTE_AND_GO;
}
-void AutocompleteEditViewWin::ExecuteCommand(int id) {
+std::wstring AutocompleteEditViewWin::GetLabelForCommandId(
+ int command_id) const {
+ DCHECK(command_id == IDS_PASTE_AND_GO);
+ return l10n_util::GetString(model_->is_paste_and_search() ?
+ IDS_PASTE_AND_SEARCH : IDS_PASTE_AND_GO);
+}
+
+void AutocompleteEditViewWin::ExecuteCommand(int command_id) {
ScopedFreeze freeze(this, GetTextObjectModel());
- if (id == IDS_PASTE_AND_GO) {
+ if (command_id == IDS_PASTE_AND_GO) {
// This case is separate from the switch() below since we don't want to wrap
// it in OnBefore/AfterPossibleChange() calls.
model_->PasteAndGo();
@@ -990,20 +975,20 @@ void AutocompleteEditViewWin::ExecuteCommand(int id) {
}
OnBeforePossibleChange();
- switch (id) {
+ switch (command_id) {
case IDS_UNDO:
Undo();
break;
- case IDS_CUT:
+ case IDC_CUT:
Cut();
break;
- case IDS_COPY:
+ case IDC_COPY:
Copy();
break;
- case IDS_PASTE:
+ case IDC_PASTE:
Paste();
break;
@@ -1173,13 +1158,14 @@ void AutocompleteEditViewWin::OnChar(TCHAR ch, UINT repeat_count, UINT flags) {
}
void AutocompleteEditViewWin::OnContextMenu(HWND window, const CPoint& point) {
+ BuildContextMenu();
if (point.x == -1 || point.y == -1) {
POINT p;
GetCaretPos(&p);
MapWindowPoints(HWND_DESKTOP, &p, 1);
- context_menu_->RunMenuAt(p.x, p.y);
+ context_menu_->RunContextMenuAt(gfx::Point(p));
} else {
- context_menu_->RunMenuAt(point.x, point.y);
+ context_menu_->RunContextMenuAt(gfx::Point(point));
}
}
@@ -2329,3 +2315,30 @@ void AutocompleteEditViewWin::RepaintDropHighlight(int position) {
InvalidateRect(&highlight_bounds, false);
}
}
+
+void AutocompleteEditViewWin::BuildContextMenu() {
+ if (context_menu_contents_.get())
+ return;
+
+ context_menu_contents_.reset(new views::SimpleMenuModel(this));
+ // Set up context menu.
+ if (popup_window_mode_) {
+ context_menu_contents_->AddItemWithStringId(IDS_COPY, IDS_COPY);
+ } else {
+ context_menu_contents_->AddItemWithStringId(IDS_UNDO, IDS_UNDO);
+ context_menu_contents_->AddSeparator();
+ context_menu_contents_->AddItemWithStringId(IDC_CUT, IDS_CUT);
+ context_menu_contents_->AddItemWithStringId(IDC_COPY, IDS_COPY);
+ context_menu_contents_->AddItemWithStringId(IDC_PASTE, IDS_PASTE);
+ // GetContextualLabel() will override this next label with the
+ // IDS_PASTE_AND_SEARCH label as needed.
+ context_menu_contents_->AddItemWithStringId(IDS_PASTE_AND_GO,
+ IDS_PASTE_AND_GO);
+ context_menu_contents_->AddSeparator();
+ context_menu_contents_->AddItemWithStringId(IDS_SELECT_ALL, IDS_SELECT_ALL);
+ context_menu_contents_->AddSeparator();
+ context_menu_contents_->AddItemWithStringId(IDS_EDIT_SEARCH_ENGINES,
+ IDS_EDIT_SEARCH_ENGINES);
+ }
+ context_menu_.reset(new views::Menu2(context_menu_contents_.get()));
+}
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.h b/chrome/browser/autocomplete/autocomplete_edit_view_win.h
index 822ebea..0c91820 100644
--- a/chrome/browser/autocomplete/autocomplete_edit_view_win.h
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.h
@@ -19,7 +19,7 @@
#include "chrome/browser/toolbar_model.h"
#include "chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h"
#include "chrome/common/page_transition_types.h"
-#include "views/controls/menu/menu.h"
+#include "views/controls/menu/simple_menu_model.h"
#include "webkit/glue/window_open_disposition.h"
class AutocompletePopupModel;
@@ -44,7 +44,7 @@ class AutocompleteEditViewWin
CWinTraits<WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL |
ES_NOHIDESEL> >,
public CRichEditCommands<AutocompleteEditViewWin>,
- public views::Menu::Delegate,
+ public views::SimpleMenuModel::Delegate,
public AutocompleteEditView {
public:
struct State {
@@ -179,10 +179,14 @@ class AutocompleteEditViewWin
DEFAULT_REFLECTION_HANDLER() // avoids black margin area
END_MSG_MAP()
- // Menu::Delegate
- virtual bool IsCommandEnabled(int id) const;
- virtual bool GetContextualLabel(int id, std::wstring* out) const;
- virtual void ExecuteCommand(int id);
+ // SimpleMenuModel::Delegate
+ virtual bool IsCommandIdChecked(int command_id) const;
+ virtual bool IsCommandIdEnabled(int command_id) const;
+ virtual bool GetAcceleratorForCommandId(int command_id,
+ views::Accelerator* accelerator);
+ virtual bool IsLabelForCommandIdDynamic(int command_id) const;
+ virtual std::wstring GetLabelForCommandId(int command_id) const;
+ virtual void ExecuteCommand(int command_id);
private:
// This object freezes repainting of the edit until the object is destroyed.
@@ -357,6 +361,9 @@ class AutocompleteEditViewWin
// text.
void RepaintDropHighlight(int position);
+ // Generates the context menu for the edit field.
+ void BuildContextMenu();
+
scoped_ptr<AutocompleteEditModel> model_;
scoped_ptr<AutocompletePopupView> popup_view_;
@@ -426,7 +433,8 @@ class AutocompleteEditViewWin
CHARRANGE saved_selection_for_focus_change_;
// The context menu for the edit.
- scoped_ptr<views::Menu> context_menu_;
+ scoped_ptr<views::SimpleMenuModel> context_menu_contents_;
+ scoped_ptr<views::Menu2> context_menu_;
// Font we're using. We keep a reference to make sure the font supplied to
// the constructor doesn't go away before we do.
diff --git a/chrome/browser/autocomplete/search_provider.cc b/chrome/browser/autocomplete/search_provider.cc
index d3d91ca..8a6d305 100644
--- a/chrome/browser/autocomplete/search_provider.cc
+++ b/chrome/browser/autocomplete/search_provider.cc
@@ -716,15 +716,15 @@ void SearchProvider::AddMatchToMap(const std::wstring& query_string,
// looks odd if both the first and last s are highlighted.
if (input_position != 0) {
match.contents_class.push_back(
- ACMatchClassification(0, ACMatchClassification::MATCH));
+ ACMatchClassification(0, ACMatchClassification::NONE));
}
match.contents_class.push_back(
- ACMatchClassification(input_position, ACMatchClassification::NONE));
+ ACMatchClassification(input_position, ACMatchClassification::DIM));
size_t next_fragment_position = input_position + input_text.length();
if (next_fragment_position < query_string.length()) {
match.contents_class.push_back(
ACMatchClassification(next_fragment_position,
- ACMatchClassification::MATCH));
+ ACMatchClassification::NONE));
}
}
} else {
diff --git a/chrome/browser/external_tab_container.cc b/chrome/browser/external_tab_container.cc
index 2dbf706..6c9b2a8 100644
--- a/chrome/browser/external_tab_container.cc
+++ b/chrome/browser/external_tab_container.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/external_tab_container.h"
+#include "app/l10n_util.h"
#include "app/win_util.h"
#include "base/logging.h"
#include "base/win_util.h"
@@ -268,17 +269,17 @@ bool ExternalTabContainer::HandleContextMenu(const ContextMenuParams& params) {
external_context_menu_.reset(
new RenderViewContextMenuExternalWin(tab_contents(),
params,
- GetNativeView(),
disabled_context_menu_ids_));
external_context_menu_->Init();
POINT screen_pt = { params.x, params.y };
MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_pt, 1);
+ bool rtl = l10n_util::TextDirection() == l10n_util::RIGHT_TO_LEFT;
automation_->Send(
new AutomationMsg_ForwardContextMenuToExternalHost(0, tab_handle_,
external_context_menu_->GetMenuHandle(), screen_pt.x, screen_pt.y,
- external_context_menu_->GetTPMAlignFlags()));
+ rtl ? TPM_RIGHTALIGN : TPM_LEFTALIGN));
return true;
}
diff --git a/chrome/browser/tab_contents/render_view_context_menu_external_win.cc b/chrome/browser/tab_contents/render_view_context_menu_external_win.cc
index 0c19f94..a9667c9 100644
--- a/chrome/browser/tab_contents/render_view_context_menu_external_win.cc
+++ b/chrome/browser/tab_contents/render_view_context_menu_external_win.cc
@@ -9,9 +9,8 @@
RenderViewContextMenuExternalWin::RenderViewContextMenuExternalWin(
TabContents* tab_contents,
const ContextMenuParams& params,
- HWND owner,
const std::vector<int> disabled_ids)
- : RenderViewContextMenuWin(tab_contents, params, owner),
+ : RenderViewContextMenuWin(tab_contents, params),
disabled_menu_ids_(disabled_ids) {
}
diff --git a/chrome/browser/tab_contents/render_view_context_menu_external_win.h b/chrome/browser/tab_contents/render_view_context_menu_external_win.h
index 3c31e44..0bd6f24 100644
--- a/chrome/browser/tab_contents/render_view_context_menu_external_win.h
+++ b/chrome/browser/tab_contents/render_view_context_menu_external_win.h
@@ -15,7 +15,6 @@ class RenderViewContextMenuExternalWin : public RenderViewContextMenuWin {
public:
RenderViewContextMenuExternalWin(TabContents* tab_contents,
const ContextMenuParams& params,
- HWND window,
const std::vector<int> disabled_menu_ids);
~RenderViewContextMenuExternalWin() {}
diff --git a/chrome/browser/tab_contents/render_view_context_menu_win.cc b/chrome/browser/tab_contents/render_view_context_menu_win.cc
index 952993f..66a923c 100644
--- a/chrome/browser/tab_contents/render_view_context_menu_win.cc
+++ b/chrome/browser/tab_contents/render_view_context_menu_win.cc
@@ -9,90 +9,44 @@
#include "chrome/browser/profile.h"
#include "grit/generated_resources.h"
+////////////////////////////////////////////////////////////////////////////////
+// RenderViewContextMenuWin, public:
+
RenderViewContextMenuWin::RenderViewContextMenuWin(
TabContents* tab_contents,
- const ContextMenuParams& params,
- HWND owner)
+ const ContextMenuParams& params)
: RenderViewContextMenu(tab_contents, params),
- sub_menu_(NULL),
- owner_(owner) {
- // anchor_position set per http://crbug.com/10827.
- views::Menu::AnchorPoint anchor_position = views::Menu::TOPLEFT;
- if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT)
- anchor_position = views::Menu::TOPRIGHT;
- menu_.reset(new views::MenuWin(this, anchor_position, owner_));
+ current_radio_group_id_(-1),
+ sub_menu_contents_(NULL) {
+ menu_contents_.reset(new views::SimpleMenuModel(this));
+ InitMenu(params.node);
+ menu_.reset(new views::Menu2(menu_contents_.get()));
}
RenderViewContextMenuWin::~RenderViewContextMenuWin() {
}
void RenderViewContextMenuWin::RunMenuAt(int x, int y) {
- menu_->RunMenuAt(x, y);
-}
-
-void RenderViewContextMenuWin::AppendMenuItem(int id) {
- AppendItem(id, l10n_util::GetString(id), views::Menu::NORMAL);
-}
-
-void RenderViewContextMenuWin::AppendMenuItem(int id,
- const std::wstring& label) {
- AppendItem(id, label, views::Menu::NORMAL);
-}
-
-void RenderViewContextMenuWin::AppendRadioMenuItem(int id,
- const std::wstring& label) {
- AppendItem(id, label, views::Menu::RADIO);
-}
-
-void RenderViewContextMenuWin::AppendCheckboxMenuItem(int id,
- const std::wstring& label) {
- AppendItem(id, label, views::Menu::CHECKBOX);
-}
-
-void RenderViewContextMenuWin::AppendSeparator() {
- views::Menu* menu = sub_menu_ ? sub_menu_ : menu_.get();
- menu->AppendSeparator();
-}
-
-void RenderViewContextMenuWin::StartSubMenu(int id, const std::wstring& label) {
- if (sub_menu_) {
- NOTREACHED();
- return;
- }
- sub_menu_ = menu_->AppendSubMenu(id, label);
-}
-
-void RenderViewContextMenuWin::FinishSubMenu() {
- DCHECK(sub_menu_);
- sub_menu_ = NULL;
-}
-
-void RenderViewContextMenuWin::AppendItem(
- int id,
- const std::wstring& label,
- views::Menu::MenuItemType type) {
- views::Menu* menu = sub_menu_ ? sub_menu_ : menu_.get();
- menu->AppendMenuItem(id, label, type);
+ menu_->RunContextMenuAt(gfx::Point(x, y));
}
-bool RenderViewContextMenuWin::IsCommandEnabled(int id) const {
- return IsItemCommandEnabled(id);
-}
+////////////////////////////////////////////////////////////////////////////////
+// RenderViewContextMenuWin, views::SimpleMenuModel::Delegate implementation:
-bool RenderViewContextMenuWin::IsItemChecked(int id) const {
- return ItemIsChecked(id);
+bool RenderViewContextMenuWin::IsCommandIdChecked(int command_id) const {
+ return ItemIsChecked(command_id);
}
-void RenderViewContextMenuWin::ExecuteCommand(int id) {
- ExecuteItemCommand(id);
+bool RenderViewContextMenuWin::IsCommandIdEnabled(int command_id) const {
+ return IsItemCommandEnabled(command_id);
}
-bool RenderViewContextMenuWin::GetAcceleratorInfo(
- int id,
+bool RenderViewContextMenuWin::GetAcceleratorForCommandId(
+ int command_id,
views::Accelerator* accel) {
// There are no formally defined accelerators we can query so we assume
// that Ctrl+C, Ctrl+V, Ctrl+X, Ctrl-A, etc do what they normally do.
- switch (id) {
+ switch (command_id) {
case IDS_CONTENT_CONTEXT_UNDO:
*accel = views::Accelerator(L'Z', false, true, false);
return true;
@@ -121,3 +75,64 @@ bool RenderViewContextMenuWin::GetAcceleratorInfo(
return false;
}
}
+
+void RenderViewContextMenuWin::ExecuteCommand(int command_id) {
+ ExecuteItemCommand(command_id);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// RenderViewContextMenuWin, protected:
+
+void RenderViewContextMenuWin::AppendMenuItem(int id) {
+ current_radio_group_id_ = -1;
+ GetTargetModel()->AddItemWithStringId(id, id);
+}
+
+void RenderViewContextMenuWin::AppendMenuItem(int id,
+ const std::wstring& label) {
+ current_radio_group_id_ = -1;
+ GetTargetModel()->AddItem(id, label);
+}
+
+void RenderViewContextMenuWin::AppendRadioMenuItem(int id,
+ const std::wstring& label) {
+ if (current_radio_group_id_ < 0)
+ current_radio_group_id_ = id;
+ GetTargetModel()->AddRadioItem(id, label, current_radio_group_id_);
+}
+
+void RenderViewContextMenuWin::AppendCheckboxMenuItem(
+ int id,
+ const std::wstring& label) {
+ current_radio_group_id_ = -1;
+ GetTargetModel()->AddCheckItem(id, label);
+}
+
+void RenderViewContextMenuWin::AppendSeparator() {
+ current_radio_group_id_ = -1;
+ GetTargetModel()->AddSeparator();
+}
+
+void RenderViewContextMenuWin::StartSubMenu(int id, const std::wstring& label) {
+ if (sub_menu_contents_) {
+ NOTREACHED() << "nested submenus not supported yet";
+ return;
+ }
+ current_radio_group_id_ = -1;
+ sub_menu_contents_ = new views::SimpleMenuModel(this);
+ menu_contents_->AddSubMenu(label, sub_menu_contents_);
+ submenu_models_.push_back(sub_menu_contents_);
+}
+
+void RenderViewContextMenuWin::FinishSubMenu() {
+ DCHECK(sub_menu_contents_);
+ current_radio_group_id_ = -1;
+ sub_menu_contents_ = NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// RenderViewContextMenuWin, private:
+
+views::SimpleMenuModel* RenderViewContextMenuWin::GetTargetModel() const {
+ return sub_menu_contents_ ? sub_menu_contents_ : menu_contents_.get();
+}
diff --git a/chrome/browser/tab_contents/render_view_context_menu_win.h b/chrome/browser/tab_contents/render_view_context_menu_win.h
index 3488d59..e188533 100644
--- a/chrome/browser/tab_contents/render_view_context_menu_win.h
+++ b/chrome/browser/tab_contents/render_view_context_menu_win.h
@@ -6,34 +6,30 @@
#define CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_CONTEXT_MENU_WIN_H_
#include "base/scoped_ptr.h"
+#include "base/scoped_vector.h"
#include "chrome/browser/tab_contents/render_view_context_menu.h"
#include "views/accelerator.h"
-#include "views/controls/menu/menu_win.h"
+#include "views/controls/menu/simple_menu_model.h"
class RenderViewContextMenuWin : public RenderViewContextMenu,
- public views::Menu::Delegate {
+ public views::SimpleMenuModel::Delegate {
public:
RenderViewContextMenuWin(TabContents* tab_contents,
- const ContextMenuParams& params,
- HWND window);
+ const ContextMenuParams& params);
~RenderViewContextMenuWin();
void RunMenuAt(int x, int y);
- // Menu::Delegate implementation ---------------------------------------------
- virtual bool IsCommandEnabled(int id) const;
- virtual bool IsItemChecked(int id) const;
- virtual void ExecuteCommand(int id);
- // TODO(port): move the logic in this function to RenderViewContextMenu.
- virtual bool GetAcceleratorInfo(int id, views::Accelerator* accel);
+ // Overridden from SimpleMenuModel::Delegate:
+ virtual bool IsCommandIdChecked(int command_id) const;
+ virtual bool IsCommandIdEnabled(int command_id) const;
+ virtual bool GetAcceleratorForCommandId(int command_id,
+ views::Accelerator* accelerator);
+ virtual void ExecuteCommand(int command_id);
HMENU GetMenuHandle() const {
- return (menu_.get() ? menu_->GetMenuHandle() : NULL);
- }
-
- unsigned int GetTPMAlignFlags() const {
- return (menu_.get() ? menu_->GetTPMAlignFlags() : 0);
+ return (menu_.get() ? menu_->GetNativeMenu() : NULL);
}
protected:
@@ -47,13 +43,21 @@ class RenderViewContextMenuWin : public RenderViewContextMenu,
virtual void FinishSubMenu();
private:
- // Append the item to |sub_menu_| if it exists, or |menu_| otherwise.
- void AppendItem(int id,
- const std::wstring& label,
- views::Menu::MenuItemType type);
+ // Gets the target model to append items to. This is either the main context
+ // menu, or a submenu if we've descended into one.
+ views::SimpleMenuModel* GetTargetModel() const;
+
+ // The current radio group for radio menu items.
+ int current_radio_group_id_;
- scoped_ptr<views::MenuWin> menu_;
- views::Menu* sub_menu_;
+ // The context menu itself and its contents.
+ scoped_ptr<views::SimpleMenuModel> menu_contents_;
+ scoped_ptr<views::Menu2> menu_;
+ // TODO(beng): This way of building submenus is kind of retarded, but it
+ // hasn't hurt us yet. It's just a bit awkward.
+ views::SimpleMenuModel* sub_menu_contents_;
+ // We own submenu models that we create, so we store them here.
+ ScopedVector<views::SimpleMenuModel> submenu_models_;
HWND owner_;
};
diff --git a/chrome/browser/tab_contents/tab_contents_view_win.cc b/chrome/browser/tab_contents/tab_contents_view_win.cc
index 341eb50..9452737 100644
--- a/chrome/browser/tab_contents/tab_contents_view_win.cc
+++ b/chrome/browser/tab_contents/tab_contents_view_win.cc
@@ -394,15 +394,10 @@ void TabContentsViewWin::HandleKeyboardEvent(
void TabContentsViewWin::ShowContextMenu(const ContextMenuParams& params) {
// Allow delegates to handle the context menu operation first.
- if (tab_contents()->delegate()->HandleContextMenu(params)) {
+ if (tab_contents()->delegate()->HandleContextMenu(params))
return;
- }
-
- RenderViewContextMenuWin menu(tab_contents(),
- params,
- GetNativeView());
- menu.Init();
+ context_menu_.reset(new RenderViewContextMenuWin(tab_contents(), params));
POINT screen_pt = { params.x, params.y };
MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_pt, 1);
@@ -411,7 +406,7 @@ void TabContentsViewWin::ShowContextMenu(const ContextMenuParams& params) {
// the context menu is being displayed.
bool old_state = MessageLoop::current()->NestableTasksAllowed();
MessageLoop::current()->SetNestableTasksAllowed(true);
- menu.RunMenuAt(screen_pt.x, screen_pt.y);
+ context_menu_->RunMenuAt(screen_pt.x, screen_pt.y);
MessageLoop::current()->SetNestableTasksAllowed(old_state);
}
diff --git a/chrome/browser/tab_contents/tab_contents_view_win.h b/chrome/browser/tab_contents/tab_contents_view_win.h
index 07bd545..6af85a1 100644
--- a/chrome/browser/tab_contents/tab_contents_view_win.h
+++ b/chrome/browser/tab_contents/tab_contents_view_win.h
@@ -10,11 +10,11 @@
#include "chrome/browser/tab_contents/tab_contents_view.h"
#include "views/widget/widget_win.h"
+class RenderViewContextMenuWin;
class SadTabView;
struct WebDropData;
class WebDropTarget;
-
// Windows-specific implementation of the TabContentsView. It is a HWND that
// contains all of the contents of the tab and associated child views.
class TabContentsViewWin : public TabContentsView,
@@ -101,6 +101,9 @@ class TabContentsViewWin : public TabContentsView,
// The id used in the ViewStorage to store the last focused view.
int last_focused_view_storage_id_;
+ // The context menu. Callbacks are asynchronous so we need to keep it around.
+ scoped_ptr<RenderViewContextMenuWin> context_menu_;
+
DISALLOW_COPY_AND_ASSIGN(TabContentsViewWin);
};
diff --git a/chrome/browser/views/bookmark_bar_view.h b/chrome/browser/views/bookmark_bar_view.h
index 23f98e3..c747610 100644
--- a/chrome/browser/views/bookmark_bar_view.h
+++ b/chrome/browser/views/bookmark_bar_view.h
@@ -13,7 +13,6 @@
#include "chrome/common/notification_registrar.h"
#include "views/controls/button/menu_button.h"
#include "views/controls/label.h"
-#include "views/controls/menu/menu.h"
#include "views/controls/menu/view_menu_delegate.h"
#include "views/view.h"
#include "third_party/skia/include/core/SkRect.h"
@@ -37,7 +36,6 @@ class BookmarkBarView : public views::View,
public BookmarkModelObserver,
public views::ViewMenuDelegate,
public views::ButtonListener,
- public views::Menu::Delegate,
public NotificationObserver,
public views::ContextMenuController,
public views::DragController,
diff --git a/chrome/browser/views/bookmark_editor_view.cc b/chrome/browser/views/bookmark_editor_view.cc
index b845b39..3208099 100644
--- a/chrome/browser/views/bookmark_editor_view.cc
+++ b/chrome/browser/views/bookmark_editor_view.cc
@@ -187,20 +187,30 @@ void BookmarkEditorView::ButtonPressed(Button* sender) {
}
}
-void BookmarkEditorView::ExecuteCommand(int id) {
+bool BookmarkEditorView::IsCommandIdChecked(int command_id) const {
+ return false;
+}
+
+bool BookmarkEditorView::IsCommandIdEnabled(int command_id) const {
+ return (command_id != IDS_EDIT || !running_menu_for_root_);
+}
+
+bool BookmarkEditorView::GetAcceleratorForCommandId(
+ int command_id,
+ views::Accelerator* accelerator) {
+ return GetWidget()->GetAccelerator(command_id, accelerator);
+}
+
+void BookmarkEditorView::ExecuteCommand(int command_id) {
DCHECK(tree_view_->GetSelectedNode());
- if (id == IDS_EDIT) {
+ if (command_id == IDS_EDIT) {
tree_view_->StartEditing(tree_view_->GetSelectedNode());
} else {
- DCHECK(id == IDS_BOOMARK_EDITOR_NEW_FOLDER_MENU_ITEM);
+ DCHECK(command_id == IDS_BOOMARK_EDITOR_NEW_FOLDER_MENU_ITEM);
NewGroup();
}
}
-bool BookmarkEditorView::IsCommandEnabled(int id) const {
- return (id != IDS_EDIT || !running_menu_for_root_);
-}
-
void BookmarkEditorView::Show(HWND parent_hwnd) {
views::Window::CreateChromeWindow(parent_hwnd, gfx::Rect(), this);
UserInputChanged();
@@ -228,14 +238,15 @@ void BookmarkEditorView::ShowContextMenu(View* source,
running_menu_for_root_ =
(tree_model_->GetParent(tree_view_->GetSelectedNode()) ==
tree_model_->GetRoot());
- context_menu_.reset(views::Menu::Create(this, views::Menu::TOPLEFT,
- GetWidget()->GetNativeView()));
- context_menu_->AppendMenuItemWithLabel(IDS_EDIT,
- l10n_util::GetString(IDS_EDIT));
- context_menu_->AppendMenuItemWithLabel(
- IDS_BOOMARK_EDITOR_NEW_FOLDER_MENU_ITEM,
- l10n_util::GetString(IDS_BOOMARK_EDITOR_NEW_FOLDER_MENU_ITEM));
- context_menu_->RunMenuAt(x, y);
+ if (!context_menu_contents_.get()) {
+ context_menu_contents_.reset(new views::SimpleMenuModel(this));
+ context_menu_contents_->AddItemWithStringId(IDS_EDIT, IDS_EDIT);
+ context_menu_contents_->AddItemWithStringId(
+ IDS_BOOMARK_EDITOR_NEW_FOLDER_MENU_ITEM,
+ IDS_BOOMARK_EDITOR_NEW_FOLDER_MENU_ITEM);
+ context_menu_.reset(new views::Menu2(context_menu_contents_.get()));
+ }
+ context_menu_->RunContextMenuAt(gfx::Point(x, y));
}
void BookmarkEditorView::Init() {
diff --git a/chrome/browser/views/bookmark_editor_view.h b/chrome/browser/views/bookmark_editor_view.h
index 1758325..51ef925 100644
--- a/chrome/browser/views/bookmark_editor_view.h
+++ b/chrome/browser/views/bookmark_editor_view.h
@@ -11,7 +11,7 @@
#include "chrome/browser/bookmarks/bookmark_editor.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "views/controls/button/button.h"
-#include "views/controls/menu/menu.h"
+#include "views/controls/menu/simple_menu_model.h"
#include "views/controls/textfield/textfield.h"
#include "views/controls/tree/tree_view.h"
#include "views/window/dialog_delegate.h"
@@ -40,7 +40,7 @@ class BookmarkEditorView : public BookmarkEditor,
public views::DialogDelegate,
public views::Textfield::Controller,
public views::ContextMenuController,
- public views::Menu::Delegate,
+ public views::SimpleMenuModel::Delegate,
public BookmarkModelObserver {
FRIEND_TEST(BookmarkEditorViewTest, ChangeParent);
FRIEND_TEST(BookmarkEditorViewTest, ChangeParentAndURL);
@@ -91,12 +91,12 @@ class BookmarkEditorView : public BookmarkEditor,
// NativeButton.
virtual void ButtonPressed(views::Button* sender);
- // Menu::Delegate method.
- virtual void ExecuteCommand(int id);
-
- // Menu::Delegate method, return false if id is edit and the bookmark node
- // was selected, true otherwise.
- virtual bool IsCommandEnabled(int id) const;
+ // SimpleMenuModel::Delegate.
+ virtual bool IsCommandIdChecked(int command_id) const;
+ virtual bool IsCommandIdEnabled(int command_id) const;
+ virtual bool GetAcceleratorForCommandId(int command_id,
+ views::Accelerator* accelerator);
+ virtual void ExecuteCommand(int command_id);
// Creates a Window and adds the BookmarkEditorView to it. When the window is
// closed the BookmarkEditorView is deleted.
@@ -244,7 +244,8 @@ class BookmarkEditorView : public BookmarkEditor,
BookmarkNode* node_;
// The context menu.
- scoped_ptr<views::Menu> context_menu_;
+ scoped_ptr<views::SimpleMenuModel> context_menu_contents_;
+ scoped_ptr<views::Menu2> context_menu_;
// Mode used to create nodes from.
BookmarkModel* bb_model_;
diff --git a/chrome/browser/views/bookmark_table_view.h b/chrome/browser/views/bookmark_table_view.h
index ed83bcb..b80d1fa 100644
--- a/chrome/browser/views/bookmark_table_view.h
+++ b/chrome/browser/views/bookmark_table_view.h
@@ -7,7 +7,6 @@
#include "chrome/browser/bookmarks/bookmark_drag_data.h"
#include "chrome/browser/bookmarks/bookmark_drop_info.h"
-#include "views/controls/menu/menu.h"
#include "views/controls/table/table_view.h"
class BookmarkModel;
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc
index 1b3e42b..db7a04f 100644
--- a/chrome/browser/views/frame/browser_view.cc
+++ b/chrome/browser/views/frame/browser_view.cc
@@ -55,7 +55,6 @@
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "grit/webkit_resources.h"
-#include "views/controls/menu/menu.h"
#if defined(OS_WIN)
#include "views/controls/scrollbar/native_scroll_bar.h"
#endif
@@ -461,6 +460,20 @@ bool BrowserView::AcceleratorPressed(const views::Accelerator& accelerator) {
}
bool BrowserView::GetAccelerator(int cmd_id, views::Accelerator* accelerator) {
+ // The standard Ctrl-X, Ctrl-V and Ctrl-C are not defined as accelerators
+ // anywhere so we need to check for them explicitly here.
+ switch (cmd_id) {
+ case IDC_CUT:
+ *accelerator = views::Accelerator(L'X', false, true, false);
+ return true;
+ case IDC_COPY:
+ *accelerator = views::Accelerator(L'C', false, true, false);
+ return true;
+ case IDC_PASTE:
+ *accelerator = views::Accelerator(L'V', false, true, false);
+ return true;
+ }
+ // Else, we retrieve the accelerator information from the accelerator table.
std::map<views::Accelerator, int>::iterator it =
accelerator_table_->begin();
for (; it != accelerator_table_->end(); ++it) {
diff --git a/chrome/browser/views/tabs/tab_renderer.h b/chrome/browser/views/tabs/tab_renderer.h
index e68308c..d265b53 100644
--- a/chrome/browser/views/tabs/tab_renderer.h
+++ b/chrome/browser/views/tabs/tab_renderer.h
@@ -10,7 +10,6 @@
#include "app/throb_animation.h"
#include "base/gfx/point.h"
#include "views/controls/button/image_button.h"
-#include "views/controls/menu/menu.h"
#include "views/view.h"
class TabContents;
diff --git a/chrome/browser/views/tabs/tab_strip.h b/chrome/browser/views/tabs/tab_strip.h
index 013f9d1..71f0301 100644
--- a/chrome/browser/views/tabs/tab_strip.h
+++ b/chrome/browser/views/tabs/tab_strip.h
@@ -10,7 +10,6 @@
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/views/tabs/tab.h"
#include "views/controls/button/image_button.h"
-#include "views/controls/menu/menu.h"
#include "views/view.h"
#if defined(OS_WIN)
#include "views/widget/widget_win.h"
diff --git a/chrome/browser/views/toolbar_view.cc b/chrome/browser/views/toolbar_view.cc
index 3d64b1d..02f31fc 100644
--- a/chrome/browser/views/toolbar_view.cc
+++ b/chrome/browser/views/toolbar_view.cc
@@ -171,8 +171,9 @@ ToolbarView::ToolbarView(Browser* browser)
profile_(NULL),
browser_(browser),
tab_(NULL),
- profiles_menu_(NULL),
- profiles_helper_(new GetProfilesHelper(this)) {
+ profiles_menu_contents_(NULL),
+ ALLOW_THIS_IN_INITIALIZER_LIST(
+ profiles_helper_(new GetProfilesHelper(this))) {
browser_->command_updater()->AddCommandObserver(IDC_BACK, this);
browser_->command_updater()->AddCommandObserver(IDC_FORWARD, this);
browser_->command_updater()->AddCommandObserver(IDC_RELOAD, this);
@@ -253,21 +254,6 @@ int ToolbarView::GetNextAccessibleViewIndex(int view_index, bool nav_left) {
// ToolbarView, Menu::BaseControllerDelegate overrides:
bool ToolbarView::GetAcceleratorInfo(int id, views::Accelerator* accel) {
- // The standard Ctrl-X, Ctrl-V and Ctrl-C are not defined as accelerators
- // anywhere so we need to check for them explicitly here.
- // TODO(cpu) Bug 1109102. Query WebKit land for the actual bindings.
- switch (id) {
- case IDC_CUT:
- *accel = views::Accelerator(L'X', false, true, false);
- return true;
- case IDC_COPY:
- *accel = views::Accelerator(L'C', false, true, false);
- return true;
- case IDC_PASTE:
- *accel = views::Accelerator(L'V', false, true, false);
- return true;
- }
- // Else, we retrieve the accelerator information from the frame.
return GetWidget()->GetAccelerator(id, accel);
}
@@ -294,7 +280,7 @@ void ToolbarView::RunMenu(views::View* source, const gfx::Point& pt,
void ToolbarView::OnGetProfilesDone(
const std::vector<std::wstring>& profiles) {
// Nothing to do if the menu has gone away.
- if (!profiles_menu_)
+ if (!profiles_menu_contents_.get())
return;
// Store the latest list of profiles in the browser.
@@ -305,20 +291,20 @@ void ToolbarView::OnGetProfilesDone(
for (int i = IDC_NEW_WINDOW_PROFILE_0;
(i <= IDC_NEW_WINDOW_PROFILE_LAST) && (iter != profiles.end());
++i, ++iter)
- profiles_menu_->AppendMenuItemWithLabel(i, *iter);
+ profiles_menu_contents_->AddItem(i, *iter);
// If there are more profiles then show "Other" link.
if (iter != profiles.end()) {
- profiles_menu_->AppendSeparator();
- profiles_menu_->AppendMenuItemWithLabel(
- IDC_SELECT_PROFILE, l10n_util::GetString(IDS_SELECT_PROFILE));
+ profiles_menu_contents_->AddSeparator();
+ profiles_menu_contents_->AddItemWithStringId(IDC_SELECT_PROFILE,
+ IDS_SELECT_PROFILE);
}
// Always show a link to select a new profile.
- profiles_menu_->AppendSeparator();
- profiles_menu_->AppendMenuItemWithLabel(
+ profiles_menu_contents_->AddSeparator();
+ profiles_menu_contents_->AddItemWithStringId(
IDC_NEW_PROFILE,
- l10n_util::GetString(IDS_SELECT_PROFILE_DIALOG_NEW_PROFILE_ENTRY));
+ IDS_SELECT_PROFILE_DIALOG_NEW_PROFILE_ENTRY);
}
////////////////////////////////////////////////////////////////////////////////
@@ -1068,6 +1054,17 @@ void ToolbarView::CreateAppMenu() {
app_menu_contents_->AddItemWithStringId(IDC_NEW_WINDOW, IDS_NEW_WINDOW);
app_menu_contents_->AddItemWithStringId(IDC_NEW_INCOGNITO_WINDOW,
IDS_NEW_INCOGNITO_WINDOW);
+ // Enumerate profiles asynchronously and then create the parent menu item.
+ // We will create the child menu items for this once the asynchronous call is
+ // done. See OnGetProfilesDone().
+ const CommandLine& command_line = *CommandLine::ForCurrentProcess();
+ if (command_line.HasSwitch(switches::kEnableUserDataDirProfiles)) {
+ profiles_helper_->GetProfiles(NULL);
+ profiles_menu_contents_.reset(new views::SimpleMenuModel(this));
+ app_menu_contents_->AddSubMenuWithStringId(IDS_PROFILE_MENU,
+ profiles_menu_contents_.get());
+ }
+
app_menu_contents_->AddSeparator();
app_menu_contents_->AddCheckItemWithStringId(IDC_SHOW_BOOKMARK_BAR,
IDS_SHOW_BOOKMARK_BAR);
diff --git a/chrome/browser/views/toolbar_view.h b/chrome/browser/views/toolbar_view.h
index 169448b..efd9d2c 100644
--- a/chrome/browser/views/toolbar_view.h
+++ b/chrome/browser/views/toolbar_view.h
@@ -227,8 +227,8 @@ class ToolbarView : public views::View,
// Current tab we're showing state for.
TabContents* tab_;
- // Profiles menu to populate with profile names.
- views::Menu* profiles_menu_;
+ // Contents of the profiles menu to populate with profile names.
+ scoped_ptr<views::SimpleMenuModel> profiles_menu_contents_;
// Helper class to enumerate profiles information on the file thread.
scoped_refptr<GetProfilesHelper> profiles_helper_;
diff --git a/views/controls/menu/menu_2.cc b/views/controls/menu/menu_2.cc
index 8ce63b6..2a0ed56 100644
--- a/views/controls/menu/menu_2.cc
+++ b/views/controls/menu/menu_2.cc
@@ -50,6 +50,10 @@ void Menu2::RunMenuAt(const gfx::Point& point, Alignment alignment) {
wrapper_->RunMenuAt(point, alignment);
}
+void Menu2::RunContextMenuAt(const gfx::Point& point) {
+ wrapper_->RunMenuAt(point, ALIGN_TOPLEFT);
+}
+
void Menu2::CancelMenu() {
wrapper_->CancelMenu();
}
diff --git a/views/controls/menu/menu_2.h b/views/controls/menu/menu_2.h
index a131ee5..68c4833 100644
--- a/views/controls/menu/menu_2.h
+++ b/views/controls/menu/menu_2.h
@@ -114,8 +114,10 @@ class Menu2 {
};
// Runs the menu at the specified point. This may or may not block, depending
- // on the platform and type of menu in use.
+ // on the platform and type of menu in use. RunContextMenuAt is the same, but
+ // the alignment is the default for a context menu.
void RunMenuAt(const gfx::Point& point, Alignment alignment);
+ void RunContextMenuAt(const gfx::Point& point);
// Cancels the active menu.
void CancelMenu();
diff --git a/views/controls/menu/native_menu_win.cc b/views/controls/menu/native_menu_win.cc
index c82844e..c5f8331 100644
--- a/views/controls/menu/native_menu_win.cc
+++ b/views/controls/menu/native_menu_win.cc
@@ -63,7 +63,7 @@ class NativeMenuWin::MenuHostWindow {
NativeMenuWin* GetNativeMenuWinFromHMENU(HMENU hmenu) const {
MENUINFO mi = {0};
mi.cbSize = sizeof(mi);
- mi.fMask = MIM_MENUDATA;
+ mi.fMask = MIM_MENUDATA | MIM_STYLE;
GetMenuInfo(hmenu, &mi);
return reinterpret_cast<NativeMenuWin*>(mi.dwMenuData);
}
@@ -92,7 +92,9 @@ class NativeMenuWin::MenuHostWindow {
// Called when the user selects a specific item.
void OnMenuCommand(int position, HMENU menu) {
- GetNativeMenuWinFromHMENU(menu)->model_->ActivatedAt(position);
+ NativeMenuWin* intergoat = GetNativeMenuWinFromHMENU(menu);
+ Menu2Model* model = intergoat->model_;
+ model->ActivatedAt(position);
}
// Called as the user moves their mouse or arrows through the contents of the
@@ -165,6 +167,7 @@ NativeMenuWin::NativeMenuWin(Menu2Model* model, HWND system_menu_for)
NativeMenuWin::~NativeMenuWin() {
STLDeleteContainerPointers(items_.begin(), items_.end());
+ DestroyMenu(menu_);
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/views/controls/textfield/native_textfield_win.cc b/views/controls/textfield/native_textfield_win.cc
index d2044a5..65c6b53 100644
--- a/views/controls/textfield/native_textfield_win.cc
+++ b/views/controls/textfield/native_textfield_win.cc
@@ -97,21 +97,6 @@ NativeTextfieldWin::NativeTextfieldWin(Textfield* textfield)
ole_interface.Attach(GetOleInterface());
text_object_model_ = ole_interface;
- context_menu_.reset(new MenuWin(this, Menu::TOPLEFT, m_hWnd));
- context_menu_->AppendMenuItemWithLabel(IDS_APP_UNDO,
- l10n_util::GetString(IDS_APP_UNDO));
- context_menu_->AppendSeparator();
- context_menu_->AppendMenuItemWithLabel(IDS_APP_CUT,
- l10n_util::GetString(IDS_APP_CUT));
- context_menu_->AppendMenuItemWithLabel(IDS_APP_COPY,
- l10n_util::GetString(IDS_APP_COPY));
- context_menu_->AppendMenuItemWithLabel(IDS_APP_PASTE,
- l10n_util::GetString(IDS_APP_PASTE));
- context_menu_->AppendSeparator();
- context_menu_->AppendMenuItemWithLabel(
- IDS_APP_SELECT_ALL,
- l10n_util::GetString(IDS_APP_SELECT_ALL));
-
container_view_ = new NativeViewHost;
textfield_->AddChildView(container_view_);
container_view_->set_focus_view(textfield_);
@@ -227,13 +212,17 @@ gfx::NativeView NativeTextfieldWin::GetTestingHandle() const {
}
////////////////////////////////////////////////////////////////////////////////
-// NativeTextfieldWin, Menu::Delegate implementation:
+// NativeTextfieldWin, SimpleMenuModel::Delegate implementation:
+
+bool NativeTextfieldWin::IsCommandIdChecked(int command_id) const {
+ return false;
+}
-bool NativeTextfieldWin::IsCommandEnabled(int id) const {
- switch (id) {
+bool NativeTextfieldWin::IsCommandIdEnabled(int command_id) const {
+ switch (command_id) {
case IDS_APP_UNDO: return !textfield_->read_only() && !!CanUndo();
case IDS_APP_CUT: return !textfield_->read_only() &&
- !textfield_->IsPassword() && !!CanCut();
+ !textfield_->IsPassword() && !!CanCut();
case IDS_APP_COPY: return !!CanCopy() && !textfield_->IsPassword();
case IDS_APP_PASTE: return !textfield_->read_only() && !!CanPaste();
case IDS_APP_SELECT_ALL: return !!CanSelectAll();
@@ -242,10 +231,28 @@ bool NativeTextfieldWin::IsCommandEnabled(int id) const {
}
}
-void NativeTextfieldWin::ExecuteCommand(int id) {
+bool NativeTextfieldWin::GetAcceleratorForCommandId(int command_id,
+ Accelerator* accelerator) {
+ // The standard Ctrl-X, Ctrl-V and Ctrl-C are not defined as accelerators
+ // anywhere so we need to check for them explicitly here.
+ switch (command_id) {
+ case IDS_APP_CUT:
+ *accelerator = views::Accelerator(L'X', false, true, false);
+ return true;
+ case IDS_APP_COPY:
+ *accelerator = views::Accelerator(L'C', false, true, false);
+ return true;
+ case IDS_APP_PASTE:
+ *accelerator = views::Accelerator(L'V', false, true, false);
+ return true;
+ }
+ return container_view_->GetWidget()->GetAccelerator(command_id, accelerator);
+}
+
+void NativeTextfieldWin::ExecuteCommand(int command_id) {
ScopedFreeze freeze(this, GetTextObjectModel());
OnBeforePossibleChange();
- switch (id) {
+ switch (command_id) {
case IDS_APP_UNDO: Undo(); break;
case IDS_APP_CUT: Cut(); break;
case IDS_APP_COPY: Copy(); break;
@@ -269,7 +276,8 @@ void NativeTextfieldWin::OnContextMenu(HWND window, const CPoint& point) {
GetCaretPos(&p);
MapWindowPoints(HWND_DESKTOP, &p, 1);
}
- context_menu_->RunMenuAt(p.x, p.y);
+ BuildContextMenu();
+ context_menu_->RunContextMenuAt(gfx::Point(p));
}
void NativeTextfieldWin::OnCopy() {
@@ -837,6 +845,21 @@ ITextDocument* NativeTextfieldWin::GetTextObjectModel() const {
return text_object_model_;
}
+void NativeTextfieldWin::BuildContextMenu() {
+ if (context_menu_contents_.get())
+ return;
+ context_menu_contents_.reset(new SimpleMenuModel(this));
+ context_menu_contents_->AddItemWithStringId(IDS_APP_UNDO, IDS_APP_UNDO);
+ context_menu_contents_->AddSeparator();
+ context_menu_contents_->AddItemWithStringId(IDS_APP_CUT, IDS_APP_CUT);
+ context_menu_contents_->AddItemWithStringId(IDS_APP_COPY, IDS_APP_COPY);
+ context_menu_contents_->AddItemWithStringId(IDS_APP_PASTE, IDS_APP_PASTE);
+ context_menu_contents_->AddSeparator();
+ context_menu_contents_->AddItemWithStringId(IDS_APP_SELECT_ALL,
+ IDS_APP_SELECT_ALL);
+ context_menu_.reset(new Menu2(context_menu_contents_.get()));
+}
+
////////////////////////////////////////////////////////////////////////////////
// NativeTextfieldWrapper, public:
diff --git a/views/controls/textfield/native_textfield_win.h b/views/controls/textfield/native_textfield_win.h
index 58034c0..514c27f 100644
--- a/views/controls/textfield/native_textfield_win.h
+++ b/views/controls/textfield/native_textfield_win.h
@@ -13,6 +13,7 @@
#include <tom.h> // For ITextDocument, a COM interface to CRichEditCtrl
#include <vsstyle.h>
+#include "views/controls/menu/simple_menu_model.h"
#include "views/controls/textfield/native_textfield_wrapper.h"
namespace views {
@@ -28,7 +29,7 @@ class NativeTextfieldWin
CWinTraits<kDefaultEditStyle> >,
public CRichEditCommands<NativeTextfieldWin>,
public NativeTextfieldWrapper,
- public Menu::Delegate {
+ public SimpleMenuModel::Delegate {
public:
DECLARE_WND_CLASS(L"ViewsTextfieldEdit");
@@ -52,6 +53,13 @@ class NativeTextfieldWin
virtual View* GetView();
virtual gfx::NativeView GetTestingHandle() const;
+ // Overridden from SimpleMenuModel::Delegate:
+ virtual bool IsCommandIdChecked(int command_id) const;
+ virtual bool IsCommandIdEnabled(int command_id) const;
+ virtual bool GetAcceleratorForCommandId(int command_id,
+ Accelerator* accelerator);
+ virtual void ExecuteCommand(int command_id);
+
// CWindowImpl
BEGIN_MSG_MAP(Edit)
MSG_WM_CHAR(OnChar)
@@ -79,10 +87,6 @@ class NativeTextfieldWin
MSG_WM_SYSKEYDOWN(OnKeyDown)
END_MSG_MAP()
- // Menu::Delegate
- virtual bool IsCommandEnabled(int id) const;
- virtual void ExecuteCommand(int id);
-
private:
// This object freezes repainting of the edit until the object is destroyed.
// Some methods of the CRichEditCtrl draw synchronously to the screen. If we
@@ -156,6 +160,9 @@ class NativeTextfieldWin
// alive.
ITextDocument* GetTextObjectModel() const;
+ // Generates the contents of the context menu.
+ void BuildContextMenu();
+
// The Textfield this object is bound to.
Textfield* textfield_;
@@ -177,8 +184,9 @@ class NativeTextfieldWin
static bool did_load_library_;
- // The context menu for the edit.
- scoped_ptr<Menu> context_menu_;
+ // The contents of the context menu for the edit.
+ scoped_ptr<SimpleMenuModel> context_menu_contents_;
+ scoped_ptr<Menu2> context_menu_;
// Border insets.
gfx::Insets content_insets_;