1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/custom_home_pages_table_model.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/i18n/rtl.h"
83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h"
93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h"
1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_list.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h"
143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/url_constants.h"
15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "googleurl/src/gurl.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/app_resources.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h"
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "third_party/skia/include/core/SkBitmap.h"
2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h"
2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/models/table_model_observer.h"
2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h"
2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/codec/png_codec.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstruct CustomHomePagesTableModel::Entry {
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Entry() : title_handle(0), favicon_handle(0) {}
283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // URL of the page.
303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GURL url;
313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Page title.  If this is empty, we'll display the URL as the entry.
333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  string16 title;
343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Icon for the page.
363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  SkBitmap icon;
373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // If non-zero, indicates we're loading the title for the page.
393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HistoryService::Handle title_handle;
403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // If non-zero, indicates we're loading the favicon for the page.
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FaviconService::Handle favicon_handle;
433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick};
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCustomHomePagesTableModel::CustomHomePagesTableModel(Profile* profile)
463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    : default_favicon_(NULL),
473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      profile_(profile),
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      observer_(NULL) {
493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  default_favicon_ = rb.GetBitmapNamed(IDR_DEFAULT_FAVICON);
513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
533345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickCustomHomePagesTableModel::~CustomHomePagesTableModel() {
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CustomHomePagesTableModel::SetURLs(const std::vector<GURL>& urls) {
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  entries_.resize(urls.size());
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < urls.size(); ++i) {
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    entries_[i].url = urls[i];
603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    entries_[i].title.erase();
613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    entries_[i].icon.reset();
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    LoadTitleAndFavicon(&(entries_[i]));
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Complete change, so tell the view to just rebuild itself.
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (observer_)
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer_->OnModelChanged();
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CustomHomePagesTableModel::Add(int index, const GURL& url) {
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(index >= 0 && index <= RowCount());
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  entries_.insert(entries_.begin() + static_cast<size_t>(index), Entry());
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  entries_[index].url = url;
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  LoadTitleAndFavicon(&(entries_[index]));
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (observer_)
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer_->OnItemsAdded(index, 1);
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CustomHomePagesTableModel::Remove(int index) {
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(index >= 0 && index < RowCount());
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Entry* entry = &(entries_[index]);
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Cancel any pending load requests now so we don't deref a bogus pointer when
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // we get the loaded notification.
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (entry->title_handle) {
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HistoryService* history_service =
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (history_service)
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      history_service->CancelRequest(entry->title_handle);
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (entry->favicon_handle) {
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FaviconService* favicon_service =
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        profile_->GetFaviconService(Profile::EXPLICIT_ACCESS);
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (favicon_service)
93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      favicon_service->CancelRequest(entry->favicon_handle);
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  entries_.erase(entries_.begin() + static_cast<size_t>(index));
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (observer_)
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer_->OnItemsRemoved(index, 1);
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CustomHomePagesTableModel::SetToCurrentlyOpenPages() {
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Remove the current entries.
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  while (RowCount())
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Remove(0);
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // And add all tabs for all open browsers with our profile.
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int add_index = 0;
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (BrowserList::const_iterator browser_i = BrowserList::begin();
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       browser_i != BrowserList::end(); ++browser_i) {
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Browser* browser = *browser_i;
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (browser->profile() != profile_)
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;  // Skip incognito browsers.
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int tab_index = 0; tab_index < browser->tab_count(); ++tab_index) {
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const GURL url = browser->GetTabContentsAt(tab_index)->GetURL();
1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (!url.is_empty() &&
1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          !(url.SchemeIs(chrome::kChromeUIScheme) &&
1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            url.host() == chrome::kChromeUISettingsHost))
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        Add(add_index++, url);
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::vector<GURL> CustomHomePagesTableModel::GetURLs() {
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<GURL> urls(entries_.size());
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < entries_.size(); ++i)
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    urls[i] = entries_[i].url;
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return urls;
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint CustomHomePagesTableModel::RowCount() {
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return static_cast<int>(entries_.size());
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenstring16 CustomHomePagesTableModel::GetText(int row, int column_id) {
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(column_id == 0);
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(row >= 0 && row < RowCount());
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return entries_[row].title.empty() ? FormattedURL(row) : entries_[row].title;
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSkBitmap CustomHomePagesTableModel::GetIcon(int row) {
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(row >= 0 && row < RowCount());
1423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return entries_[row].icon.isNull() ? *default_favicon_ : entries_[row].icon;
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenstring16 CustomHomePagesTableModel::GetTooltip(int row) {
1463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return entries_[row].title.empty() ? string16() :
1473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      l10n_util::GetStringFUTF16(IDS_OPTIONS_STARTUP_PAGE_TOOLTIP,
1483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                 entries_[row].title, FormattedURL(row));
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
15172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid CustomHomePagesTableModel::SetObserver(ui::TableModelObserver* observer) {
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  observer_ = observer;
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid CustomHomePagesTableModel::LoadTitleAndFavicon(Entry* entry) {
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HistoryService* history_service =
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (history_service) {
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    entry->title_handle = history_service->QueryURL(entry->url, false,
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        &query_consumer_,
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NewCallback(this, &CustomHomePagesTableModel::OnGotTitle));
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FaviconService* favicon_service =
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      profile_->GetFaviconService(Profile::EXPLICIT_ACCESS);
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (favicon_service) {
166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    entry->favicon_handle = favicon_service->GetFaviconForURL(entry->url,
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        history::FAVICON, &query_consumer_,
168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NewCallback(this, &CustomHomePagesTableModel::OnGotFavicon));
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CustomHomePagesTableModel::OnGotTitle(HistoryService::Handle handle,
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           bool found_url,
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           const history::URLRow* row,
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           history::VisitVector* visits) {
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int entry_index;
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Entry* entry =
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GetEntryByLoadHandle(&Entry::title_handle, handle, &entry_index);
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!entry) {
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The URLs changed before we were called back.
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  entry->title_handle = 0;
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (found_url && !row->title().empty()) {
1853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    entry->title = row->title();
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (observer_)
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      observer_->OnItemsChanged(static_cast<int>(entry_index), 1);
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid CustomHomePagesTableModel::OnGotFavicon(
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FaviconService::Handle handle,
193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    history::FaviconData favicon) {
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int entry_index;
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Entry* entry =
196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GetEntryByLoadHandle(&Entry::favicon_handle, handle, &entry_index);
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!entry) {
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The URLs changed before we were called back.
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  entry->favicon_handle = 0;
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (favicon.is_valid()) {
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int width, height;
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<unsigned char> decoded_data;
205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (gfx::PNGCodec::Decode(favicon.image_data->front(),
206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                              favicon.image_data->size(),
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              gfx::PNGCodec::FORMAT_BGRA, &decoded_data,
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              &width, &height)) {
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      entry->icon.setConfig(SkBitmap::kARGB_8888_Config, width, height);
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      entry->icon.allocPixels();
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      memcpy(entry->icon.getPixels(), &decoded_data.front(),
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch             width * height * 4);
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (observer_)
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        observer_->OnItemsChanged(static_cast<int>(entry_index), 1);
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCustomHomePagesTableModel::Entry*
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CustomHomePagesTableModel::GetEntryByLoadHandle(
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CancelableRequestProvider::Handle Entry::* member,
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CancelableRequestProvider::Handle handle,
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int* index) {
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < entries_.size(); ++i) {
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (entries_[i].*member == handle) {
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *index = static_cast<int>(i);
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return &entries_[i];
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return NULL;
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenstring16 CustomHomePagesTableModel::FormattedURL(int row) const {
2343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string languages =
2353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      profile_->GetPrefs()->GetString(prefs::kAcceptLanguages);
2363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  string16 url = net::FormatUrl(entries_[row].url, languages);
2373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  url = base::i18n::GetDisplayStringInLTRDirectionality(url);
2383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return url;
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
240