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 if (know_favicon && data.get() && data->size() && data->size() > 0) { |
| 236 int unique_id = load_consumer_.GetClientDataForCurrentRequest(); |
| 237 // We need both the NavigationEntry and the model_index so we search for |
| 238 // the unique_index by model_index. |
| 239 NavigationEntry* entry = NULL; |
| 240 int model_index = -1; |
| 241 for (int i = 0; i < GetItemCount() - 1; i++) { |
| 242 if (IsSeparator(i)) |
| 243 continue; |
| 244 if (GetNavigationEntry(i)->unique_id() == unique_id) { |
| 245 model_index = i; |
| 246 entry = GetNavigationEntry(i); |
| 247 break; |
| 248 } |
| 249 } |
| 250 if (!entry) |
| 251 return; |
| 252 // Now that we have a valid NavigationEntry, decode the favicon and assign |
| 253 // it to the NavigationEntry. |
| 254 SkBitmap fav_icon; |
| 255 if (gfx::PNGCodec::Decode(data->front(), data->size(), &fav_icon)) { |
| 256 entry->favicon().set_is_valid(true); |
| 257 entry->favicon().set_url(icon_url); |
| 258 if (fav_icon.empty()) |
| 259 return; |
| 260 entry->favicon().set_bitmap(fav_icon); |
| 261 if (delegate_) { |
| 262 delegate_->OnIconChanged(model_index); |
| 263 } |
| 264 } |
| 265 } |
| 266 } |
| 267 |
199 int BackForwardMenuModel::GetHistoryItemCount() const { | 268 int BackForwardMenuModel::GetHistoryItemCount() const { |
200 TabContents* contents = GetTabContents(); | 269 TabContents* contents = GetTabContents(); |
201 int items = 0; | 270 int items = 0; |
202 | 271 |
203 if (model_type_ == FORWARD_MENU) { | 272 if (model_type_ == FORWARD_MENU) { |
204 // Only count items from n+1 to end (if n is current entry) | 273 // Only count items from n+1 to end (if n is current entry) |
205 items = contents->controller().entry_count() - | 274 items = contents->controller().entry_count() - |
206 contents->controller().GetCurrentEntryIndex() - 1; | 275 contents->controller().GetCurrentEntryIndex() - 1; |
207 } else { | 276 } else { |
208 items = contents->controller().GetCurrentEntryIndex(); | 277 items = contents->controller().GetCurrentEntryIndex(); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 metric_string += "ForwardMenu_"; | 439 metric_string += "ForwardMenu_"; |
371 else | 440 else |
372 metric_string += "BackMenu_"; | 441 metric_string += "BackMenu_"; |
373 metric_string += action; | 442 metric_string += action; |
374 if (index != -1) { | 443 if (index != -1) { |
375 // +1 is for historical reasons (indices used to start at 1). | 444 // +1 is for historical reasons (indices used to start at 1). |
376 metric_string += base::IntToString(index + 1); | 445 metric_string += base::IntToString(index + 1); |
377 } | 446 } |
378 return metric_string; | 447 return metric_string; |
379 } | 448 } |
OLD | NEW |