OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "build/build_config.h" | 5 #include "build/build_config.h" |
6 | 6 |
7 #include "chrome/browser/ui/toolbar/back_forward_menu_model.h" | 7 #include "chrome/browser/ui/toolbar/back_forward_menu_model.h" |
8 | 8 |
9 #include "app/l10n_util.h" | 9 #include "app/l10n_util.h" |
10 #include "app/text_elider.h" | 10 #include "app/text_elider.h" |
11 #include "app/resource_bundle.h" | 11 #include "app/resource_bundle.h" |
12 #include "base/string_number_conversions.h" | 12 #include "base/string_number_conversions.h" |
13 #include "chrome/browser/metrics/user_metrics.h" | 13 #include "chrome/browser/metrics/user_metrics.h" |
14 #include "chrome/browser/profiles/profile.h" | |
14 #include "chrome/browser/tab_contents/navigation_controller.h" | 15 #include "chrome/browser/tab_contents/navigation_controller.h" |
15 #include "chrome/browser/tab_contents/navigation_entry.h" | 16 #include "chrome/browser/tab_contents/navigation_entry.h" |
16 #include "chrome/browser/tab_contents/tab_contents.h" | 17 #include "chrome/browser/tab_contents/tab_contents.h" |
17 #include "chrome/browser/ui/browser.h" | 18 #include "chrome/browser/ui/browser.h" |
18 #include "chrome/common/url_constants.h" | 19 #include "chrome/common/url_constants.h" |
20 #include "gfx/codec/png_codec.h" | |
19 #include "grit/generated_resources.h" | 21 #include "grit/generated_resources.h" |
20 #include "grit/theme_resources.h" | 22 #include "grit/theme_resources.h" |
21 #include "net/base/registry_controlled_domain.h" | 23 #include "net/base/registry_controlled_domain.h" |
22 | 24 |
23 const int BackForwardMenuModel::kMaxHistoryItems = 12; | 25 const int BackForwardMenuModel::kMaxHistoryItems = 12; |
24 const int BackForwardMenuModel::kMaxChapterStops = 5; | 26 const int BackForwardMenuModel::kMaxChapterStops = 5; |
25 static const int kMaxWidth = 700; | 27 static const int kMaxWidth = 700; |
26 | 28 |
27 BackForwardMenuModel::BackForwardMenuModel(Browser* browser, | 29 BackForwardMenuModel::BackForwardMenuModel(Browser* browser, |
28 ModelType model_type) | 30 ModelType model_type) |
29 : browser_(browser), | 31 : browser_(browser), |
30 test_tab_contents_(NULL), | 32 test_tab_contents_(NULL), |
31 model_type_(model_type) { | 33 model_type_(model_type), |
34 delegate_(NULL) { | |
32 } | 35 } |
33 | 36 |
34 bool BackForwardMenuModel::HasIcons() const { | 37 bool BackForwardMenuModel::HasIcons() const { |
35 return true; | 38 return true; |
36 } | 39 } |
37 | 40 |
38 int BackForwardMenuModel::GetItemCount() const { | 41 int BackForwardMenuModel::GetItemCount() const { |
39 int items = GetHistoryItemCount(); | 42 int items = GetHistoryItemCount(); |
40 | 43 |
41 if (items > 0) { | 44 if (items > 0) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
99 } | 102 } |
100 | 103 |
101 bool BackForwardMenuModel::IsItemCheckedAt(int index) const { | 104 bool BackForwardMenuModel::IsItemCheckedAt(int index) const { |
102 return false; | 105 return false; |
103 } | 106 } |
104 | 107 |
105 int BackForwardMenuModel::GetGroupIdAt(int index) const { | 108 int BackForwardMenuModel::GetGroupIdAt(int index) const { |
106 return false; | 109 return false; |
107 } | 110 } |
108 | 111 |
109 bool BackForwardMenuModel::GetIconAt(int index, SkBitmap* icon) const { | 112 bool BackForwardMenuModel::GetIconAt(int index, SkBitmap* icon) { |
110 if (!ItemHasIcon(index)) | 113 if (!ItemHasIcon(index)) |
111 return false; | 114 return false; |
112 | 115 |
113 if (index == GetItemCount() - 1) { | 116 if (index == GetItemCount() - 1) { |
114 *icon = *ResourceBundle::GetSharedInstance().GetBitmapNamed( | 117 *icon = *ResourceBundle::GetSharedInstance().GetBitmapNamed( |
115 IDR_HISTORY_FAVICON); | 118 IDR_HISTORY_FAVICON); |
116 } else { | 119 } else { |
117 NavigationEntry* entry = GetNavigationEntry(index); | 120 NavigationEntry* entry = GetNavigationEntry(index); |
118 *icon = entry->favicon().bitmap(); | 121 *icon = entry->favicon().bitmap(); |
122 if (!entry->favicon().is_valid()) { | |
123 FetchFavicon(entry, index); | |
124 } | |
119 } | 125 } |
120 | 126 |
121 return true; | 127 return true; |
122 } | 128 } |
123 | 129 |
124 menus::ButtonMenuItemModel* BackForwardMenuModel::GetButtonMenuItemAt( | 130 menus::ButtonMenuItemModel* BackForwardMenuModel::GetButtonMenuItemAt( |
125 int index) const { | 131 int index) const { |
126 return NULL; | 132 return NULL; |
127 } | 133 } |
128 | 134 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
168 int controller_index = MenuIndexToNavEntryIndex(index); | 174 int controller_index = MenuIndexToNavEntryIndex(index); |
169 if (!browser_->NavigateToIndexWithDisposition( | 175 if (!browser_->NavigateToIndexWithDisposition( |
170 controller_index, static_cast<WindowOpenDisposition>(disposition))) { | 176 controller_index, static_cast<WindowOpenDisposition>(disposition))) { |
171 NOTREACHED(); | 177 NOTREACHED(); |
172 } | 178 } |
173 } | 179 } |
174 | 180 |
175 void BackForwardMenuModel::MenuWillShow() { | 181 void BackForwardMenuModel::MenuWillShow() { |
176 UserMetrics::RecordComputedAction(BuildActionName("Popup", -1), | 182 UserMetrics::RecordComputedAction(BuildActionName("Popup", -1), |
177 browser_->profile()); | 183 browser_->profile()); |
184 requested_favicons_.clear(); | |
185 load_consumer_.CancelAllRequests(); | |
178 } | 186 } |
179 | 187 |
180 bool BackForwardMenuModel::IsSeparator(int index) const { | 188 bool BackForwardMenuModel::IsSeparator(int index) const { |
181 int history_items = GetHistoryItemCount(); | 189 int history_items = GetHistoryItemCount(); |
182 // If the index is past the number of history items + separator, | 190 // If the index is past the number of history items + separator, |
183 // we then consider if it is a chapter-stop entry. | 191 // we then consider if it is a chapter-stop entry. |
184 if (index > history_items) { | 192 if (index > history_items) { |
185 // We either are in ChapterStop area, or at the end of the list (the "Show | 193 // We either are in ChapterStop area, or at the end of the list (the "Show |
186 // Full History" link). | 194 // Full History" link). |
187 int chapter_stops = GetChapterStopCount(history_items); | 195 int chapter_stops = GetChapterStopCount(history_items); |
188 if (chapter_stops == 0) | 196 if (chapter_stops == 0) |
189 return false; // We must have reached the "Show Full History" link. | 197 return false; // We must have reached the "Show Full History" link. |
190 // Otherwise, look to see if we have reached the separator for the | 198 // Otherwise, look to see if we have reached the separator for the |
191 // chapter-stops. If not, this is a chapter stop. | 199 // chapter-stops. If not, this is a chapter stop. |
192 return (index == history_items + 1 + chapter_stops); | 200 return (index == history_items + 1 + chapter_stops); |
193 } | 201 } |
194 | 202 |
195 // Look to see if we have reached the separator for the history items. | 203 // Look to see if we have reached the separator for the history items. |
196 return index == history_items; | 204 return index == history_items; |
197 } | 205 } |
198 | 206 |
207 void BackForwardMenuModel::SetDelegate(Delegate* delegate) { | |
208 delegate_ = delegate; | |
209 } | |
210 | |
211 void BackForwardMenuModel::FetchFavicon(NavigationEntry* entry, int index) { | |
212 // If the favicon has already been requested for this menu, don't do | |
213 // anything. | |
214 if (requested_favicons_.find(entry->unique_id()) != | |
215 requested_favicons_.end()) { | |
216 return; | |
217 } | |
218 requested_favicons_.insert(entry->unique_id()); | |
219 FaviconService* favicon_service = | |
220 browser_->profile()->GetFaviconService(Profile::EXPLICIT_ACCESS); | |
221 if (!favicon_service) | |
222 return; | |
223 FaviconService::Handle handle = favicon_service->GetFaviconForURL( | |
224 entry->url(), &load_consumer_, | |
225 NewCallback(this, &BackForwardMenuModel::OnFavIconDataAvailable)); | |
226 load_consumer_.SetClientData(favicon_service, handle, entry->unique_id()); | |
227 } | |
228 | |
229 void BackForwardMenuModel::OnFavIconDataAvailable( | |
230 FaviconService::Handle handle, | |
231 bool know_favicon, | |
232 scoped_refptr<RefCountedMemory> data, | |
233 bool expired, | |
234 GURL icon_url) { | |
235 SkBitmap fav_icon; | |
236 if (know_favicon && data.get() && data->size() && data->size() > 0 && | |
237 gfx::PNGCodec::Decode(data->front(), data->size(), &fav_icon)) { | |
238 int unique_id = load_consumer_.GetClientDataForCurrentRequest(); | |
sky
2011/01/04 21:51:15
Finding the navigation entry is cheap, but decodin
| |
239 // We need both the NavigationEntry and the model_index so we search for | |
240 // the unique_index by model_index. | |
241 NavigationEntry* entry = NULL; | |
242 int model_index = -1; | |
243 for (int i = 0; i < GetItemCount() - 1; i++) { | |
244 if (IsSeparator(i)) | |
245 continue; | |
246 entry = GetNavigationEntry(i); | |
247 if (entry->unique_id() == unique_id) { | |
248 model_index = i; | |
249 break; | |
250 } | |
251 } | |
252 if (!entry) | |
sky
2011/01/04 21:51:15
Notice that even if you didn't find the matching N
| |
253 return; | |
254 entry->favicon().set_is_valid(true); | |
255 entry->favicon().set_url(icon_url); | |
256 if (fav_icon.empty()) | |
257 return; | |
258 entry->favicon().set_bitmap(fav_icon); | |
259 if (delegate_) { | |
260 delegate_->OnIconChanged(model_index); | |
261 } | |
262 } | |
263 } | |
264 | |
199 int BackForwardMenuModel::GetHistoryItemCount() const { | 265 int BackForwardMenuModel::GetHistoryItemCount() const { |
200 TabContents* contents = GetTabContents(); | 266 TabContents* contents = GetTabContents(); |
201 int items = 0; | 267 int items = 0; |
202 | 268 |
203 if (model_type_ == FORWARD_MENU) { | 269 if (model_type_ == FORWARD_MENU) { |
204 // Only count items from n+1 to end (if n is current entry) | 270 // Only count items from n+1 to end (if n is current entry) |
205 items = contents->controller().entry_count() - | 271 items = contents->controller().entry_count() - |
206 contents->controller().GetCurrentEntryIndex() - 1; | 272 contents->controller().GetCurrentEntryIndex() - 1; |
207 } else { | 273 } else { |
208 items = contents->controller().GetCurrentEntryIndex(); | 274 items = contents->controller().GetCurrentEntryIndex(); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
370 metric_string += "ForwardMenu_"; | 436 metric_string += "ForwardMenu_"; |
371 else | 437 else |
372 metric_string += "BackMenu_"; | 438 metric_string += "BackMenu_"; |
373 metric_string += action; | 439 metric_string += action; |
374 if (index != -1) { | 440 if (index != -1) { |
375 // +1 is for historical reasons (indices used to start at 1). | 441 // +1 is for historical reasons (indices used to start at 1). |
376 metric_string += base::IntToString(index + 1); | 442 metric_string += base::IntToString(index + 1); |
377 } | 443 } |
378 return metric_string; | 444 return metric_string; |
379 } | 445 } |
OLD | NEW |