1// Copyright 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef CHROME_BROWSER_UI_TOOLBAR_RECENT_TABS_SUB_MENU_MODEL_H_ 6#define CHROME_BROWSER_UI_TOOLBAR_RECENT_TABS_SUB_MENU_MODEL_H_ 7 8#include <set> 9 10#include "base/memory/weak_ptr.h" 11#include "base/task/cancelable_task_tracker.h" 12#include "chrome/browser/favicon/favicon_service.h" 13#include "chrome/browser/sessions/tab_restore_service.h" 14#include "chrome/browser/sessions/tab_restore_service_observer.h" 15#include "chrome/browser/sync/glue/synced_session.h" 16#include "ui/base/accelerators/accelerator.h" 17#include "ui/base/models/simple_menu_model.h" 18 19class Browser; 20struct SessionTab; 21 22namespace browser_sync { 23class OpenTabsUIDelegate; 24} 25 26namespace favicon_base { 27struct FaviconImageResult; 28} 29 30namespace gfx { 31class Image; 32} 33 34namespace ui { 35class AcceleratorProvider; 36} 37 38// A menu model that builds the contents of "Recent tabs" submenu, which include 39// the recently closed tabs/windows of current device i.e. local entries, and 40// opened tabs of other devices. 41class RecentTabsSubMenuModel : public ui::SimpleMenuModel, 42 public ui::SimpleMenuModel::Delegate, 43 public TabRestoreServiceObserver { 44 public: 45 // Command Id for recently closed items header or disabled item to which the 46 // accelerator string will be appended. 47 static const int kRecentlyClosedHeaderCommandId; 48 static const int kDisabledRecentlyClosedHeaderCommandId; 49 50 // Exposed for tests only: return the Command Id for the first entry in the 51 // recently closed window items list. 52 static int GetFirstRecentTabsCommandId(); 53 54 // If |open_tabs_delegate| is NULL, the default delegate for |browser|'s 55 // profile will be used. Testing may require a specific |open_tabs_delegate|. 56 RecentTabsSubMenuModel(ui::AcceleratorProvider* accelerator_provider, 57 Browser* browser, 58 browser_sync::OpenTabsUIDelegate* open_tabs_delegate); 59 virtual ~RecentTabsSubMenuModel(); 60 61 // Overridden from ui::SimpleMenuModel::Delegate: 62 virtual bool IsCommandIdChecked(int command_id) const OVERRIDE; 63 virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE; 64 virtual bool GetAcceleratorForCommandId( 65 int command_id, 66 ui::Accelerator* accelerator) OVERRIDE; 67 virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE; 68 virtual const gfx::FontList* GetLabelFontListAt(int index) const OVERRIDE; 69 70 int GetMaxWidthForItemAtIndex(int item_index) const; 71 bool GetURLAndTitleForItemAtIndex(int index, 72 std::string* url, 73 base::string16* title); 74 75 private: 76 struct TabNavigationItem; 77 typedef std::vector<TabNavigationItem> TabNavigationItems; 78 79 typedef std::vector<SessionID::id_type> WindowItems; 80 81 // Build the menu items by populating the menumodel. 82 void Build(); 83 84 // Build the recently closed tabs and windows items. 85 void BuildLocalEntries(); 86 87 // Build the tabs items from other devices. 88 void BuildTabsFromOtherDevices(); 89 90 // Build a recently closed tab item with parameters needed to restore it, and 91 // add it to the menumodel at |curr_model_index|. 92 void BuildLocalTabItem(int seesion_id, 93 const base::string16& title, 94 const GURL& url, 95 int curr_model_index); 96 97 // Build the recently closed window item with parameters needed to restore it, 98 // and add it to the menumodel at |curr_model_index|. 99 void BuildLocalWindowItem(const SessionID::id_type& window_id, 100 int num_tabs, 101 int curr_model_index); 102 103 // Build the tab item for other devices with parameters needed to restore it. 104 void BuildOtherDevicesTabItem(const std::string& session_tag, 105 const SessionTab& tab); 106 107 // Add the favicon for the device section header. 108 void AddDeviceFavicon(int index_in_menu, 109 browser_sync::SyncedSession::DeviceType device_type); 110 111 // Add the favicon for a local or other devices' tab asynchronously, 112 // OnFaviconDataAvailable() will be invoked when the favicon is ready. 113 void AddTabFavicon(int command_id, const GURL& url); 114 void OnFaviconDataAvailable( 115 int command_id, 116 const favicon_base::FaviconImageResult& image_result); 117 118 // Clear all recently closed tabs and windows. 119 void ClearLocalEntries(); 120 121 // Converts |command_id| of menu item to index in local or other devices' 122 // TabNavigationItems, and returns the corresponding local or other devices' 123 // TabNavigationItems in |tab_items|. 124 int CommandIdToTabVectorIndex(int command_id, TabNavigationItems** tab_items); 125 126 // Used to access (and lazily initialize) open_tabs_delegate_. 127 // TODO(tim): This lazy-init for member variables is error prone because you 128 // can always skip going through the function and access the field directly. 129 // Consider instead having code just deal with potentially NULL open_tabs_ 130 // and have it initialized by an event / callback. 131 browser_sync::OpenTabsUIDelegate* GetOpenTabsUIDelegate(); 132 133 // Overridden from TabRestoreServiceObserver: 134 virtual void TabRestoreServiceChanged(TabRestoreService* service) OVERRIDE; 135 virtual void TabRestoreServiceDestroyed(TabRestoreService* service) OVERRIDE; 136 137 Browser* browser_; // Weak. 138 139 browser_sync::OpenTabsUIDelegate* open_tabs_delegate_; // Weak. 140 141 // Accelerator for reopening last closed tab. 142 ui::Accelerator reopen_closed_tab_accelerator_; 143 144 // Navigation items for local recently closed tabs. The |command_id| for 145 // these is set to |kFirstLocalTabCommandId| plus the index into the vector. 146 // Upon invocation of the menu, the navigation information is retrieved from 147 // |local_tab_navigation_items_| and used to navigate to the item specified. 148 TabNavigationItems local_tab_navigation_items_; 149 150 // Similar to |local_tab_navigation_items_| except the tabs are opened tabs 151 // from other devices, and the first |command_id| is 152 // |kFirstOtherDevicesTabCommandId|. 153 TabNavigationItems other_devices_tab_navigation_items_; 154 155 // Window items for local recently closed windows. The |command_id| for 156 // these is set to |kFirstLocalWindowCommandId| plus the index into the 157 // vector. Upon invocation of the menu, information is retrieved from 158 // |local_window_items_| and used to create the specified window. 159 WindowItems local_window_items_; 160 161 // Index of the last local entry (recently closed tab or window) in the 162 // menumodel. 163 int last_local_model_index_; 164 165 gfx::Image default_favicon_; 166 167 base::CancelableTaskTracker local_tab_cancelable_task_tracker_; 168 base::CancelableTaskTracker other_devices_tab_cancelable_task_tracker_; 169 170 base::WeakPtrFactory<RecentTabsSubMenuModel> weak_ptr_factory_; 171 172 DISALLOW_COPY_AND_ASSIGN(RecentTabsSubMenuModel); 173}; 174 175#endif // CHROME_BROWSER_UI_TOOLBAR_RECENT_TABS_SUB_MENU_MODEL_H_ 176