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.
5 #ifndef CHROME_BROWSER_UI_TOOLBAR_RECENT_TABS_SUB_MENU_MODEL_H_
6 #define CHROME_BROWSER_UI_TOOLBAR_RECENT_TABS_SUB_MENU_MODEL_H_
10 #include "base/memory/weak_ptr.h"
11 #include "base/task/cancelable_task_tracker.h"
12 #include "base/timer/elapsed_timer.h"
13 #include "chrome/browser/sessions/tab_restore_service.h"
14 #include "chrome/browser/sessions/tab_restore_service_observer.h"
15 #include "components/favicon/core/favicon_service.h"
16 #include "components/sync_driver/glue/synced_session.h"
17 #include "ui/base/accelerators/accelerator.h"
18 #include "ui/base/models/simple_menu_model.h"
22 namespace sync_driver
{
23 class OpenTabsUIDelegate
;
26 namespace favicon_base
{
27 struct FaviconImageResult
;
39 class AcceleratorProvider
;
42 // A menu model that builds the contents of "Recent tabs" submenu, which include
43 // the recently closed tabs/windows of current device i.e. local entries, and
44 // opened tabs of other devices.
45 class RecentTabsSubMenuModel
: public ui::SimpleMenuModel
,
46 public ui::SimpleMenuModel::Delegate
,
47 public TabRestoreServiceObserver
{
49 // Command Id for recently closed items header or disabled item to which the
50 // accelerator string will be appended.
51 static const int kRecentlyClosedHeaderCommandId
;
52 static const int kDisabledRecentlyClosedHeaderCommandId
;
54 // Exposed for tests only: return the Command Id for the first entry in the
55 // recently closed window items list.
56 static int GetFirstRecentTabsCommandId();
58 // If |open_tabs_delegate| is NULL, the default delegate for |browser|'s
59 // profile will be used. Testing may require a specific |open_tabs_delegate|.
60 RecentTabsSubMenuModel(ui::AcceleratorProvider
* accelerator_provider
,
62 sync_driver::OpenTabsUIDelegate
* open_tabs_delegate
);
63 ~RecentTabsSubMenuModel() override
;
65 // Overridden from ui::SimpleMenuModel::Delegate:
66 bool IsCommandIdChecked(int command_id
) const override
;
67 bool IsCommandIdEnabled(int command_id
) const override
;
68 bool GetAcceleratorForCommandId(int command_id
,
69 ui::Accelerator
* accelerator
) override
;
70 void ExecuteCommand(int command_id
, int event_flags
) override
;
71 const gfx::FontList
* GetLabelFontListAt(int index
) const override
;
73 int GetMaxWidthForItemAtIndex(int item_index
) const;
74 bool GetURLAndTitleForItemAtIndex(int index
,
76 base::string16
* title
);
79 struct TabNavigationItem
;
80 typedef std::vector
<TabNavigationItem
> TabNavigationItems
;
82 typedef std::vector
<SessionID::id_type
> WindowItems
;
84 // Build the menu items by populating the menumodel.
87 // Build the recently closed tabs and windows items.
88 void BuildLocalEntries();
90 // Build the tabs items from other devices.
91 void BuildTabsFromOtherDevices();
93 // Build a recently closed tab item with parameters needed to restore it, and
94 // add it to the menumodel at |curr_model_index|.
95 void BuildLocalTabItem(int seesion_id
,
96 const base::string16
& title
,
98 int curr_model_index
);
100 // Build the recently closed window item with parameters needed to restore it,
101 // and add it to the menumodel at |curr_model_index|.
102 void BuildLocalWindowItem(const SessionID::id_type
& window_id
,
104 int curr_model_index
);
106 // Build the tab item for other devices with parameters needed to restore it.
107 void BuildOtherDevicesTabItem(const std::string
& session_tag
,
108 const sessions::SessionTab
& tab
);
110 // Add the favicon for the device section header.
111 void AddDeviceFavicon(int index_in_menu
,
112 sync_driver::SyncedSession::DeviceType device_type
);
114 // Add the favicon for a local or other devices' tab asynchronously,
115 // OnFaviconDataAvailable() will be invoked when the favicon is ready.
116 void AddTabFavicon(int command_id
, const GURL
& url
);
117 void OnFaviconDataAvailable(
119 const favicon_base::FaviconImageResult
& image_result
);
121 // Clear all recently closed tabs and windows.
122 void ClearLocalEntries();
124 // Converts |command_id| of menu item to index in local or other devices'
125 // TabNavigationItems, and returns the corresponding local or other devices'
126 // TabNavigationItems in |tab_items|.
127 int CommandIdToTabVectorIndex(int command_id
, TabNavigationItems
** tab_items
);
129 // Used to access (and lazily initialize) open_tabs_delegate_.
130 // TODO(tim): This lazy-init for member variables is error prone because you
131 // can always skip going through the function and access the field directly.
132 // Consider instead having code just deal with potentially NULL open_tabs_
133 // and have it initialized by an event / callback.
134 sync_driver::OpenTabsUIDelegate
* GetOpenTabsUIDelegate();
136 // Overridden from TabRestoreServiceObserver:
137 void TabRestoreServiceChanged(TabRestoreService
* service
) override
;
138 void TabRestoreServiceDestroyed(TabRestoreService
* service
) override
;
140 Browser
* browser_
; // Weak.
142 sync_driver::OpenTabsUIDelegate
* open_tabs_delegate_
; // Weak.
144 // Accelerator for reopening last closed tab.
145 ui::Accelerator reopen_closed_tab_accelerator_
;
147 // Accelerator for showing history.
148 ui::Accelerator show_history_accelerator_
;
150 // Navigation items for local recently closed tabs. The |command_id| for
151 // these is set to |kFirstLocalTabCommandId| plus the index into the vector.
152 // Upon invocation of the menu, the navigation information is retrieved from
153 // |local_tab_navigation_items_| and used to navigate to the item specified.
154 TabNavigationItems local_tab_navigation_items_
;
156 // Similar to |local_tab_navigation_items_| except the tabs are opened tabs
157 // from other devices, and the first |command_id| is
158 // |kFirstOtherDevicesTabCommandId|.
159 TabNavigationItems other_devices_tab_navigation_items_
;
161 // Window items for local recently closed windows. The |command_id| for
162 // these is set to |kFirstLocalWindowCommandId| plus the index into the
163 // vector. Upon invocation of the menu, information is retrieved from
164 // |local_window_items_| and used to create the specified window.
165 WindowItems local_window_items_
;
167 // Index of the last local entry (recently closed tab or window) in the
169 int last_local_model_index_
;
171 gfx::Image default_favicon_
;
173 base::CancelableTaskTracker local_tab_cancelable_task_tracker_
;
174 base::CancelableTaskTracker other_devices_tab_cancelable_task_tracker_
;
176 // Time the menu is open for until a recent tab is selected.
177 base::ElapsedTimer menu_opened_timer_
;
179 base::WeakPtrFactory
<RecentTabsSubMenuModel
> weak_ptr_factory_
;
181 DISALLOW_COPY_AND_ASSIGN(RecentTabsSubMenuModel
);
184 #endif // CHROME_BROWSER_UI_TOOLBAR_RECENT_TABS_SUB_MENU_MODEL_H_