Index: views/controls/menu/menu_item_view.cc |
diff --git a/views/controls/menu/menu_item_view.cc b/views/controls/menu/menu_item_view.cc |
index c2c266b880218e302021aca1f115a57632317d10..41943548665dd4d9b9fcdd032a578bab6b1344dd 100644 |
--- a/views/controls/menu/menu_item_view.cc |
+++ b/views/controls/menu/menu_item_view.cc |
@@ -5,6 +5,7 @@ |
#include "views/controls/menu/menu_item_view.h" |
#include "base/i18n/case_conversion.h" |
+#include "base/stl_util-inl.h" |
#include "base/utf_string_conversions.h" |
#include "grit/app_strings.h" |
#include "ui/base/accessibility/accessible_view_state.h" |
@@ -102,6 +103,7 @@ MenuItemView::~MenuItemView() { |
// MenuController should be the only place handling deletion of the menu. |
// (57890). |
delete submenu_; |
+ STLDeleteElements(&removed_items_); |
} |
bool MenuItemView::GetTooltipText(const gfx::Point& p, std::wstring* tooltip) { |
@@ -251,6 +253,46 @@ void MenuItemView::Cancel() { |
} |
} |
+MenuItemView* MenuItemView::AddMenuItemAt(int index, |
+ int item_id, |
+ const std::wstring& label, |
+ const SkBitmap& icon, |
+ Type type) { |
+ DCHECK_LE(0, index); |
+ if (!submenu_) |
+ CreateSubmenu(); |
+ DCHECK_GE(submenu_->child_count(), index); |
+ if (type == SEPARATOR) { |
+ submenu_->AddChildViewAt(new MenuSeparator(), index); |
+ return NULL; |
+ } |
+ MenuItemView* item = new MenuItemView(this, item_id, type); |
+ if (label.empty() && GetDelegate()) |
+ item->SetTitle(GetDelegate()->GetLabel(item_id)); |
+ else |
+ item->SetTitle(label); |
+ item->SetIcon(icon); |
+ if (type == SUBMENU) |
+ item->CreateSubmenu(); |
+ submenu_->AddChildViewAt(item, index); |
+ return item; |
+} |
+ |
+void MenuItemView::RemoveMenuItemAt(int index) { |
+ DCHECK(submenu_); |
+ DCHECK_LE(0, index); |
+ DCHECK_GT(submenu_->child_count(), index); |
+ |
+ View* item = submenu_->GetChildViewAt(index); |
+ DCHECK(item); |
+ submenu_->RemoveChildView(item); |
+ |
+ // RemoveChildView() does not delete the item, which is a good thing |
+ // in case a submenu is being displayed while items are being removed. |
+ // Deletion will be done by ChildrenChanged() or at destruction. |
+ removed_items_.push_back(item); |
+} |
+ |
MenuItemView* MenuItemView::AppendMenuItemFromModel(ui::MenuModel* model, |
int index, |
int id) { |
@@ -293,22 +335,8 @@ MenuItemView* MenuItemView::AppendMenuItemImpl(int item_id, |
const std::wstring& label, |
const SkBitmap& icon, |
Type type) { |
- if (!submenu_) |
- CreateSubmenu(); |
- if (type == SEPARATOR) { |
- submenu_->AddChildView(new MenuSeparator()); |
- return NULL; |
- } |
- MenuItemView* item = new MenuItemView(this, item_id, type); |
- if (label.empty() && GetDelegate()) |
- item->SetTitle(GetDelegate()->GetLabel(item_id)); |
- else |
- item->SetTitle(label); |
- item->SetIcon(icon); |
- if (type == SUBMENU) |
- item->CreateSubmenu(); |
- submenu_->AddChildView(item); |
- return item; |
+ const int index = submenu_ ? submenu_->child_count() : 0; |
+ return AddMenuItemAt(index, item_id, label, icon, type); |
} |
SubmenuView* MenuItemView::CreateSubmenu() { |
@@ -425,24 +453,25 @@ MenuItemView* MenuItemView::GetMenuItemByID(int id) { |
void MenuItemView::ChildrenChanged() { |
MenuController* controller = GetMenuController(); |
- if (!controller) |
- return; // We're not showing, nothing to do. |
+ if (controller) { |
+ // Handles the case where we were empty and are no longer empty. |
+ RemoveEmptyMenus(); |
- // Handles the case where we were empty and are no longer empty. |
- RemoveEmptyMenus(); |
- |
- // Handles the case where we were not empty, but now are. |
- AddEmptyMenus(); |
+ // Handles the case where we were not empty, but now are. |
+ AddEmptyMenus(); |
- controller->MenuChildrenChanged(this); |
+ controller->MenuChildrenChanged(this); |
- if (submenu_) { |
- // Force a paint and layout. This handles the case of the top level window's |
- // size remaining the same, resulting in no change to the submenu's size and |
- // no layout. |
- submenu_->Layout(); |
- submenu_->SchedulePaint(); |
+ if (submenu_) { |
+ // Force a paint and layout. This handles the case of the top |
+ // level window's size remaining the same, resulting in no |
+ // change to the submenu's size and no layout. |
+ submenu_->Layout(); |
+ submenu_->SchedulePaint(); |
+ } |
} |
+ |
+ STLDeleteElements(&removed_items_); |
} |
void MenuItemView::Layout() { |