| 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 "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
| 10 #include "chrome/browser/metrics/user_metrics.h" | 10 #include "chrome/browser/metrics/user_metrics.h" |
| 11 #include "chrome/browser/prefs/pref_service.h" | 11 #include "chrome/browser/prefs/pref_service.h" |
| 12 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
| 13 #include "chrome/browser/ui/browser.h" | 13 #include "chrome/browser/ui/browser.h" |
| 14 #include "chrome/common/pref_names.h" | 14 #include "chrome/common/pref_names.h" |
| 15 #include "chrome/common/url_constants.h" | 15 #include "chrome/common/url_constants.h" |
| 16 #include "content/browser/tab_contents/navigation_controller.h" | 16 #include "content/browser/tab_contents/navigation_controller.h" |
| 17 #include "content/browser/tab_contents/navigation_entry.h" | 17 #include "content/browser/tab_contents/navigation_entry.h" |
| 18 #include "content/browser/tab_contents/tab_contents.h" | 18 #include "content/browser/tab_contents/tab_contents.h" |
| 19 #include "grit/generated_resources.h" | 19 #include "grit/generated_resources.h" |
| 20 #include "grit/theme_resources.h" | 20 #include "grit/theme_resources.h" |
| 21 #include "net/base/registry_controlled_domain.h" | 21 #include "net/base/registry_controlled_domain.h" |
| 22 #include "ui/base/l10n/l10n_util.h" | 22 #include "ui/base/l10n/l10n_util.h" |
| 23 #include "ui/base/resource/resource_bundle.h" | 23 #include "ui/base/resource/resource_bundle.h" |
| 24 #include "ui/base/text/text_elider.h" | 24 #include "ui/base/text/text_elider.h" |
| 25 #include "ui/gfx/codec/png_codec.h" |
| 25 | 26 |
| 26 const int BackForwardMenuModel::kMaxHistoryItems = 12; | 27 const int BackForwardMenuModel::kMaxHistoryItems = 12; |
| 27 const int BackForwardMenuModel::kMaxChapterStops = 5; | 28 const int BackForwardMenuModel::kMaxChapterStops = 5; |
| 28 static const int kMaxWidth = 700; | 29 static const int kMaxWidth = 700; |
| 29 | 30 |
| 30 BackForwardMenuModel::BackForwardMenuModel(Browser* browser, | 31 BackForwardMenuModel::BackForwardMenuModel(Browser* browser, |
| 31 ModelType model_type) | 32 ModelType model_type) |
| 32 : browser_(browser), | 33 : browser_(browser), |
| 33 test_tab_contents_(NULL), | 34 test_tab_contents_(NULL), |
| 34 model_type_(model_type) { | 35 model_type_(model_type), |
| 36 menu_model_delegate_(NULL) { |
| 35 } | 37 } |
| 36 | 38 |
| 37 bool BackForwardMenuModel::HasIcons() const { | 39 bool BackForwardMenuModel::HasIcons() const { |
| 38 return true; | 40 return true; |
| 39 } | 41 } |
| 40 | 42 |
| 41 int BackForwardMenuModel::GetItemCount() const { | 43 int BackForwardMenuModel::GetItemCount() const { |
| 42 int items = GetHistoryItemCount(); | 44 int items = GetHistoryItemCount(); |
| 43 | 45 |
| 44 if (items > 0) { | 46 if (items > 0) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 } | 108 } |
| 107 | 109 |
| 108 bool BackForwardMenuModel::IsItemCheckedAt(int index) const { | 110 bool BackForwardMenuModel::IsItemCheckedAt(int index) const { |
| 109 return false; | 111 return false; |
| 110 } | 112 } |
| 111 | 113 |
| 112 int BackForwardMenuModel::GetGroupIdAt(int index) const { | 114 int BackForwardMenuModel::GetGroupIdAt(int index) const { |
| 113 return false; | 115 return false; |
| 114 } | 116 } |
| 115 | 117 |
| 116 bool BackForwardMenuModel::GetIconAt(int index, SkBitmap* icon) const { | 118 bool BackForwardMenuModel::GetIconAt(int index, SkBitmap* icon) { |
| 117 if (!ItemHasIcon(index)) | 119 if (!ItemHasIcon(index)) |
| 118 return false; | 120 return false; |
| 119 | 121 |
| 120 if (index == GetItemCount() - 1) { | 122 if (index == GetItemCount() - 1) { |
| 121 *icon = *ResourceBundle::GetSharedInstance().GetBitmapNamed( | 123 *icon = *ResourceBundle::GetSharedInstance().GetBitmapNamed( |
| 122 IDR_HISTORY_FAVICON); | 124 IDR_HISTORY_FAVICON); |
| 123 } else { | 125 } else { |
| 124 NavigationEntry* entry = GetNavigationEntry(index); | 126 NavigationEntry* entry = GetNavigationEntry(index); |
| 125 *icon = entry->favicon().bitmap(); | 127 *icon = entry->favicon().bitmap(); |
| 128 if (!entry->favicon().is_valid() && menu_model_delegate()) { |
| 129 FetchFavicon(entry); |
| 130 } |
| 126 } | 131 } |
| 127 | 132 |
| 128 return true; | 133 return true; |
| 129 } | 134 } |
| 130 | 135 |
| 131 ui::ButtonMenuItemModel* BackForwardMenuModel::GetButtonMenuItemAt( | 136 ui::ButtonMenuItemModel* BackForwardMenuModel::GetButtonMenuItemAt( |
| 132 int index) const { | 137 int index) const { |
| 133 return NULL; | 138 return NULL; |
| 134 } | 139 } |
| 135 | 140 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 int controller_index = MenuIndexToNavEntryIndex(index); | 180 int controller_index = MenuIndexToNavEntryIndex(index); |
| 176 if (!browser_->NavigateToIndexWithDisposition( | 181 if (!browser_->NavigateToIndexWithDisposition( |
| 177 controller_index, static_cast<WindowOpenDisposition>(disposition))) { | 182 controller_index, static_cast<WindowOpenDisposition>(disposition))) { |
| 178 NOTREACHED(); | 183 NOTREACHED(); |
| 179 } | 184 } |
| 180 } | 185 } |
| 181 | 186 |
| 182 void BackForwardMenuModel::MenuWillShow() { | 187 void BackForwardMenuModel::MenuWillShow() { |
| 183 UserMetrics::RecordComputedAction(BuildActionName("Popup", -1), | 188 UserMetrics::RecordComputedAction(BuildActionName("Popup", -1), |
| 184 browser_->profile()); | 189 browser_->profile()); |
| 190 requested_favicons_.clear(); |
| 191 load_consumer_.CancelAllRequests(); |
| 185 } | 192 } |
| 186 | 193 |
| 187 bool BackForwardMenuModel::IsSeparator(int index) const { | 194 bool BackForwardMenuModel::IsSeparator(int index) const { |
| 188 int history_items = GetHistoryItemCount(); | 195 int history_items = GetHistoryItemCount(); |
| 189 // If the index is past the number of history items + separator, | 196 // If the index is past the number of history items + separator, |
| 190 // we then consider if it is a chapter-stop entry. | 197 // we then consider if it is a chapter-stop entry. |
| 191 if (index > history_items) { | 198 if (index > history_items) { |
| 192 // We either are in ChapterStop area, or at the end of the list (the "Show | 199 // We either are in ChapterStop area, or at the end of the list (the "Show |
| 193 // Full History" link). | 200 // Full History" link). |
| 194 int chapter_stops = GetChapterStopCount(history_items); | 201 int chapter_stops = GetChapterStopCount(history_items); |
| 195 if (chapter_stops == 0) | 202 if (chapter_stops == 0) |
| 196 return false; // We must have reached the "Show Full History" link. | 203 return false; // We must have reached the "Show Full History" link. |
| 197 // Otherwise, look to see if we have reached the separator for the | 204 // Otherwise, look to see if we have reached the separator for the |
| 198 // chapter-stops. If not, this is a chapter stop. | 205 // chapter-stops. If not, this is a chapter stop. |
| 199 return (index == history_items + 1 + chapter_stops); | 206 return (index == history_items + 1 + chapter_stops); |
| 200 } | 207 } |
| 201 | 208 |
| 202 // Look to see if we have reached the separator for the history items. | 209 // Look to see if we have reached the separator for the history items. |
| 203 return index == history_items; | 210 return index == history_items; |
| 204 } | 211 } |
| 205 | 212 |
| 213 void BackForwardMenuModel::SetMenuModelDelegate( |
| 214 ui::MenuModelDelegate* menu_model_delegate) { |
| 215 menu_model_delegate_ = menu_model_delegate; |
| 216 } |
| 217 |
| 218 void BackForwardMenuModel::FetchFavicon(NavigationEntry* entry) { |
| 219 // If the favicon has already been requested for this menu, don't do |
| 220 // anything. |
| 221 if (requested_favicons_.find(entry->unique_id()) != |
| 222 requested_favicons_.end()) { |
| 223 return; |
| 224 } |
| 225 requested_favicons_.insert(entry->unique_id()); |
| 226 FaviconService* favicon_service = |
| 227 browser_->profile()->GetFaviconService(Profile::EXPLICIT_ACCESS); |
| 228 if (!favicon_service) |
| 229 return; |
| 230 FaviconService::Handle handle = favicon_service->GetFaviconForURL( |
| 231 entry->url(), history::FAVICON, &load_consumer_, |
| 232 NewCallback(this, &BackForwardMenuModel::OnFavIconDataAvailable)); |
| 233 load_consumer_.SetClientData(favicon_service, handle, entry->unique_id()); |
| 234 } |
| 235 |
| 236 void BackForwardMenuModel::OnFavIconDataAvailable( |
| 237 FaviconService::Handle handle, |
| 238 history::FaviconData favicon) { |
| 239 if (favicon.is_valid()) { |
| 240 int unique_id = load_consumer_.GetClientDataForCurrentRequest(); |
| 241 // Find the current model_index for the unique_id. |
| 242 NavigationEntry* entry = NULL; |
| 243 int model_index = -1; |
| 244 for (int i = 0; i < GetItemCount() - 1; i++) { |
| 245 if (IsSeparator(i)) |
| 246 continue; |
| 247 if (GetNavigationEntry(i)->unique_id() == unique_id) { |
| 248 model_index = i; |
| 249 entry = GetNavigationEntry(i); |
| 250 break; |
| 251 } |
| 252 } |
| 253 |
| 254 if (!entry) |
| 255 // The NavigationEntry wasn't found, this can happen if the user |
| 256 // navigates to another page and a NavigatationEntry falls out of the |
| 257 // range of kMaxHistoryItems. |
| 258 return; |
| 259 |
| 260 // Now that we have a valid NavigationEntry, decode the favicon and assign |
| 261 // it to the NavigationEntry. |
| 262 SkBitmap fav_icon; |
| 263 if (gfx::PNGCodec::Decode(favicon.image_data->front(), |
| 264 favicon.image_data->size(), |
| 265 &fav_icon)) { |
| 266 entry->favicon().set_is_valid(true); |
| 267 entry->favicon().set_url(favicon.icon_url); |
| 268 if (fav_icon.empty()) |
| 269 return; |
| 270 entry->favicon().set_bitmap(fav_icon); |
| 271 if (menu_model_delegate()) { |
| 272 menu_model_delegate()->OnIconChanged(model_index); |
| 273 } |
| 274 } |
| 275 } |
| 276 } |
| 277 |
| 206 int BackForwardMenuModel::GetHistoryItemCount() const { | 278 int BackForwardMenuModel::GetHistoryItemCount() const { |
| 207 TabContents* contents = GetTabContents(); | 279 TabContents* contents = GetTabContents(); |
| 208 int items = 0; | 280 int items = 0; |
| 209 | 281 |
| 210 if (model_type_ == FORWARD_MENU) { | 282 if (model_type_ == FORWARD_MENU) { |
| 211 // Only count items from n+1 to end (if n is current entry) | 283 // Only count items from n+1 to end (if n is current entry) |
| 212 items = contents->controller().entry_count() - | 284 items = contents->controller().entry_count() - |
| 213 contents->controller().GetCurrentEntryIndex() - 1; | 285 contents->controller().GetCurrentEntryIndex() - 1; |
| 214 } else { | 286 } else { |
| 215 items = contents->controller().GetCurrentEntryIndex(); | 287 items = contents->controller().GetCurrentEntryIndex(); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 metric_string += "ForwardMenu_"; | 449 metric_string += "ForwardMenu_"; |
| 378 else | 450 else |
| 379 metric_string += "BackMenu_"; | 451 metric_string += "BackMenu_"; |
| 380 metric_string += action; | 452 metric_string += action; |
| 381 if (index != -1) { | 453 if (index != -1) { |
| 382 // +1 is for historical reasons (indices used to start at 1). | 454 // +1 is for historical reasons (indices used to start at 1). |
| 383 metric_string += base::IntToString(index + 1); | 455 metric_string += base::IntToString(index + 1); |
| 384 } | 456 } |
| 385 return metric_string; | 457 return metric_string; |
| 386 } | 458 } |
| OLD | NEW |