12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef CHROME_BROWSER_UI_TOOLBAR_RECENT_TABS_SUB_MENU_MODEL_H_ 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CHROME_BROWSER_UI_TOOLBAR_RECENT_TABS_SUB_MENU_MODEL_H_ 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <set> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/weak_ptr.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/task/cancelable_task_tracker.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/favicon/favicon_service.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sessions/tab_restore_service.h" 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/sessions/tab_restore_service_observer.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sync/glue/synced_session.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/accelerators/accelerator.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/models/simple_menu_model.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class Browser; 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct SessionTab; 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace browser_sync { 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class OpenTabsUIDelegate; 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace favicon_base { 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)struct FaviconImageResult; 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace gfx { 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class Image; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ui { 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AcceleratorProvider; 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A menu model that builds the contents of "Recent tabs" submenu, which include 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// the recently closed tabs/windows of current device i.e. local entries, and 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// opened tabs of other devices. 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RecentTabsSubMenuModel : public ui::SimpleMenuModel, 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public ui::SimpleMenuModel::Delegate, 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public TabRestoreServiceObserver { 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Command Id for recently closed items header or disabled item to which the 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // accelerator string will be appended. 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static const int kRecentlyClosedHeaderCommandId; 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static const int kDisabledRecentlyClosedHeaderCommandId; 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Exposed for tests only: return the Command Id for the first entry in the 515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // recently closed window items list. 525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu static int GetFirstRecentTabsCommandId(); 535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If |open_tabs_delegate| is NULL, the default delegate for |browser|'s 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // profile will be used. Testing may require a specific |open_tabs_delegate|. 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecentTabsSubMenuModel(ui::AcceleratorProvider* accelerator_provider, 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser, 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser_sync::OpenTabsUIDelegate* open_tabs_delegate); 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~RecentTabsSubMenuModel(); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Overridden from ui::SimpleMenuModel::Delegate: 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool IsCommandIdChecked(int command_id) const OVERRIDE; 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool GetAcceleratorForCommandId( 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int command_id, 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::Accelerator* accelerator) OVERRIDE; 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE; 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual const gfx::FontList* GetLabelFontListAt(int index) const OVERRIDE; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int GetMaxWidthForItemAtIndex(int item_index) const; 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool GetURLAndTitleForItemAtIndex(int index, 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string* url, 73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16* title); 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) struct TabNavigationItem; 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) typedef std::vector<TabNavigationItem> TabNavigationItems; 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) typedef std::vector<SessionID::id_type> WindowItems; 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Build the menu items by populating the menumodel. 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Build(); 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Build the recently closed tabs and windows items. 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void BuildLocalEntries(); 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Build the tabs items from other devices. 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void BuildTabsFromOtherDevices(); 894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Build a recently closed tab item with parameters needed to restore it, and 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // add it to the menumodel at |curr_model_index|. 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void BuildLocalTabItem(int seesion_id, 93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& title, 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const GURL& url, 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int curr_model_index); 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Build the recently closed window item with parameters needed to restore it, 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // and add it to the menumodel at |curr_model_index|. 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void BuildLocalWindowItem(const SessionID::id_type& window_id, 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int num_tabs, 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int curr_model_index); 1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Build the tab item for other devices with parameters needed to restore it. 1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void BuildOtherDevicesTabItem(const std::string& session_tag, 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const SessionTab& tab); 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Add the favicon for the device section header. 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void AddDeviceFavicon(int index_in_menu, 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser_sync::SyncedSession::DeviceType device_type); 1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Add the favicon for a local or other devices' tab asynchronously, 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // OnFaviconDataAvailable() will be invoked when the favicon is ready. 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void AddTabFavicon(int command_id, const GURL& url); 1140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch void OnFaviconDataAvailable( 1150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int command_id, 1160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const favicon_base::FaviconImageResult& image_result); 1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Clear all recently closed tabs and windows. 1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void ClearLocalEntries(); 1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Converts |command_id| of menu item to index in local or other devices' 1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // TabNavigationItems, and returns the corresponding local or other devices' 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // TabNavigationItems in |tab_items|. 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int CommandIdToTabVectorIndex(int command_id, TabNavigationItems** tab_items); 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Used to access (and lazily initialize) open_tabs_delegate_. 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(tim): This lazy-init for member variables is error prone because you 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // can always skip going through the function and access the field directly. 129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Consider instead having code just deal with potentially NULL open_tabs_ 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // and have it initialized by an event / callback. 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser_sync::OpenTabsUIDelegate* GetOpenTabsUIDelegate(); 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Overridden from TabRestoreServiceObserver: 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void TabRestoreServiceChanged(TabRestoreService* service) OVERRIDE; 1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void TabRestoreServiceDestroyed(TabRestoreService* service) OVERRIDE; 1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser_; // Weak. 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser_sync::OpenTabsUIDelegate* open_tabs_delegate_; // Weak. 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Accelerator for reopening last closed tab. 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::Accelerator reopen_closed_tab_accelerator_; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Navigation items for local recently closed tabs. The |command_id| for 1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // these is set to |kFirstLocalTabCommandId| plus the index into the vector. 1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Upon invocation of the menu, the navigation information is retrieved from 1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // |local_tab_navigation_items_| and used to navigate to the item specified. 1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TabNavigationItems local_tab_navigation_items_; 1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Similar to |local_tab_navigation_items_| except the tabs are opened tabs 1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // from other devices, and the first |command_id| is 1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // |kFirstOtherDevicesTabCommandId|. 1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TabNavigationItems other_devices_tab_navigation_items_; 1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Window items for local recently closed windows. The |command_id| for 1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // these is set to |kFirstLocalWindowCommandId| plus the index into the 1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // vector. Upon invocation of the menu, information is retrieved from 1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // |local_window_items_| and used to create the specified window. 1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WindowItems local_window_items_; 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Index of the last local entry (recently closed tab or window) in the 1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // menumodel. 1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int last_local_model_index_; 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Image default_favicon_; 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::CancelableTaskTracker local_tab_cancelable_task_tracker_; 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::CancelableTaskTracker other_devices_tab_cancelable_task_tracker_; 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtrFactory<RecentTabsSubMenuModel> weak_ptr_factory_; 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(RecentTabsSubMenuModel); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // CHROME_BROWSER_UI_TOOLBAR_RECENT_TABS_SUB_MENU_MODEL_H_ 176