diff options
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | app/app_base.gypi | 1 | ||||
-rw-r--r-- | chrome/browser/chromeos/status/clock_menu_button.h | 3 | ||||
-rw-r--r-- | chrome/browser/chromeos/status/input_method_menu.cc | 6 | ||||
-rw-r--r-- | chrome/browser/chromeos/status/input_method_menu.h | 3 | ||||
-rw-r--r-- | chrome/browser/chromeos/status/network_menu.cc | 2 | ||||
-rw-r--r-- | chrome/browser/chromeos/status/network_menu.h | 3 | ||||
-rw-r--r-- | chrome/browser/chromeos/status/power_menu_button.h | 3 | ||||
-rw-r--r-- | chrome/browser/ui/toolbar/back_forward_menu_model.cc | 76 | ||||
-rw-r--r-- | chrome/browser/ui/toolbar/back_forward_menu_model.h | 39 | ||||
-rw-r--r-- | chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc | 99 | ||||
-rw-r--r-- | ui/base/models/menu_model.h | 6 | ||||
-rw-r--r-- | ui/base/models/menu_model_delegate.h | 22 | ||||
-rw-r--r-- | ui/base/models/simple_menu_model.cc | 8 | ||||
-rw-r--r-- | ui/base/models/simple_menu_model.h | 7 | ||||
-rw-r--r-- | views/view_unittest.cc | 3 |
16 files changed, 264 insertions, 18 deletions
@@ -97,3 +97,4 @@ Kushal Pisavadia <kushi.p@gmail.com> Maarten Lankhorst <m.b.lankhorst@gmail.com> Vipul Bhasin <vipul.bhasin@gmail.com> Ryan Norton <rnorton10@gmail.com> +Dillon Sellars <dill.sellars@gmail.com> diff --git a/app/app_base.gypi b/app/app_base.gypi index 70d9227..0971ee4 100644 --- a/app/app_base.gypi +++ b/app/app_base.gypi @@ -166,6 +166,7 @@ '../ui/base/models/button_menu_item_model.h', '../ui/base/models/menu_model.cc', '../ui/base/models/menu_model.h', + '../ui/base/models/menu_model_delegate.h', '../ui/base/models/simple_menu_model.cc', '../ui/base/models/simple_menu_model.h', '../ui/base/models/combobox_model.h', diff --git a/chrome/browser/chromeos/status/clock_menu_button.h b/chrome/browser/chromeos/status/clock_menu_button.h index 3f85a2b..434309d 100644 --- a/chrome/browser/chromeos/status/clock_menu_button.h +++ b/chrome/browser/chromeos/status/clock_menu_button.h @@ -42,7 +42,7 @@ class ClockMenuButton : public StatusAreaButton, ui::Accelerator* accelerator) const { return false; } virtual bool IsItemCheckedAt(int index) const { return false; } virtual int GetGroupIdAt(int index) const { return 0; } - virtual bool GetIconAt(int index, SkBitmap* icon) const { return false; } + virtual bool GetIconAt(int index, SkBitmap* icon) { return false; } virtual ui::ButtonMenuItemModel* GetButtonMenuItemAt(int index) const { return NULL; } @@ -51,6 +51,7 @@ class ClockMenuButton : public StatusAreaButton, virtual void HighlightChangedTo(int index) {} virtual void ActivatedAt(int index); virtual void MenuWillShow() {} + virtual void SetMenuModelDelegate(ui::MenuModelDelegate* delegate) {} // Overridden from ResumeLibrary::Observer: virtual void PowerChanged(PowerLibrary* obj) {} diff --git a/chrome/browser/chromeos/status/input_method_menu.cc b/chrome/browser/chromeos/status/input_method_menu.cc index e004cf6..305871a 100644 --- a/chrome/browser/chromeos/status/input_method_menu.cc +++ b/chrome/browser/chromeos/status/input_method_menu.cc @@ -221,7 +221,7 @@ bool InputMethodMenu::HasIcons() const { return false; } -bool InputMethodMenu::GetIconAt(int index, SkBitmap* icon) const { +bool InputMethodMenu::GetIconAt(int index, SkBitmap* icon) { return false; } @@ -249,6 +249,10 @@ void InputMethodMenu::MenuWillShow() { // Views for Chromium OS does not support this interface yet. } +void InputMethodMenu::SetMenuModelDelegate(ui::MenuModelDelegate* delegate) { + // Not needed for current usage. +} + int InputMethodMenu::GetItemCount() const { if (!model_.get()) { // Model is not constructed yet. This means that diff --git a/chrome/browser/chromeos/status/input_method_menu.h b/chrome/browser/chromeos/status/input_method_menu.h index a336395..e377d61 100644 --- a/chrome/browser/chromeos/status/input_method_menu.h +++ b/chrome/browser/chromeos/status/input_method_menu.h @@ -48,13 +48,14 @@ class InputMethodMenu : public views::ViewMenuDelegate, ui::Accelerator* accelerator) const; virtual bool IsItemCheckedAt(int index) const; virtual int GetGroupIdAt(int index) const; - virtual bool GetIconAt(int index, SkBitmap* icon) const; + virtual bool GetIconAt(int index, SkBitmap* icon); virtual ui::ButtonMenuItemModel* GetButtonMenuItemAt(int index) const; virtual bool IsEnabledAt(int index) const; virtual ui::MenuModel* GetSubmenuModelAt(int index) const; virtual void HighlightChangedTo(int index); virtual void ActivatedAt(int index); virtual void MenuWillShow(); + virtual void SetMenuModelDelegate(ui::MenuModelDelegate* delegate); // views::ViewMenuDelegate implementation. Sub classes can override the method // to adjust the position of the menu. diff --git a/chrome/browser/chromeos/status/network_menu.cc b/chrome/browser/chromeos/status/network_menu.cc index 2415490..f68454e 100644 --- a/chrome/browser/chromeos/status/network_menu.cc +++ b/chrome/browser/chromeos/status/network_menu.cc @@ -279,7 +279,7 @@ bool NetworkMenu::IsItemCheckedAt(int index) const { return true; } -bool NetworkMenu::GetIconAt(int index, SkBitmap* icon) const { +bool NetworkMenu::GetIconAt(int index, SkBitmap* icon) { if (!menu_items_[index].icon.empty()) { *icon = menu_items_[index].icon; return true; diff --git a/chrome/browser/chromeos/status/network_menu.h b/chrome/browser/chromeos/status/network_menu.h index 9187799..f96d49f 100644 --- a/chrome/browser/chromeos/status/network_menu.h +++ b/chrome/browser/chromeos/status/network_menu.h @@ -99,7 +99,7 @@ class NetworkMenu : public views::ViewMenuDelegate, ui::Accelerator* accelerator) const { return false; } virtual bool IsItemCheckedAt(int index) const; virtual int GetGroupIdAt(int index) const { return 0; } - virtual bool GetIconAt(int index, SkBitmap* icon) const; + virtual bool GetIconAt(int index, SkBitmap* icon); virtual ui::ButtonMenuItemModel* GetButtonMenuItemAt(int index) const { return NULL; } @@ -108,6 +108,7 @@ class NetworkMenu : public views::ViewMenuDelegate, virtual void HighlightChangedTo(int index) {} virtual void ActivatedAt(int index); virtual void MenuWillShow() {} + virtual void SetMenuModelDelegate(ui::MenuModelDelegate* delegate) {} void SetFirstLevelMenuWidth(int width); diff --git a/chrome/browser/chromeos/status/power_menu_button.h b/chrome/browser/chromeos/status/power_menu_button.h index a839e63..709d2bc4 100644 --- a/chrome/browser/chromeos/status/power_menu_button.h +++ b/chrome/browser/chromeos/status/power_menu_button.h @@ -41,7 +41,7 @@ class PowerMenuButton : public StatusAreaButton, ui::Accelerator* accelerator) const { return false; } virtual bool IsItemCheckedAt(int index) const { return false; } virtual int GetGroupIdAt(int index) const { return 0; } - virtual bool GetIconAt(int index, SkBitmap* icon) const { return false; } + virtual bool GetIconAt(int index, SkBitmap* icon) { return false; } virtual ui::ButtonMenuItemModel* GetButtonMenuItemAt(int index) const { return NULL; } @@ -50,6 +50,7 @@ class PowerMenuButton : public StatusAreaButton, virtual void HighlightChangedTo(int index) {} virtual void ActivatedAt(int index) {} virtual void MenuWillShow() {} + virtual void SetMenuModelDelegate(ui::MenuModelDelegate* delegate) {} // PowerLibrary::Observer implementation. virtual void PowerChanged(PowerLibrary* obj); diff --git a/chrome/browser/ui/toolbar/back_forward_menu_model.cc b/chrome/browser/ui/toolbar/back_forward_menu_model.cc index c77c894..cd74736 100644 --- a/chrome/browser/ui/toolbar/back_forward_menu_model.cc +++ b/chrome/browser/ui/toolbar/back_forward_menu_model.cc @@ -22,6 +22,7 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/text/text_elider.h" +#include "ui/gfx/codec/png_codec.h" const int BackForwardMenuModel::kMaxHistoryItems = 12; const int BackForwardMenuModel::kMaxChapterStops = 5; @@ -31,7 +32,8 @@ BackForwardMenuModel::BackForwardMenuModel(Browser* browser, ModelType model_type) : browser_(browser), test_tab_contents_(NULL), - model_type_(model_type) { + model_type_(model_type), + menu_model_delegate_(NULL) { } bool BackForwardMenuModel::HasIcons() const { @@ -113,7 +115,7 @@ int BackForwardMenuModel::GetGroupIdAt(int index) const { return false; } -bool BackForwardMenuModel::GetIconAt(int index, SkBitmap* icon) const { +bool BackForwardMenuModel::GetIconAt(int index, SkBitmap* icon) { if (!ItemHasIcon(index)) return false; @@ -123,6 +125,9 @@ bool BackForwardMenuModel::GetIconAt(int index, SkBitmap* icon) const { } else { NavigationEntry* entry = GetNavigationEntry(index); *icon = entry->favicon().bitmap(); + if (!entry->favicon().is_valid() && menu_model_delegate()) { + FetchFavicon(entry); + } } return true; @@ -182,6 +187,8 @@ void BackForwardMenuModel::ActivatedAtWithDisposition( void BackForwardMenuModel::MenuWillShow() { UserMetrics::RecordComputedAction(BuildActionName("Popup", -1), browser_->profile()); + requested_favicons_.clear(); + load_consumer_.CancelAllRequests(); } bool BackForwardMenuModel::IsSeparator(int index) const { @@ -203,6 +210,71 @@ bool BackForwardMenuModel::IsSeparator(int index) const { return index == history_items; } +void BackForwardMenuModel::SetMenuModelDelegate( + ui::MenuModelDelegate* menu_model_delegate) { + menu_model_delegate_ = menu_model_delegate; +} + +void BackForwardMenuModel::FetchFavicon(NavigationEntry* entry) { + // If the favicon has already been requested for this menu, don't do + // anything. + if (requested_favicons_.find(entry->unique_id()) != + requested_favicons_.end()) { + return; + } + requested_favicons_.insert(entry->unique_id()); + FaviconService* favicon_service = + browser_->profile()->GetFaviconService(Profile::EXPLICIT_ACCESS); + if (!favicon_service) + return; + FaviconService::Handle handle = favicon_service->GetFaviconForURL( + entry->url(), history::FAVICON, &load_consumer_, + NewCallback(this, &BackForwardMenuModel::OnFavIconDataAvailable)); + load_consumer_.SetClientData(favicon_service, handle, entry->unique_id()); +} + +void BackForwardMenuModel::OnFavIconDataAvailable( + FaviconService::Handle handle, + history::FaviconData favicon) { + if (favicon.is_valid()) { + int unique_id = load_consumer_.GetClientDataForCurrentRequest(); + // Find the current model_index for the unique_id. + NavigationEntry* entry = NULL; + int model_index = -1; + for (int i = 0; i < GetItemCount() - 1; i++) { + if (IsSeparator(i)) + continue; + if (GetNavigationEntry(i)->unique_id() == unique_id) { + model_index = i; + entry = GetNavigationEntry(i); + break; + } + } + + if (!entry) + // The NavigationEntry wasn't found, this can happen if the user + // navigates to another page and a NavigatationEntry falls out of the + // range of kMaxHistoryItems. + return; + + // Now that we have a valid NavigationEntry, decode the favicon and assign + // it to the NavigationEntry. + SkBitmap fav_icon; + if (gfx::PNGCodec::Decode(favicon.image_data->front(), + favicon.image_data->size(), + &fav_icon)) { + entry->favicon().set_is_valid(true); + entry->favicon().set_url(favicon.icon_url); + if (fav_icon.empty()) + return; + entry->favicon().set_bitmap(fav_icon); + if (menu_model_delegate()) { + menu_model_delegate()->OnIconChanged(model_index); + } + } + } +} + int BackForwardMenuModel::GetHistoryItemCount() const { TabContents* contents = GetTabContents(); int items = 0; diff --git a/chrome/browser/ui/toolbar/back_forward_menu_model.h b/chrome/browser/ui/toolbar/back_forward_menu_model.h index b1bb08c..655369d 100644 --- a/chrome/browser/ui/toolbar/back_forward_menu_model.h +++ b/chrome/browser/ui/toolbar/back_forward_menu_model.h @@ -6,11 +6,13 @@ #define CHROME_BROWSER_UI_TOOLBAR_BACK_FORWARD_MENU_MODEL_H_ #pragma once +#include <set> #include <string> #include "base/basictypes.h" #include "base/gtest_prod_util.h" #include "base/string16.h" +#include "chrome/browser/favicon_service.h" #include "ui/base/models/menu_model.h" #include "webkit/glue/window_open_disposition.h" @@ -53,7 +55,7 @@ class BackForwardMenuModel : public ui::MenuModel { ui::Accelerator* accelerator) const; virtual bool IsItemCheckedAt(int index) const; virtual int GetGroupIdAt(int index) const; - virtual bool GetIconAt(int index, SkBitmap* icon) const; + virtual bool GetIconAt(int index, SkBitmap* icon); virtual ui::ButtonMenuItemModel* GetButtonMenuItemAt(int index) const; virtual bool IsEnabledAt(int index) const; virtual MenuModel* GetSubmenuModelAt(int index) const; @@ -65,7 +67,28 @@ class BackForwardMenuModel : public ui::MenuModel { // Is the item at |index| a separator? bool IsSeparator(int index) const; + // Set the delegate for triggering OnIconChanged. + virtual void SetMenuModelDelegate(ui::MenuModelDelegate* menu_model_delegate); + + protected: + ui::MenuModelDelegate* menu_model_delegate() { return menu_model_delegate_; } + private: + friend class BackFwdMenuModelTest; + FRIEND_TEST_ALL_PREFIXES(BackFwdMenuModelTest, BasicCase); + FRIEND_TEST_ALL_PREFIXES(BackFwdMenuModelTest, MaxItemsTest); + FRIEND_TEST_ALL_PREFIXES(BackFwdMenuModelTest, ChapterStops); + FRIEND_TEST_ALL_PREFIXES(BackFwdMenuModelTest, EscapeLabel); + FRIEND_TEST_ALL_PREFIXES(BackFwdMenuModelTest, FaviconLoadTest); + + // Requests a favicon from the FaviconService. Called by GetIconAt if the + // NavigationEntry has an invalid favicon. + void FetchFavicon(NavigationEntry* entry); + + // Callback from the favicon service. + void OnFavIconDataAvailable(FaviconService::Handle handle, + history::FaviconData favicon); + // Allows the unit test to use its own dummy tab contents. void set_test_tab_contents(TabContents* test_tab_contents) { test_tab_contents_ = test_tab_contents; @@ -160,11 +183,15 @@ class BackForwardMenuModel : public ui::MenuModel { // back button. ModelType model_type_; - friend class BackFwdMenuModelTest; - FRIEND_TEST_ALL_PREFIXES(BackFwdMenuModelTest, BasicCase); - FRIEND_TEST_ALL_PREFIXES(BackFwdMenuModelTest, MaxItemsTest); - FRIEND_TEST_ALL_PREFIXES(BackFwdMenuModelTest, ChapterStops); - FRIEND_TEST_ALL_PREFIXES(BackFwdMenuModelTest, EscapeLabel); + // Keeps track of which favicons have already been requested from the history + // to prevent duplicate requests, identified by NavigationEntry->unique_id(). + std::set<int> requested_favicons_; + + // Used for loading favicons from history. + CancelableRequestConsumerTSimple<int> load_consumer_; + + // Used for receiving notifications when an icon is changed. + ui::MenuModelDelegate* menu_model_delegate_; DISALLOW_COPY_AND_ASSIGN(BackForwardMenuModel); }; diff --git a/chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc b/chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc index 5e8d1d4..93a284c 100644 --- a/chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc +++ b/chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc @@ -7,14 +7,50 @@ #include "base/path_service.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" +#include "chrome/browser/history/history.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/browser.h" #include "chrome/common/url_constants.h" +#include "chrome/test/testing_profile.h" +#include "content/browser/browser_thread.h" #include "content/browser/renderer_host/test_render_view_host.h" #include "content/browser/tab_contents/navigation_controller.h" #include "content/browser/tab_contents/navigation_entry.h" #include "content/browser/tab_contents/tab_contents.h" #include "content/browser/tab_contents/test_tab_contents.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/gfx/codec/png_codec.h" + +namespace { + +// Creates a bitmap of the specified color. +SkBitmap CreateBitmap(SkColor color) { + SkBitmap bitmap; + bitmap.setConfig(SkBitmap::kARGB_8888_Config, 16, 16); + bitmap.allocPixels(); + bitmap.eraseColor(color); + return bitmap; +} + +class FaviconDelegate : public ui::MenuModelDelegate { + public: + FaviconDelegate() : was_called_(false) {} + + void OnIconChanged(int model_index) { + was_called_ = true; + MessageLoop::current()->Quit(); + } + + bool was_called() const { return was_called_; } + + private: + bool was_called_; + + DISALLOW_COPY_AND_ASSIGN(FaviconDelegate); +}; + +} // namespace class BackFwdMenuModelTest : public RenderViewHostTestHarness { public: @@ -450,3 +486,66 @@ TEST_F(BackFwdMenuModelTest, EscapeLabel) { EXPECT_EQ(ASCIIToUTF16("A &&&&&& B"), back_model->GetLabelAt(0)); #endif // defined(OS_MACOSX) } + +// Test asynchronous loading of favicon from history service. +TEST_F(BackFwdMenuModelTest, FaviconLoadTest) { + profile()->CreateHistoryService(true, false); + profile()->CreateFaviconService(); + Browser browser(Browser::TYPE_NORMAL, profile()); + FaviconDelegate favicon_delegate; + + BackForwardMenuModel back_model( + &browser, BackForwardMenuModel::BACKWARD_MENU); + back_model.set_test_tab_contents(controller().tab_contents()); + back_model.SetMenuModelDelegate(&favicon_delegate); + + SkBitmap new_icon(CreateBitmap(SK_ColorRED)); + std::vector<unsigned char> icon_data; + gfx::PNGCodec::EncodeBGRASkBitmap(new_icon, false, &icon_data); + + GURL url1 = GURL("http://www.a.com/1"); + GURL url2 = GURL("http://www.a.com/2"); + GURL url1_favicon("http://www.a.com/1/favicon.ico"); + + NavigateAndCommit(url1); + // Navigate to a new URL so that url1 will be in the BackForwardMenuModel. + NavigateAndCommit(url2); + + // Set the desired favicon for url1. + profile()->GetHistoryService(Profile::EXPLICIT_ACCESS)->AddPage(url1, + history::SOURCE_BROWSED); + profile()->GetFaviconService(Profile::EXPLICIT_ACCESS)->SetFavicon(url1, + url1_favicon, icon_data, history::FAVICON); + + // Will return the current icon (default) but start an anync call + // to retrieve the favicon from the favicon service. + SkBitmap default_icon; + back_model.GetIconAt(0, &default_icon); + + // Make the favicon service run GetFavIconForURL, + // FaviconDelegate.OnIconChanged will be called. + MessageLoop::current()->Run(); + + // Verify that the callback executed. + EXPECT_TRUE(favicon_delegate.was_called()); + + // Verify the bitmaps match. + SkBitmap valid_icon; + // This time we will get the new favicon returned. + back_model.GetIconAt(0, &valid_icon); + SkAutoLockPixels a(new_icon); + SkAutoLockPixels b(valid_icon); + SkAutoLockPixels c(default_icon); + // Verify we did not get the default favicon. + EXPECT_NE(0, memcmp(default_icon.getPixels(), valid_icon.getPixels(), + default_icon.getSize())); + // Verify we did get the expected favicon. + EXPECT_EQ(0, memcmp(new_icon.getPixels(), valid_icon.getPixels(), + new_icon.getSize())); + + // Make sure the browser deconstructor doesn't have problems. + browser.CloseAllTabs(); + // This is required to prevent the message loop from hanging. + profile()->DestroyHistoryService(); +} + diff --git a/ui/base/models/menu_model.h b/ui/base/models/menu_model.h index d838a56..9734162 100644 --- a/ui/base/models/menu_model.h +++ b/ui/base/models/menu_model.h @@ -8,6 +8,7 @@ #include "base/scoped_ptr.h" #include "base/string16.h" +#include "ui/base/models/menu_model_delegate.h" #include "ui/gfx/native_widget_types.h" class SkBitmap; @@ -85,7 +86,7 @@ class MenuModel { // Gets the icon for the item at the specified index, returning true if there // is an icon, false otherwise. - virtual bool GetIconAt(int index, SkBitmap* icon) const = 0; + virtual bool GetIconAt(int index, SkBitmap* icon) = 0; // Returns the model for a menu item with a line of buttons at |index|. virtual ButtonMenuItemModel* GetButtonMenuItemAt(int index) const = 0; @@ -116,6 +117,9 @@ class MenuModel { // Called when the menu has been closed. virtual void MenuClosed() {} + // Set the MenuModelDelegate. Owned by the caller of this function. + virtual void SetMenuModelDelegate(MenuModelDelegate* delegate) = 0; + // Retrieves the model and index that contains a specific command id. Returns // true if an item with the specified command id is found. |model| is inout, // and specifies the model to start searching from. diff --git a/ui/base/models/menu_model_delegate.h b/ui/base/models/menu_model_delegate.h new file mode 100644 index 0000000..9516e59 --- /dev/null +++ b/ui/base/models/menu_model_delegate.h @@ -0,0 +1,22 @@ +// Copyright (c) 2010 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 UI_BASE_MODELS_MENU_MODEL_DELEGATE_H_ +#define UI_BASE_MODELS_MENU_MODEL_DELEGATE_H_ +#pragma once + +namespace ui { + +class MenuModelDelegate { + public: + // Invoked when an icon has been loaded from history. + virtual void OnIconChanged(int index) = 0; + + protected: + virtual ~MenuModelDelegate() {} +}; + +} // namespace ui + +#endif // UI_BASE_MODELS_MENU_MODEL_DELEGATE_H_ diff --git a/ui/base/models/simple_menu_model.cc b/ui/base/models/simple_menu_model.cc index 6152766..28c1b01 100644 --- a/ui/base/models/simple_menu_model.cc +++ b/ui/base/models/simple_menu_model.cc @@ -54,6 +54,7 @@ void SimpleMenuModel::Delegate::MenuClosed() { SimpleMenuModel::SimpleMenuModel(Delegate* delegate) : delegate_(delegate), + menu_model_delegate_(NULL), ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { } @@ -245,7 +246,7 @@ int SimpleMenuModel::GetGroupIdAt(int index) const { return items_.at(FlipIndex(index)).group_id; } -bool SimpleMenuModel::GetIconAt(int index, SkBitmap* icon) const { +bool SimpleMenuModel::GetIconAt(int index, SkBitmap* icon) { if (IsItemDynamicAt(index)) return delegate_->GetIconForCommandId(GetCommandIdAt(index), icon); @@ -299,6 +300,11 @@ void SimpleMenuModel::MenuClosed() { method_factory_.NewRunnableMethod(&SimpleMenuModel::OnMenuClosed)); } +void SimpleMenuModel::SetMenuModelDelegate( + ui::MenuModelDelegate* menu_model_delegate) { + menu_model_delegate_ = menu_model_delegate; +} + void SimpleMenuModel::OnMenuClosed() { if (delegate_) delegate_->MenuClosed(); diff --git a/ui/base/models/simple_menu_model.h b/ui/base/models/simple_menu_model.h index 32490ad..59b752f 100644 --- a/ui/base/models/simple_menu_model.h +++ b/ui/base/models/simple_menu_model.h @@ -112,7 +112,7 @@ class SimpleMenuModel : public MenuModel { ui::Accelerator* accelerator) const; virtual bool IsItemCheckedAt(int index) const; virtual int GetGroupIdAt(int index) const; - virtual bool GetIconAt(int index, SkBitmap* icon) const; + virtual bool GetIconAt(int index, SkBitmap* icon); virtual ui::ButtonMenuItemModel* GetButtonMenuItemAt(int index) const; virtual bool IsEnabledAt(int index) const; virtual bool IsVisibleAt(int index) const; @@ -120,6 +120,7 @@ class SimpleMenuModel : public MenuModel { virtual void ActivatedAt(int index); virtual MenuModel* GetSubmenuModelAt(int index) const; virtual void MenuClosed(); + virtual void SetMenuModelDelegate(ui::MenuModelDelegate* menu_model_delegate); protected: // Some variants of this model (SystemMenuModel) relies on items to be @@ -131,6 +132,8 @@ class SimpleMenuModel : public MenuModel { Delegate* delegate() { return delegate_; } + MenuModelDelegate* menu_model_delegate() { return menu_model_delegate_; } + private: struct Item; @@ -146,6 +149,8 @@ class SimpleMenuModel : public MenuModel { Delegate* delegate_; + MenuModelDelegate* menu_model_delegate_; + ScopedRunnableMethodFactory<SimpleMenuModel> method_factory_; DISALLOW_COPY_AND_ASSIGN(SimpleMenuModel); diff --git a/views/view_unittest.cc b/views/view_unittest.cc index 2bded07..428f320 100644 --- a/views/view_unittest.cc +++ b/views/view_unittest.cc @@ -1232,7 +1232,7 @@ class MockMenuModel : public MenuModel { ui::Accelerator* accelerator)); MOCK_CONST_METHOD1(IsItemCheckedAt, bool(int index)); MOCK_CONST_METHOD1(GetGroupIdAt, int(int index)); - MOCK_CONST_METHOD2(GetIconAt, bool(int index, SkBitmap* icon)); + MOCK_METHOD2(GetIconAt, bool(int index, SkBitmap* icon)); MOCK_CONST_METHOD1(GetButtonMenuItemAt, ButtonMenuItemModel*(int index)); MOCK_CONST_METHOD1(IsEnabledAt, bool(int index)); MOCK_CONST_METHOD1(IsVisibleAt, bool(int index)); @@ -1243,6 +1243,7 @@ class MockMenuModel : public MenuModel { int disposition)); MOCK_METHOD0(MenuWillShow, void()); MOCK_METHOD0(MenuClosed, void()); + MOCK_METHOD1(SetMenuModelDelegate, void(MenuModelDelegate* delegate)); MOCK_METHOD3(GetModelAndIndexForCommandId, bool(int command_id, MenuModel** model, int* index)); }; |