Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8657)

Unified Diff: chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.cc

Issue 23530070: backup for dynamic recent tabs submenu (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: new RecentTabsMenuModelDelegate w/ new intf Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.cc
diff --git a/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.cc b/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.cc
index 0ab3291188a7d7226e938272c0ed03b7daf2ff2c..33a24ffd96f6b3d58b3d9236c8ce576ee90154bb 100644
--- a/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.cc
+++ b/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.cc
@@ -41,22 +41,26 @@
namespace {
-// First comamnd id for navigatable (and hence executable) tab menu item.
+// First comamnd id for navigatable (and hence executable) tab/window menu item.
// The models and menu are not 1-1:
-// - menu has "Reopen closed tab", "No tabs from other devices", device section
-// headers, separators and executable tab items.
-// - |tab_navigation_items_| only has navigatabale/executable tab items.
-// - |window_items_| only has executable open window items.
-// Using an initial command ids for tab/window items makes it easier and less
-// error-prone to manipulate the models and menu.
-// These values must be bigger than the maximum possible number of items in
-// menu, so that index of last menu item doesn't clash with this value when menu
-// items are retrieved via GetIndexOfCommandId.
-const int kFirstTabCommandId = 100;
-const int kFirstWindowCommandId = 200;
-
-// The maximum number of recently closed entries to be shown in the menu.
-const int kMaxRecentlyClosedEntries = 8;
+// - menu has "Recently closed" header, "No tabs from other devices", device
+// section headers, separators, executable local and foreign tab items, and
+// executable local window items.
+// - |local_tab_navigation_items_| and |foreign_tab_navigation_items_| only have
+// navigatabale/executable tab items.
+// - |local_window_items_| only has executable open window items.
+// Using initial command ids for local tab, local window and foreign tab items
+// makes it easier and less error-prone to manipulate the models, data vectors
+// and menu. These ids must be bigger than the maximum possible number of
+// items in menu, so that index of the last menu item doesn't clash with these
+// values when menu items are retrieved via GetIndexOfCommandId.
+const int kFirstLocalTabCommandId = 100;
+const int kFirstLocalWindowCommandId = 200;
+const int kFirstForeignTabCommandId = 300;
+
+// The maximum number of local recently closed entries (tab or window) to be
+// shown in the menu.
+const int kMaxLocalEntries = 8;
// Comparator function for use with std::sort that will sort sessions by
// descending modified_time (i.e., most recent first).
@@ -71,43 +75,42 @@ bool SortTabsByRecency(const SessionTab* t1, const SessionTab* t2) {
return t1->timestamp > t2->timestamp;
}
-// Returns true if the command id is related to a tab model index.
+// Returns true if the command id identifies a tab model index.
bool IsTabModelCommandId(int command_id) {
- return command_id >= kFirstTabCommandId && command_id < kFirstWindowCommandId;
+ return command_id >= kFirstForeignTabCommandId ||
+ (command_id >= kFirstLocalTabCommandId &&
+ command_id < kFirstLocalWindowCommandId);
}
-// Returns true if the command id is related to a window model index.
+// Returns true if the command id identifies a window model index.
bool IsWindowModelCommandId(int command_id) {
- return command_id >= kFirstWindowCommandId &&
+ return command_id >= kFirstLocalWindowCommandId &&
command_id < RecentTabsSubMenuModel::kRecentlyClosedHeaderCommandId;
}
-// Convert |tab_model_index| to command id of menu item.
-int TabModelIndexToCommandId(int tab_model_index) {
- int command_id = tab_model_index + kFirstTabCommandId;
- DCHECK_LT(command_id, kFirstWindowCommandId);
+// Convert |tab_model_index| to command id of menu item, with |first_command_id|
+// as the base command id.
+int TabModelIndexToCommandId(int tab_model_index, int first_command_id) {
+ int command_id = tab_model_index + first_command_id;
+ DCHECK(first_command_id == kFirstForeignTabCommandId ||
+ command_id < kFirstLocalWindowCommandId);
return command_id;
}
-// Convert |command_id| of menu item to index in tab model.
-int CommandIdToTabModelIndex(int command_id) {
- DCHECK_GE(command_id, kFirstTabCommandId);
- DCHECK_LT(command_id, kFirstWindowCommandId);
- return command_id - kFirstTabCommandId;
-}
-
// Convert |window_model_index| to command id of menu item.
int WindowModelIndexToCommandId(int window_model_index) {
- int command_id = window_model_index + kFirstWindowCommandId;
+ int command_id = window_model_index + kFirstLocalWindowCommandId;
+ DCHECK_LT(command_id, kFirstForeignTabCommandId);
DCHECK_LT(command_id, RecentTabsSubMenuModel::kRecentlyClosedHeaderCommandId);
return command_id;
}
// Convert |command_id| of menu item to index in window model.
int CommandIdToWindowModelIndex(int command_id) {
- DCHECK_GE(command_id, kFirstWindowCommandId);
+ DCHECK_GE(command_id, kFirstLocalWindowCommandId);
+ DCHECK_LT(command_id, kFirstForeignTabCommandId);
DCHECK_LT(command_id, RecentTabsSubMenuModel::kRecentlyClosedHeaderCommandId);
- return command_id - kFirstWindowCommandId;
+ return command_id - kFirstLocalWindowCommandId;
}
} // namespace
@@ -120,7 +123,8 @@ enum RecentTabAction {
LIMIT_RECENT_TAB_ACTION
};
-// An element in |RecentTabsSubMenuModel::tab_navigation_items_| that stores
+// An element in |RecentTabsSubMenuModel::local_tab_navigation_items_| or
+// |RecentTabsSubMenuModel::foreign_tab_navigation_items_| that stores
// the navigation information of a local or foreign tab required to restore the
// tab.
struct RecentTabsSubMenuModel::TabNavigationItem {
@@ -157,9 +161,26 @@ RecentTabsSubMenuModel::RecentTabsSubMenuModel(
: ui::SimpleMenuModel(this),
browser_(browser),
associator_(associator),
+ last_local_model_index_(-1),
default_favicon_(ResourceBundle::GetSharedInstance().
GetNativeImageNamed(IDR_DEFAULT_FAVICON)),
weak_ptr_factory_(this) {
+ // Invoke asynchronous call to load tabs from local last session, which does
+ // nothing if the tabs have already been loaded or they shouldn't be loaded.
+ // TabRestoreServiceChanged() will be called after the tabs are loaded.
+ TabRestoreService* service =
+ TabRestoreServiceFactory::GetForProfile(browser_->profile());
+ if (service) {
+ service->LoadTabsFromLastSession();
+
+// TODO(sail): enable this when mac implements the dynamic menu, together with
+// MenuModelDelegate::PrepareChange, OnItemRemoved, OnItemAdded and ChangesDone.
+#if !defined(OS_MACOSX)
+ service->AddObserver(this);
+#endif
+ }
+
+ // Build the menu.
Build();
// Retrieve accelerator key for IDC_RESTORE_TAB now, because on ASH, it's not
@@ -183,6 +204,29 @@ RecentTabsSubMenuModel::RecentTabsSubMenuModel(
}
RecentTabsSubMenuModel::~RecentTabsSubMenuModel() {
+ TabRestoreService* service =
+ TabRestoreServiceFactory::GetForProfile(browser_->profile());
+ if (service)
+ service->RemoveObserver(this);
+}
+
+int RecentTabsSubMenuModel::ModelIndexToIdInParentMenu(int model_index) const {
+ // If |model_index| identifies a local tab/window menu item, return as is;
+ // otherwise, reserve enough id's for maximum possible local entries.
+ if (model_index <= last_local_model_index_)
+ return model_index;
+ return model_index + kMaxLocalEntries - last_local_model_index_;
+}
+
+int RecentTabsSubMenuModel::IdInParentMenuToModelIndex(
+ int id_in_parent_menu) const {
+ // If |id_in_parent_menu| identifies a local tab/window menu item, return as
+ // is; otherwise, ModelIndexToIdInParentMenu() would have reserved enough Id's
+ // for maximum possible local entries, so reverse that logic.
+ int index = id_in_parent_menu <= last_local_model_index_ ? id_in_parent_menu :
+ id_in_parent_menu - kMaxLocalEntries + last_local_model_index_;
+ DCHECK(index >= 0 && index < GetItemCount());
+ return index;
}
bool RecentTabsSubMenuModel::IsCommandIdChecked(int command_id) const {
@@ -238,10 +282,9 @@ void RecentTabsSubMenuModel::ExecuteCommand(int command_id, int event_flags) {
TabRestoreServiceDelegate::FindDelegateForWebContents(
browser_->tab_strip_model()->GetActiveWebContents());
if (IsTabModelCommandId(command_id)) {
- int model_idx = CommandIdToTabModelIndex(command_id);
- DCHECK(model_idx >= 0 &&
- model_idx < static_cast<int>(tab_navigation_items_.size()));
- const TabNavigationItem& item = tab_navigation_items_[model_idx];
+ TabNavigationItems* tab_items = NULL;
+ int model_idx = CommandIdToTabModelIndex(command_id, &tab_items);
+ const TabNavigationItem& item = tab_items->at(model_idx);
DCHECK(item.tab_id > -1 && item.url.is_valid());
if (item.session_tag.empty()) { // Restore tab of local session.
@@ -271,10 +314,10 @@ void RecentTabsSubMenuModel::ExecuteCommand(int command_id, int event_flags) {
if (service && delegate) {
int model_idx = CommandIdToWindowModelIndex(command_id);
DCHECK(model_idx >= 0 &&
- model_idx < static_cast<int>(window_items_.size()));
+ model_idx < static_cast<int>(local_window_items_.size()));
UMA_HISTOGRAM_ENUMERATION("WrenchMenu.RecentTabsSubMenu", RESTORE_WINDOW,
LIMIT_RECENT_TAB_ACTION);
- service->RestoreEntryById(delegate, window_items_[model_idx],
+ service->RestoreEntryById(delegate, local_window_items_[model_idx],
browser_->host_desktop_type(), disposition);
}
}
@@ -300,17 +343,15 @@ int RecentTabsSubMenuModel::GetMaxWidthForItemAtIndex(int item_index) const {
return 320;
}
-bool RecentTabsSubMenuModel::GetURLAndTitleForItemAtIndex(
- int index,
- std::string* url,
- string16* title) const {
+bool RecentTabsSubMenuModel::GetURLAndTitleForItemAtIndex(int index,
+ std::string* url,
+ string16* title) {
int command_id = GetCommandIdAt(index);
if (IsTabModelCommandId(command_id)) {
- int model_idx = CommandIdToTabModelIndex(command_id);
- DCHECK(model_idx >= 0 &&
- model_idx < static_cast<int>(tab_navigation_items_.size()));
- *url = tab_navigation_items_[model_idx].url.possibly_invalid_spec();
- *title = tab_navigation_items_[model_idx].title;
+ TabNavigationItems* tab_items = NULL;
+ int model_idx = CommandIdToTabModelIndex(command_id, &tab_items);
+ *url = tab_items->at(model_idx).url.possibly_invalid_spec();
+ *title = tab_items->at(model_idx).title;
return true;
}
return false;
@@ -318,66 +359,81 @@ bool RecentTabsSubMenuModel::GetURLAndTitleForItemAtIndex(
void RecentTabsSubMenuModel::Build() {
// The menu contains:
- // - Recently closed tabs header, then list of tabs, then separator
+ // - Recently closed header, then list of local recently closed tabs/windows,
+ // then separator
// - device 1 section header, then list of tabs from device, then separator
// - device 2 section header, then list of tabs from device, then separator
// - device 3 section header, then list of tabs from device, then separator
// - More... to open the history tab to get more other devices.
- // |tab_navigation_items_| only contains navigatable (and hence executable)
- // tab items for other devices, and |window_items_| contains the recently
- // closed windows.
- BuildRecentTabs();
- BuildDevices();
+ // |local_tab_navigation_items_| and |foreign_tab_navigation_items_| only
+ // contain navigatable (and hence executable) tab items for local recently
+ // closed tabs and tabs of other devices respectively.
+ // |local_window_items_| contains the local recently closed windows.
+ BuildLocalEntries();
+ BuildForeignTabs();
}
-void RecentTabsSubMenuModel::BuildRecentTabs() {
- ListValue recently_closed_list;
+void RecentTabsSubMenuModel::BuildLocalEntries() {
+ // All local items use InsertItem*At() to append or insert a menu item.
+ // We're appending if building the entries for the first time i.e. invoked
+ // from Constructor(), inserting when local entries change subsequently i.e.
+ // invoked from TabRestoreServiceChanged().
+
+ int curr_model_index = 0;
+
TabRestoreService* service =
TabRestoreServiceFactory::GetForProfile(browser_->profile());
- if (service) {
- // This does nothing if the tabs have already been loaded or they
- // shouldn't be loaded.
- service->LoadTabsFromLastSession();
- }
-
if (!service || service->entries().size() == 0) {
// This is to show a disabled restore tab entry with the accelerator to
// teach users about this command.
- AddItemWithStringId(kDisabledRecentlyClosedHeaderCommandId,
- IDS_NEW_TAB_RECENTLY_CLOSED);
- return;
- }
-
- AddItemWithStringId(kRecentlyClosedHeaderCommandId,
- IDS_NEW_TAB_RECENTLY_CLOSED);
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- SetIcon(GetItemCount() - 1,
- rb.GetNativeImageNamed(IDR_RECENTLY_CLOSED_WINDOW));
-
- int added_count = 0;
- TabRestoreService::Entries entries = service->entries();
- for (TabRestoreService::Entries::const_iterator it = entries.begin();
- it != entries.end() && added_count < kMaxRecentlyClosedEntries; ++it) {
- TabRestoreService::Entry* entry = *it;
- if (entry->type == TabRestoreService::TAB) {
- TabRestoreService::Tab* tab = static_cast<TabRestoreService::Tab*>(entry);
- const sessions::SerializedNavigationEntry& current_navigation =
- tab->navigations.at(tab->current_navigation_index);
- BuildLocalTabItem(
- entry->id,
- current_navigation.title(),
- current_navigation.virtual_url());
- } else {
- DCHECK_EQ(entry->type, TabRestoreService::WINDOW);
- BuildWindowItem(
- entry->id,
- static_cast<TabRestoreService::Window*>(entry)->tabs.size());
+ InsertItemWithStringIdAt(curr_model_index++,
+ kDisabledRecentlyClosedHeaderCommandId,
+ IDS_NEW_TAB_RECENTLY_CLOSED);
+ } else {
+ InsertItemWithStringIdAt(curr_model_index,
+ kRecentlyClosedHeaderCommandId,
+ IDS_NEW_TAB_RECENTLY_CLOSED);
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ SetIcon(curr_model_index,
+ rb.GetNativeImageNamed(IDR_RECENTLY_CLOSED_WINDOW));
+ ++curr_model_index;
+
+ int added_count = 0;
+ TabRestoreService::Entries entries = service->entries();
+ for (TabRestoreService::Entries::const_iterator it = entries.begin();
+ it != entries.end() && added_count < kMaxLocalEntries; ++it) {
+ TabRestoreService::Entry* entry = *it;
+ if (entry->type == TabRestoreService::TAB) {
+ TabRestoreService::Tab* tab =
+ static_cast<TabRestoreService::Tab*>(entry);
+ const sessions::SerializedNavigationEntry& current_navigation =
+ tab->navigations.at(tab->current_navigation_index);
+ BuildLocalTabItem(
+ entry->id,
+ current_navigation.title(),
+ current_navigation.virtual_url(),
+ curr_model_index);
+ } else {
+ DCHECK_EQ(entry->type, TabRestoreService::WINDOW);
+ BuildLocalWindowItem(
+ entry->id,
+ static_cast<TabRestoreService::Window*>(entry)->tabs.size(),
+ curr_model_index);
+ }
+ ++added_count;
+ ++curr_model_index;
}
- ++added_count;
}
+
+ DCHECK_GT(curr_model_index, 0);
+ last_local_model_index_ = curr_model_index - 1;
}
-void RecentTabsSubMenuModel::BuildDevices() {
+void RecentTabsSubMenuModel::BuildForeignTabs() {
+ // All foreign items (device headers or tabs) use AddItem*() to append a menu
+ // item, because they are always only built once (i.e. invoked from
+ // Constructor()) and don't change after that.
+
browser_sync::SessionModelAssociator* associator = GetModelAssociator();
std::vector<const browser_sync::SyncedSession*> sessions;
if (!associator || !associator->GetAllForeignSessions(&sessions)) {
@@ -451,50 +507,56 @@ void RecentTabsSubMenuModel::BuildDevices() {
AddItemWithStringId(IDC_SHOW_HISTORY, IDS_RECENT_TABS_MORE);
}
-void RecentTabsSubMenuModel::BuildLocalTabItem(
- int session_id,
- const string16& title,
- const GURL& url) {
+void RecentTabsSubMenuModel::BuildLocalTabItem(int session_id,
+ const string16& title,
+ const GURL& url,
+ int curr_model_index) {
TabNavigationItem item("", session_id, title, url);
- int command_id = TabModelIndexToCommandId(tab_navigation_items_.size());
+ int command_id = TabModelIndexToCommandId(
+ local_tab_navigation_items_.size(), kFirstLocalTabCommandId);
+ // See comments in BuildLocalEntries() about usage of InsertItem*At().
// There may be no tab title, in which case, use the url as tab title.
- AddItem(command_id, title.empty() ? UTF8ToUTF16(item.url.spec()) : title);
- AddTabFavicon(tab_navigation_items_.size(), command_id, item.url);
- tab_navigation_items_.push_back(item);
+ InsertItemAt(curr_model_index, command_id,
+ title.empty() ? UTF8ToUTF16(item.url.spec()) : title);
+ AddTabFavicon(command_id, item.url);
+ local_tab_navigation_items_.push_back(item);
}
-void RecentTabsSubMenuModel::BuildForeignTabItem(
- const std::string& session_tag,
- const SessionTab& tab) {
+void RecentTabsSubMenuModel::BuildLocalWindowItem(
+ const SessionID::id_type& window_id,
+ int num_tabs,
+ int curr_model_index) {
+ int command_id = WindowModelIndexToCommandId(local_window_items_.size());
+ // See comments in BuildLocalEntries() about usage of InsertItem*At().
+ if (num_tabs == 1) {
+ InsertItemWithStringIdAt(curr_model_index, command_id,
+ IDS_NEW_TAB_RECENTLY_CLOSED_WINDOW_SINGLE);
+ } else {
+ InsertItemAt(curr_model_index, command_id, l10n_util::GetStringFUTF16(
+ IDS_NEW_TAB_RECENTLY_CLOSED_WINDOW_MULTIPLE,
+ base::IntToString16(num_tabs)));
+ }
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ SetIcon(curr_model_index, rb.GetNativeImageNamed(IDR_RECENTLY_CLOSED_WINDOW));
+ local_window_items_.push_back(window_id);
+}
+
+void RecentTabsSubMenuModel::BuildForeignTabItem(const std::string& session_tag,
+ const SessionTab& tab) {
const sessions::SerializedNavigationEntry& current_navigation =
tab.navigations.at(tab.normalized_navigation_index());
TabNavigationItem item(session_tag, tab.tab_id.id(),
current_navigation.title(),
current_navigation.virtual_url());
- int command_id = TabModelIndexToCommandId(tab_navigation_items_.size());
+ int command_id = TabModelIndexToCommandId(
+ foreign_tab_navigation_items_.size(), kFirstForeignTabCommandId);
+ // See comments in BuildForeignTabs() about usage of AddItem*().
// There may be no tab title, in which case, use the url as tab title.
AddItem(command_id,
current_navigation.title().empty() ?
UTF8ToUTF16(item.url.spec()) : current_navigation.title());
- AddTabFavicon(tab_navigation_items_.size(), command_id, item.url);
- tab_navigation_items_.push_back(item);
-}
-
-void RecentTabsSubMenuModel::BuildWindowItem(
- const SessionID::id_type& window_id,
- int num_tabs) {
- int command_id = WindowModelIndexToCommandId(window_items_.size());
- if (num_tabs == 1) {
- AddItemWithStringId(command_id, IDS_NEW_TAB_RECENTLY_CLOSED_WINDOW_SINGLE);
- } else {
- AddItem(command_id, l10n_util::GetStringFUTF16(
- IDS_NEW_TAB_RECENTLY_CLOSED_WINDOW_MULTIPLE,
- base::IntToString16(num_tabs)));
- }
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- SetIcon(GetItemCount() - 1,
- rb.GetNativeImageNamed(IDR_RECENTLY_CLOSED_WINDOW));
- window_items_.push_back(window_id);
+ AddTabFavicon(command_id, item.url);
+ foreign_tab_navigation_items_.push_back(item);
}
void RecentTabsSubMenuModel::AddDeviceFavicon(
@@ -524,9 +586,7 @@ void RecentTabsSubMenuModel::AddDeviceFavicon(
SetIcon(index_in_menu, rb.GetNativeImageNamed(favicon_id));
}
-void RecentTabsSubMenuModel::AddTabFavicon(int model_index,
- int command_id,
- const GURL& url) {
+void RecentTabsSubMenuModel::AddTabFavicon(int command_id, const GURL& url) {
int index_in_menu = GetIndexOfCommandId(command_id);
// If tab has synced favicon, use it.
@@ -537,9 +597,8 @@ void RecentTabsSubMenuModel::AddTabFavicon(int model_index,
scoped_refptr<base::RefCountedMemory> favicon_png;
if (associator &&
associator->GetSyncedFaviconForPageURL(url.spec(), &favicon_png)) {
- gfx::Image image = gfx::Image::CreateFrom1xPNGBytes(
- favicon_png->front(),
- favicon_png->size());
+ gfx::Image image = gfx::Image::CreateFrom1xPNGBytes(favicon_png->front(),
+ favicon_png->size());
SetIcon(index_in_menu, image);
return;
}
@@ -561,7 +620,9 @@ void RecentTabsSubMenuModel::AddTabFavicon(int model_index,
base::Bind(&RecentTabsSubMenuModel::OnFaviconDataAvailable,
weak_ptr_factory_.GetWeakPtr(),
command_id),
- &cancelable_task_tracker_);
+ command_id >= kFirstForeignTabCommandId ?
+ &foreign_tab_cancelable_task_tracker_ :
+ &local_tab_cancelable_task_tracker_);
}
void RecentTabsSubMenuModel::OnFaviconDataAvailable(
@@ -569,14 +630,41 @@ void RecentTabsSubMenuModel::OnFaviconDataAvailable(
const chrome::FaviconImageResult& image_result) {
if (image_result.image.IsEmpty())
return;
- DCHECK(!tab_navigation_items_.empty());
int index_in_menu = GetIndexOfCommandId(command_id);
- DCHECK(index_in_menu != -1);
+ DCHECK_GT(index_in_menu, -1);
SetIcon(index_in_menu, image_result.image);
if (GetMenuModelDelegate())
GetMenuModelDelegate()->OnIconChanged(index_in_menu);
}
+int RecentTabsSubMenuModel::CommandIdToTabModelIndex(
+ int command_id, TabNavigationItems** tab_items) {
+ if (command_id >= kFirstForeignTabCommandId) {
+ *tab_items = &foreign_tab_navigation_items_;
+ return command_id - kFirstForeignTabCommandId;
+ }
+ DCHECK_GE(command_id, kFirstLocalTabCommandId);
+ DCHECK_LT(command_id, kFirstLocalWindowCommandId);
+ *tab_items = &local_tab_navigation_items_;
+ return command_id - kFirstLocalTabCommandId;
+}
+
+void RecentTabsSubMenuModel::ClearLocalEntries() {
+ // Remove local items (recent tabs and windows) from model.
+ while (last_local_model_index_ >= 0)
+ RemoveItemAt(last_local_model_index_--);
+
+ // Cancel asynchronous FaviconService::GetFaviconImageForURL() tasks of all
+ // local tabs.
+ local_tab_cancelable_task_tracker_.TryCancelAll();
+
+ // Remove all local tab navigation items.
+ local_tab_navigation_items_.clear();
+
+ // Remove all local window items.
+ local_window_items_.clear();
+}
+
browser_sync::SessionModelAssociator*
RecentTabsSubMenuModel::GetModelAssociator() {
if (!associator_) {
@@ -588,3 +676,33 @@ browser_sync::SessionModelAssociator*
}
return associator_;
}
+
+void RecentTabsSubMenuModel::TabRestoreServiceChanged(
+ TabRestoreService* service) {
+ ui::MenuModelDelegate* menu_model_delegate = GetMenuModelDelegate();
+ if (menu_model_delegate) {
+ menu_model_delegate->PrepareForChange();
+
+ // Notify delegate to remove all local entries from the menu; do so in
+ // decreasing order so that indexes of remaining items don't change.
+ for (int i = last_local_model_index_; i >=0; --i)
+ menu_model_delegate->OnItemRemoved(i);
+ }
+
+ ClearLocalEntries();
+
+ BuildLocalEntries();
+
+ if (menu_model_delegate) {
+ // Notify delegate to add the new local entries to the menu.
+ for (int i = 0; i <= last_local_model_index_; ++i)
+ menu_model_delegate->OnItemAdded(i);
+
+ menu_model_delegate->ChangesDone();
+ }
+}
+
+void RecentTabsSubMenuModel::TabRestoreServiceDestroyed(
+ TabRestoreService* service) {
+ TabRestoreServiceChanged(service);
+}

Powered by Google App Engine
This is Rietveld 408576698